Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java
new file mode 100644
index 0000000000000000000000000000000000000000..306dbb963b93348a1533b1293f8befa29234b55e
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarControlContainer.java
@@ -0,0 +1,351 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.toolbar;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.ScaleDrawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.google.android.apps.chrome.R;
+
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler;
+import org.chromium.chrome.browser.contextualsearch.SwipeRecognizer;
+import org.chromium.chrome.browser.widget.ControlContainer;
+import org.chromium.chrome.browser.widget.SmoothProgressBar;
+import org.chromium.chrome.browser.widget.SmoothProgressBar.ProgressChangeListener;
+import org.chromium.chrome.browser.widget.ViewResourceFrameLayout;
+import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager;
+import org.chromium.ui.UiUtils;
+import org.chromium.ui.resources.dynamics.ViewResourceAdapter;
+
+/**
+ * Layout for the browser controls (omnibox, menu, tab strip, etc..).
+ */
+public class ToolbarControlContainer extends FrameLayout implements ControlContainer {
+ private final float mTabStripHeight;
+
+ private Toolbar mToolbar;
+ private ToolbarViewResourceFrameLayout mToolbarContainer;
+ private View mMenuBtn;
+
+ private final SwipeRecognizer mSwipeRecognizer;
+ private EdgeSwipeHandler mSwipeHandler;
+
+ private FindToolbarManager mFindToolbarManager;
+
+ private ViewResourceAdapter mProgressResourceAdapter;
+
+ /**
+ * Constructs a new control container.
+ * <p>
+ * This constructor is used when inflating from XML.
+ *
+ * @param context The context used to build this view.
+ * @param attrs The attributes used to determine how to construct this view.
+ */
+ public ToolbarControlContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mTabStripHeight = context.getResources().getDimension(R.dimen.tab_strip_height);
+ mSwipeRecognizer = new SwipeRecognizerImpl(context);
+ }
+
+ @Override
+ public ViewResourceAdapter getProgressResourceAdapter() {
+ return mProgressResourceAdapter;
+ }
+
+ @Override
+ public ViewResourceAdapter getToolbarResourceAdapter() {
+ return mToolbarContainer.getResourceAdapter();
+ }
+
+ @Override
+ public void setSwipeHandler(EdgeSwipeHandler handler) {
+ mSwipeHandler = handler;
+ mSwipeRecognizer.setSwipeHandler(handler);
+ }
+
+ /**
+ * Sets the manager in charge of find in page.
+ */
+ public void setFindToolbarManager(FindToolbarManager manager) {
+ mFindToolbarManager = manager;
+ }
+
+ @Override
+ public void onFinishInflate() {
+ mToolbar = (Toolbar) findViewById(R.id.toolbar);
+ mToolbarContainer = (ToolbarViewResourceFrameLayout) findViewById(R.id.toolbar_container);
+ mMenuBtn = findViewById(R.id.menu_button);
+
+ // TODO(yusufo): Get rid of the calls below and avoid casting to the layout without making
+ // the interface bigger.
+ SmoothProgressBar progressView = ((ToolbarLayout) mToolbar).getProgressBar();
+ if (progressView != null) {
+ mProgressResourceAdapter = new ProgressViewResourceAdapter(progressView);
+ }
+
+ if (mToolbar instanceof ToolbarTablet) {
+ // On tablet, draw a fake tab strip and toolbar until the compositor is ready to draw
+ // the real tab strip. (On phone, the toolbar is made entirely of Android views, which
+ // are already initialized.)
+ setBackgroundResource(R.drawable.toolbar_background);
+ }
+
+ assert mToolbar != null;
+ assert mMenuBtn != null;
+
+ super.onFinishInflate();
+ }
+
+ /**
+ * Invalidate the entire capturing bitmap region.
+ */
+ public void invalidateBitmap() {
+ ((ToolbarViewResourceAdapter) getToolbarResourceAdapter()).forceInvalidate();
+ }
+
+ /**
+ * Update whether the control container is ready to have the bitmap representation of
+ * itself be captured.
+ */
+ public void setReadyForBitmapCapture(boolean ready) {
+ mToolbarContainer.mReadyForBitmapCapture = ready;
+ }
+
+ /**
+ * The layout that handles generating the toolbar view resource.
+ */
+ // Only publicly visible due to lint warnings.
+ public static class ToolbarViewResourceFrameLayout extends ViewResourceFrameLayout {
+ private boolean mReadyForBitmapCapture;
+
+ public ToolbarViewResourceFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected ViewResourceAdapter createResourceAdapter() {
+ return new ToolbarViewResourceAdapter(
+ this, (Toolbar) findViewById(R.id.toolbar));
+ }
+
+ @Override
+ protected boolean isReadyForCapture() {
+ return mReadyForBitmapCapture;
+ }
+ }
+
+ private static class ProgressViewResourceAdapter extends ViewResourceAdapter
+ implements ProgressChangeListener {
+
+ private final SmoothProgressBar mProgressView;
+ private final Rect mPreviousDrawBounds = new Rect();
+ private int mProgressVisibility;
+ private int mProgress;
+
+ ProgressViewResourceAdapter(SmoothProgressBar progressView) {
+ super(progressView);
+
+ mProgressView = progressView;
+ mProgressVisibility = mProgressView.getVisibility();
+ progressView.addProgressChangeListener(this);
+ }
+
+ @Override
+ public void onProgressChanged(int progress) {
+ if (mProgressVisibility != View.VISIBLE) return;
+ if (progress < mProgress) {
+ mPreviousDrawBounds.setEmpty();
+ }
+ mProgress = progress;
+ invalidate(null);
+ }
+
+ @Override
+ public void onProgressVisibilityChanged(int visibility) {
+ if (mProgressVisibility == visibility) return;
+
+ if (visibility == View.VISIBLE || mProgressVisibility == View.VISIBLE) {
+ invalidate(null);
+ mPreviousDrawBounds.setEmpty();
+ }
+ mProgressVisibility = visibility;
+ }
+
+ @Override
+ protected void onCaptureStart(Canvas canvas, Rect dirtyRect) {
+ canvas.save();
+ canvas.clipRect(
+ mPreviousDrawBounds.right, 0,
+ mProgressView.getWidth(), mProgressView.getHeight());
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ canvas.restore();
+
+ super.onCaptureStart(canvas, dirtyRect);
+ }
+
+ @Override
+ protected void capture(Canvas canvas) {
+ if (mProgressVisibility != View.VISIBLE) {
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ } else {
+ super.capture(canvas);
+ }
+ }
+
+ @Override
+ protected void onCaptureEnd() {
+ super.onCaptureEnd();
+ // If we are unable to get accurate draw bounds, then set the draw bounds to
+ // ensure the entire view is cleared.
+ mPreviousDrawBounds.setEmpty();
+
+ // The secondary drawable has an alpha component, so track the bounds of the
+ // primary drawable. This will allow the subsequent draw call to clear the secondary
+ // portion not overlapped by the primary to prevent the alpha components from
+ // stacking and getting progressively darker.
+ Drawable progressDrawable = mProgressView.getProgressDrawable();
+ if (progressDrawable instanceof LayerDrawable) {
+ LayerDrawable progressLayerDrawable = (LayerDrawable) progressDrawable;
+ for (int i = 0; i < progressLayerDrawable.getNumberOfLayers(); i++) {
+ if (progressLayerDrawable.getId(i) != android.R.id.progress) continue;
+ Drawable primaryProgressDrawable = progressLayerDrawable.getDrawable(i);
+ if (!(primaryProgressDrawable instanceof ScaleDrawable)) continue;
+
+ ((ScaleDrawable) primaryProgressDrawable).getDrawable().copyBounds(
+ mPreviousDrawBounds);
+ }
+ }
+ }
+
+ @Override
+ protected void computeContentPadding(Rect outContentPadding) {
+ super.computeContentPadding(outContentPadding);
+ MarginLayoutParams layoutParams =
+ (MarginLayoutParams) mProgressView.getLayoutParams();
+ outContentPadding.offset(0, layoutParams.topMargin);
+ }
+ }
+
+ private static class ToolbarViewResourceAdapter extends ViewResourceAdapter {
+ private final int mToolbarActualHeightPx;
+ private final int[] mTempPosition = new int[2];
+
+ private final View mToolbarContainer;
+ private final Toolbar mToolbar;
+
+ /** Builds the resource adapter for the toolbar. */
+ public ToolbarViewResourceAdapter(View toolbarContainer, Toolbar toolbar) {
+ super(toolbarContainer);
+
+ mToolbarContainer = toolbarContainer;
+ mToolbar = toolbar;
+ mToolbarActualHeightPx = toolbarContainer.getResources().getDimensionPixelSize(
+ R.dimen.control_container_height);
+ }
+
+ /**
+ * Force this resource to be recaptured in full, ignoring the checks
+ * {@link #invalidate(Rect)} does.
+ */
+ public void forceInvalidate() {
+ super.invalidate(null);
+ }
+
+ @Override
+ public boolean isDirty() {
+ return mToolbar != null && mToolbar.isReadyForTextureCapture() && super.isDirty();
+ }
+
+ @Override
+ protected void onCaptureStart(Canvas canvas, Rect dirtyRect) {
+ // Erase the shadow component of the bitmap if the clip rect included shadow. Because
+ // this region is not opaque painting twice would be bad.
+ if (dirtyRect.intersects(
+ 0, mToolbarActualHeightPx,
+ mToolbarContainer.getWidth(), mToolbarContainer.getHeight())) {
+ canvas.save();
+ canvas.clipRect(
+ 0, mToolbarActualHeightPx,
+ mToolbarContainer.getWidth(), mToolbarContainer.getHeight());
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ canvas.restore();
+ }
+
+ mToolbar.setTextureCaptureMode(true);
+
+ super.onCaptureStart(canvas, dirtyRect);
+ }
+
+ @Override
+ protected void onCaptureEnd() {
+ mToolbar.setTextureCaptureMode(false);
+ }
+
+ @Override
+ protected void computeContentPadding(Rect outContentPadding) {
+ outContentPadding.set(0, 0, mToolbarContainer.getWidth(), mToolbarActualHeightPx);
+ }
+
+ @Override
+ protected void computeContentAperture(Rect outContentAperture) {
+ mToolbar.getLocationBarContentRect(outContentAperture);
+ mToolbar.getPositionRelativeToContainer(mToolbarContainer, mTempPosition);
+ outContentAperture.offset(mTempPosition[0], mTempPosition[1]);
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // Don't eat the event if we don't have a handler.
+ if (mSwipeHandler == null) return false;
+
+ // If we have ACTION_DOWN in this context, that means either no child consumed the event or
+ // this class is the top UI at the event position. Then, we don't need to feed the event to
+ // mGestureDetector here because the event is already once fed in onInterceptTouchEvent().
+ // Moreover, we have to return true so that this class can continue to intercept all the
+ // subsequent events.
+ if (event.getActionMasked() == MotionEvent.ACTION_DOWN && !isOnTabStrip(event)) {
+ return true;
+ }
+
+ return mSwipeRecognizer.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (mSwipeHandler == null) return false;
+
+ return mSwipeRecognizer.onTouchEvent(event);
+ }
+
+ private boolean isOnTabStrip(MotionEvent e) {
+ return e.getY() <= mTabStripHeight;
+ }
+
+ private class SwipeRecognizerImpl extends SwipeRecognizer {
+ public SwipeRecognizerImpl(Context context) {
+ super(context);
+ }
+
+ @Override
+ public boolean shouldRecognizeSwipe(MotionEvent e1, MotionEvent e2) {
+ if (isOnTabStrip(e1)) return false;
+ if (mToolbar.shouldIgnoreSwipeGesture()) return false;
+ if (UiUtils.isKeyboardShowing(getContext(), ToolbarControlContainer.this)) return false;
+ if (mFindToolbarManager == null || mFindToolbarManager.isShowing()) return false;
+ return true;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698