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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java

Issue 1372963005: Separate ContextualSearchPanel from OverlayPanel (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rebase-extract-management-delegate
Patch Set: fix redundant null check Created 5 years, 2 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/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4aa8fe67fe81b2f7856d4a6377ab3af7923d07f
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanel.java
@@ -0,0 +1,405 @@
+// 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.compositor.bottombar;
+
+import android.content.Context;
+
+import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.ChromeActivity;
+import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanelAnimation;
+import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.content.browser.ContentViewCore;
+
+/**
+ * Controls the Overlay Panel.
+ */
+public class OverlayPanel extends ContextualSearchPanelAnimation
+ implements OverlayPanelContentFactory {
+
+ /**
+ * State of the Overlay Panel.
+ */
+ public static enum PanelState {
+ UNDEFINED,
+ CLOSED,
+ PEEKED,
+ EXPANDED,
+ MAXIMIZED;
+ }
+
+ /**
+ * The reason for a change in the Overlay Panel's state.
+ * TODO(mdjones): Separate generic reasons from Contextual Search reasons.
+ */
+ public static enum StateChangeReason {
+ UNKNOWN,
+ RESET,
+ BACK_PRESS,
+ TEXT_SELECT_TAP,
+ TEXT_SELECT_LONG_PRESS,
+ INVALID_SELECTION,
+ CLEARED_SELECTION,
+ BASE_PAGE_TAP,
+ BASE_PAGE_SCROLL,
+ SEARCH_BAR_TAP,
+ SERP_NAVIGATION,
+ TAB_PROMOTION,
+ CLICK,
+ SWIPE,
+ FLING,
+ OPTIN,
+ OPTOUT,
+ CLOSE_BUTTON;
+ }
+
+ /**
+ * The activity this panel is in.
+ */
+ protected ChromeActivity mActivity;
+
+ /**
+ * The initial height of the Overlay Panel.
+ */
+ private float mInitialPanelHeight;
+
+ /**
+ * Whether a touch gesture has been detected.
+ */
+ private boolean mHasDetectedTouchGesture;
+
+ /**
+ * That factory that creates OverlayPanelContents.
+ */
+ private OverlayPanelContentFactory mContentFactory;
+
+ /**
+ * Container for content the panel will show.
+ */
+ private OverlayPanelContent mContent;
+
+ // ============================================================================================
+ // Constructor
+ // ============================================================================================
+
+ /**
+ * @param context The current Android {@link Context}.
+ * @param updateHost The {@link LayoutUpdateHost} used to request updates in the Layout.
+ */
+ public OverlayPanel(Context context, LayoutUpdateHost updateHost) {
+ super(context, updateHost);
+ mContentFactory = this;
+ }
+
+ /**
+ * Destroy the native components associated with this panel's content.
+ */
+ public void destroy() {
+ destroyOverlayPanelContent();
+ }
+
+ @Override
+ protected void onClosed(StateChangeReason reason) {
+ destroy();
+ }
+
+ // ============================================================================================
+ // General API
+ // ============================================================================================
+
+ /**
+ * @return True if the panel is in the PEEKED state.
+ */
+ public boolean isPeeking() {
+ return doesPanelHeightMatchState(PanelState.PEEKED);
+ }
+
+ /**
+ * @return Whether the Panel is in its expanded state.
+ */
+ public boolean isExpanded() {
+ return doesPanelHeightMatchState(PanelState.EXPANDED);
+ }
+
+ /**
+ * @param url The URL that the panel should load.
+ */
+ public void loadUrlInPanel(String url) {
+ getOverlayPanelContent().loadUrl(url);
+ }
+
+ /**
+ * @return True if a URL has been loaded in the panel's current ContentViewCore.
+ */
+ public boolean isProcessingPendingNavigation() {
+ return mContent != null && mContent.isProcessingPendingNavigation();
+ }
+
+ /**
+ * @param activity The ChromeActivity associated with the panel.
+ */
+ public void setChromeActivity(ChromeActivity activity) {
+ mActivity = activity;
+ }
+
+ // ============================================================================================
+ // Content
+ // ============================================================================================
+
+ /**
+ * @return True if the panel's content view is showing.
+ */
+ public boolean isContentShowing() {
+ return mContent != null && mContent.isContentShowing();
+ }
+
+ /**
+ * @return The ContentViewCore that this panel currently holds.
+ */
+ public ContentViewCore getContentViewCore() {
+ // Expose OverlayPanelContent method.
+ return mContent != null ? mContent.getContentViewCore() : null;
+ }
+
+ /**
+ * Create a new OverlayPanelContent object. This can be overridden for tests.
+ * @return A new OverlayPanelContent object.
+ */
+ public OverlayPanelContent createNewOverlayPanelContent() {
+ return new OverlayPanelContent(new OverlayContentDelegate(),
+ new OverlayContentProgressObserver(), mActivity);
+ }
+
+ /**
+ * @return A new OverlayPanelContent if the instance was null or the existing one.
+ */
+ protected OverlayPanelContent getOverlayPanelContent() {
+ // Only create the content when necessary
+ if (mContent == null) {
+ mContent = mContentFactory.createNewOverlayPanelContent();
+ }
+ return mContent;
+ }
+
+ /**
+ * Destroy the native components of the OverlayPanelContent.
+ */
+ protected void destroyOverlayPanelContent() {
+ // It is possible that an OverlayPanelContent was never created for this panel.
+ if (mContent != null) {
+ mContent.destroy();
+ mContent = null;
+ }
+ }
+
+ /**
+ * Sets the top control state based on the internals of the panel.
+ */
+ public void updateTopControlsState() {
+ if (mContent == null) return;
+
+ if (isFullscreenSizePanel()) {
+ // Consider the ContentView height to be fullscreen, and inform the system that
+ // the Toolbar is always visible (from the Compositor's perspective), even though
+ // the Toolbar and Base Page might be offset outside the screen. This means the
+ // renderer will consider the ContentView height to be the fullscreen height
+ // minus the Toolbar height.
+ //
+ // This is necessary to fix the bugs: crbug.com/510205 and crbug.com/510206
+ mContent.updateTopControlsState(false, true, false);
+ } else {
+ mContent.updateTopControlsState(true, false, false);
+ }
+ }
+
+ /**
+ * Remove the last entry from history provided it is in a given time frame.
+ * @param historyUrl The URL to remove.
+ * @param urlTimeMs The time that the URL was visited.
+ */
+ public void removeLastHistoryEntry(String historyUrl, long urlTimeMs) {
+ if (mContent == null) return;
+ // Expose OverlayPanelContent method.
+ mContent.removeLastHistoryEntry(historyUrl, urlTimeMs);
+ }
+
+ /**
+ * @return The vertical scroll position of the content.
+ */
+ public float getContentVerticalScroll() {
+ return mContent.getContentVerticalScroll();
+ }
+
+ // ============================================================================================
+ // ContextualSearchPanelBase methods.
+ // ============================================================================================
+
+ @Override
+ protected int getControlContainerHeightResource() {
+ // TODO(mdjones): Investigate passing this in to the constructor instead.
+ assert mActivity != null;
+ return mActivity.getControlContainerHeightResource();
+ }
+
+ // ============================================================================================
+ // Generic Event Handling
+ // ============================================================================================
+
+ /**
+ * Handles the beginning of the swipe gesture.
+ */
+ public void handleSwipeStart() {
+ if (animationIsRunning()) {
+ cancelHeightAnimation();
+ }
+
+ mHasDetectedTouchGesture = false;
+ mInitialPanelHeight = getHeight();
+ }
+
+ /**
+ * Handles the movement of the swipe gesture.
+ *
+ * @param ty The movement's total displacement in dps.
+ */
+ public void handleSwipeMove(float ty) {
+ if (ty > 0 && getPanelState() == PanelState.MAXIMIZED) {
+ // Resets the Content View scroll position when swiping the Panel down
+ // after being maximized.
+ mContent.resetContentViewScroll();
+ }
+
+ // Negative ty value means an upward movement so subtracting ty means expanding the panel.
+ setClampedPanelHeight(mInitialPanelHeight - ty);
+ requestUpdate();
+ }
+
+ /**
+ * Handles the end of the swipe gesture.
+ */
+ public void handleSwipeEnd() {
+ // This method will be called after handleFling() and handleClick()
+ // methods because we also need to track down the onUpOrCancel()
+ // action from the Layout. Therefore the animation to the nearest
+ // PanelState should only happen when no other gesture has been
+ // detected.
+ if (!mHasDetectedTouchGesture) {
+ mHasDetectedTouchGesture = true;
+ animateToNearestState();
+ }
+ }
+
+ /**
+ * Handles the fling gesture.
+ *
+ * @param velocity The velocity of the gesture in dps per second.
+ */
+ public void handleFling(float velocity) {
+ mHasDetectedTouchGesture = true;
+ animateToProjectedState(velocity);
+ }
+
+ /**
+ * Handles the click gesture.
+ *
+ * @param time The timestamp of the gesture.
+ * @param x The x coordinate of the gesture.
+ * @param y The y coordinate of the gesture.
+ */
+ public void handleClick(long time, float x, float y) {
+ mHasDetectedTouchGesture = true;
+ if (isCoordinateInsideBasePage(x, y)) {
+ closePanel(StateChangeReason.BASE_PAGE_TAP, true);
+ } else if (isCoordinateInsideBar(x, y) && !onInterceptBarClick()) {
+ handleBarClick(time, x, y);
+ }
+ }
+
+ /**
+ * Handles the click gesture specifically on the bar.
+ *
+ * @param time The timestamp of the gesture.
+ * @param x The x coordinate of the gesture.
+ * @param y The y coordinate of the gesture.
+ */
+ protected void handleBarClick(long time, float x, float y) {
+ if (isPeeking()) {
+ if (supportsExpandedState()) {
+ expandPanel(StateChangeReason.SEARCH_BAR_TAP);
+ } else {
+ maximizePanel(StateChangeReason.SEARCH_BAR_TAP);
+ }
+ }
+ }
+
+ /**
+ * Allows the click on the bar to be intercepted.
+ * @return True if the click on the bar was intercepted by this function.
+ */
+ protected boolean onInterceptBarClick() {
+ return false;
+ }
+
+ // ============================================================================================
+ // Gesture Event helpers
+ // ============================================================================================
+
+ /**
+ * @param x The x coordinate in dp.
+ * @param y The y coordinate in dp.
+ * @return Whether the given coordinate is inside the bar area of the overlay.
+ */
+ public boolean isCoordinateInsideBar(float x, float y) {
+ return isCoordinateInsideOverlayPanel(x, y)
+ && y >= getOffsetY() && y <= (getOffsetY() + getSearchBarContainerHeight());
+ }
+
+ /**
+ * @param x The x coordinate in dp.
+ * @param y The y coordinate in dp.
+ * @return Whether the given coordinate is inside the Overlay Content View area.
+ */
+ public boolean isCoordinateInsideContent(float x, float y) {
+ return isCoordinateInsideOverlayPanel(x, y)
+ && y > getContentY();
+ }
+
+ /**
+ * @return The horizontal offset of the Overlay Content View in dp.
+ */
+ public float getContentX() {
+ return getOffsetX();
+ }
+
+ /**
+ * @return The vertical offset of the Overlay Content View in dp.
+ */
+ public float getContentY() {
+ return getOffsetY() + getSearchBarContainerHeight() + getPromoHeight();
+ }
+
+ /**
+ * @param x The x coordinate in dp.
+ * @param y The y coordinate in dp.
+ * @return Whether the given coordinate is inside the Overlay Panel area.
+ */
+ private boolean isCoordinateInsideOverlayPanel(float x, float y) {
+ return y >= getOffsetY() && y <= (getOffsetY() + getHeight())
+ && x >= getOffsetX() && x <= (getOffsetX() + getWidth());
+ }
+
+ /**
+ * @param x The x coordinate in dp.
+ * @param y The y coordinate in dp.
+ * @return Whether the given coordinate is inside the Base Page area.
+ */
+ private boolean isCoordinateInsideBasePage(float x, float y) {
+ return !isCoordinateInsideOverlayPanel(x, y);
+ }
+
+ @VisibleForTesting
+ public void setOverlayPanelContentFactory(OverlayPanelContentFactory factory) {
+ mContentFactory = factory;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698