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

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

Issue 987883002: Upstream Layout.java and associated files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move to SuppressFBWarnings from findbugs_exclude.xml Created 5 years, 9 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/contextualsearch/ContextualSearchPanel.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..188e231fccd98b23cd1ad4a1907e3f8765243d1a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -0,0 +1,440 @@
+// 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.contextualsearch;
+
+import android.content.Context;
+import android.os.Handler;
+
+import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
+
+/**
+ * Controls the Contextual Search Panel.
+ */
+public class ContextualSearchPanel extends ContextualSearchPanelAnimation
+ implements ContextualSearchPanelDelegate {
+
+ /**
+ * State of the Contextual Search Panel.
+ */
+ public static enum PanelState {
+ UNDEFINED,
+ CLOSED,
+ PEEKED,
+ PROMO,
+ EXPANDED,
+ MAXIMIZED;
+ }
+
+ /**
+ * The reason for a change in the Contextual Search Panel's state.
+ */
+ public static enum StateChangeReason {
+ UNKNOWN,
+ RESET,
+ BACK_PRESS,
+ TEXT_SELECT_TAP,
+ TEXT_SELECT_LONG_PRESS,
+ INVALID_SELECTION,
+ BASE_PAGE_TAP,
+ BASE_PAGE_SCROLL,
+ SEARCH_BAR_TAP,
+ SERP_NAVIGATION,
+ TAB_PROMOTION,
+ CLICK,
+ SWIPE,
+ FLING,
+ OPTIN,
+ OPTOUT;
+ }
+
+ /**
+ * The delay after which the hide progress will be hidden.
+ */
+ private static final long HIDE_PROGRESS_BAR_DELAY = 1000 / 60 * 4;
+
+ /**
+ * The initial height of the Contextual Search Panel.
+ */
+ private float mInitialPanelHeight;
+
+ /**
+ * Whether the Panel should be promoted to a new tab after being maximized.
+ */
+ private boolean mShouldPromoteToTabAfterMaximizing;
+
+ /**
+ * Whether a touch gesture has been detected.
+ */
+ private boolean mHasDetectedTouchGesture;
+
+ /**
+ * Whether the search content view has been touched.
+ */
+ private boolean mHasSearchContentViewBeenTouched;
+
+ /**
+ * The {@link ContextualSearchPanelHost} used to communicate with the supported layout.
+ */
+ private ContextualSearchPanelHost mSearchPanelHost;
+
+ /**
+ * The object for handling global Contextual Search management duties
+ */
+ private ContextualSearchManagementDelegate mManagementDelegate;
+
+ // ============================================================================================
+ // Constructor
+ // ============================================================================================
+
+ /**
+ * @param context The current Android {@link Context}.
+ * @param updateHost The {@link LayoutUpdateHost} used to request updates in the Layout.
+ */
+ public ContextualSearchPanel(Context context, LayoutUpdateHost updateHost) {
+ super(context, updateHost);
+ }
+
+ // ============================================================================================
+ // Layout Integration
+ // ============================================================================================
+
+ /**
+ * Sets the {@ContextualSearchPanelHost} used to communicate with the supported layout.
+ * @param host The {@ContextualSearchPanelHost}.
+ */
+ public void setHost(ContextualSearchPanelHost host) {
+ mSearchPanelHost = host;
+ }
+
+ // ============================================================================================
+ // Contextual Search Manager Integration
+ // ============================================================================================
+
+ /**
+ * Sets the {@code ContextualSearchManagementDelegate} associated with this Layout.
+ * @param delegate The {@code ContextualSearchManagementDelegate}.
+ */
+ public void setManagementDelegate(ContextualSearchManagementDelegate delegate) {
+ mManagementDelegate = delegate;
+ }
+
+ /**
+ * @return The {@code ContextualSearchManagementDelegate} associated with this Layout.
+ */
+ public ContextualSearchManagementDelegate getManagementDelegate() {
+ return mManagementDelegate;
+ }
+
+ /**
+ * Sets the visibility of the Search Content View.
+ * @param isVisible True to make it visible.
+ */
+ public void setSearchContentViewVisibility(boolean isVisible) {
+ if (mManagementDelegate != null) {
+ mManagementDelegate.setSearchContentViewVisibility(isVisible);
+ }
+ }
+
+ // ============================================================================================
+ // Generic Event Handling
+ // ============================================================================================
+
+ /**
+ * Handles the beginning of the swipe gesture.
+ */
+ public void handleSwipeStart() {
+ if (animationIsRunning()) {
+ cancelAnimation(this, Property.PANEL_HEIGHT);
+ }
+
+ 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 Search Content View scroll position when swiping the Panel down
+ // after being maximized.
+ mManagementDelegate.resetSearchContentViewScroll();
+ }
+
+ // 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 (isYCoordinateInsideBasePage(y)) {
+ closePanel(StateChangeReason.BASE_PAGE_TAP, true);
+ } else if (isYCoordinateInsideSearchBar(y)) {
+ // TODO(pedrosimonetti): handle click in the close button here.
+ if (isPeeking()) {
+ if (mManagementDelegate.isRunningInCompatibilityMode()) {
+ mManagementDelegate.openResolvedSearchUrlInNewTab();
+ } else {
+ expandPanel(StateChangeReason.SEARCH_BAR_TAP);
+ }
+ } else if (isExpanded()) {
+ peekPanel(StateChangeReason.SEARCH_BAR_TAP);
+ } else if (isMaximized()) {
+ mManagementDelegate.promoteToTab(true);
+ }
+ }
+ }
+
+ // ============================================================================================
+ // Gesture Event helpers
+ // ============================================================================================
+
+ /**
+ * @param y The y coordinate in dp.
+ * @return Whether the given |y| coordinate is inside the Search Bar area.
+ */
+ public boolean isYCoordinateInsideSearchBar(float y) {
+ return !isYCoordinateInsideBasePage(y) && !isYCoordinateInsideSearchContentView(y);
+ }
+
+ /**
+ * @param y The y coordinate in dp.
+ * @return Whether the given |y| coordinate is inside the Search Content
+ * View area.
+ */
+ public boolean isYCoordinateInsideSearchContentView(float y) {
+ return y > getSearchContentViewOffsetY();
+ }
+
+ /**
+ * @return The vertical offset of the Search Content View in dp.
+ */
+ public float getSearchContentViewOffsetY() {
+ return getOffsetY() + getSearchBarHeight();
+ }
+
+ /**
+ * @param y The y coordinate in dp.
+ * @return Whether the given |y| coordinate is inside the Base Page area.
+ */
+ private boolean isYCoordinateInsideBasePage(float y) {
+ return y < getOffsetY();
+ }
+
+ /**
+ * @return Whether the Panel is in its expanded state.
+ */
+ protected boolean isExpanded() {
+ return doesPanelHeightMatchState(PanelState.EXPANDED);
+ }
+
+ /**
+ * Acknowledges that there was a touch in the search content view, though no immediate action
+ * needs to be taken.
+ */
+ public void onTouchSearchContentViewAck() {
+ mHasSearchContentViewBeenTouched = true;
+ }
+
+ // ============================================================================================
+ // Animation Handling
+ // ============================================================================================
+
+ @Override
+ protected void onAnimationFinished() {
+ super.onAnimationFinished();
+
+ if (shouldHideContextualSearchLayout()) {
+ if (mSearchPanelHost != null) {
+ mSearchPanelHost.hideLayout(false);
+ }
+ if (getPanelState() == PanelState.CLOSED) {
+ mManagementDelegate.dismissContextualSearchBar();
+ }
+ }
+
+ if (mShouldPromoteToTabAfterMaximizing && getPanelState() == PanelState.MAXIMIZED) {
+ mShouldPromoteToTabAfterMaximizing = false;
+ mManagementDelegate.promoteToTab(false);
+ }
+ }
+
+ /**
+ * Whether the Contextual Search Layout should be hidden.
+ *
+ * @return Whether the Contextual Search Layout should be hidden.
+ */
+ private boolean shouldHideContextualSearchLayout() {
+ final PanelState state = getPanelState();
+
+ return (state == PanelState.PEEKED || state == PanelState.CLOSED)
+ && getHeight() == getPanelHeightFromState(state);
+ }
+
+ // ============================================================================================
+ // Panel Delegate
+ // ============================================================================================
+
+ @Override
+ public boolean isShowing() {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ return super.isShowing();
+ }
+
+ @Override
+ public boolean isPeeking() {
+ return doesPanelHeightMatchState(PanelState.PEEKED);
+ }
+
+ @Override
+ public void maximizePanelThenPromoteToTab(StateChangeReason reason) {
+ mShouldPromoteToTabAfterMaximizing = true;
+ maximizePanel(reason);
+ }
+
+ @Override
+ public void maximizePanelThenPromoteToTab(StateChangeReason reason, long duration) {
+ mShouldPromoteToTabAfterMaximizing = true;
+ animatePanelToState(PanelState.MAXIMIZED, reason, duration);
+ }
+
+ @Override
+ public void peekPanel(StateChangeReason reason) {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.peekPanel(reason);
+
+ if (getPanelState() == PanelState.CLOSED || getPanelState() == PanelState.PEEKED) {
+ mHasSearchContentViewBeenTouched = false;
+ }
+ }
+
+ @Override
+ public void closePanel(StateChangeReason reason, boolean animate) {
+ // If the close action is animated, the Layout will be hidden when
+ // the animation is finished, so we should only hide the Layout
+ // here when not animating.
+ if (!animate && mSearchPanelHost != null) {
+ mSearchPanelHost.hideLayout(true);
+ }
+ mHasSearchContentViewBeenTouched = false;
+
+ super.closePanel(reason, animate);
+ }
+
+ @Override
+ public void updateBasePageSelectionYPx(float y) {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.updateBasePageSelectionYPx(y);
+ }
+
+ @Override
+ public void setPromoContentHeight(float height) {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.setPromoContentHeight(height);
+ }
+
+ @Override
+ public void setShouldHidePromoHeader(boolean shouldHidePromoHeader) {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.setShouldHidePromoHeader(shouldHidePromoHeader);
+ }
+
+ @Override
+ public void animateAfterFirstRunSuccess() {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.animateAfterFirstRunSuccess();
+ }
+
+ @Override
+ public void onLoadStarted() {
+ setProgressBarCompletion(0);
+ setProgressBarVisible(true);
+ requestUpdate();
+ }
+
+ @Override
+ public void onLoadStopped() {
+ // Hides the Progress Bar after a delay to make sure it is rendered for at least
+ // a few frames, otherwise its completion won't be visually noticeable.
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ setProgressBarVisible(false);
+ requestUpdate();
+ }
+ }, HIDE_PROGRESS_BAR_DELAY);
+ }
+
+ @Override
+ public void onLoadProgressChanged(int progress) {
+ setProgressBarCompletion(progress);
+ requestUpdate();
+ }
+
+ @Override
+ public PanelState getPanelState() {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ return super.getPanelState();
+ }
+
+ @Override
+ public void setDidSearchInvolvePromo() {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.setDidSearchInvolvePromo();
+ }
+
+ @Override
+ public void setWasSearchContentViewSeen() {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.setWasSearchContentViewSeen();
+ }
+
+ @Override
+ public void setIsPromoActive(boolean shown) {
+ // NOTE(pedrosimonetti): exposing superclass method to the interface.
+ super.setIsPromoActive(shown);
+ }
+
+ @Override
+ public boolean didTouchSearchContentView() {
+ return mHasSearchContentViewBeenTouched;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698