Chromium Code Reviews| 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 |
| index 4ebb19b2cec8fbeb2b56dcde994d586e5dcde005..84a3956e981b51b89f3a9ae8b99b2bfd02e8f4ff 100644 |
| --- 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 |
| @@ -14,13 +14,18 @@ import org.chromium.base.ApplicationStatus; |
| import org.chromium.base.ApplicationStatus.ActivityStateListener; |
| import org.chromium.base.VisibleForTesting; |
| import org.chromium.chrome.browser.ChromeActivity; |
| +import org.chromium.chrome.browser.compositor.LayerTitleCache; |
| import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager.PanelPriority; |
| import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost; |
| +import org.chromium.chrome.browser.compositor.layouts.components.VirtualView; |
| import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEventFilter.ScrollDirection; |
| import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler; |
| import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter; |
| +import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilterHost; |
| import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureHandler; |
| -import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; |
| +import org.chromium.chrome.browser.compositor.layouts.eventfilter.OverlayPanelEventFilter; |
| +import org.chromium.chrome.browser.compositor.overlays.SceneOverlay; |
| +import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer; |
| import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; |
| import org.chromium.chrome.browser.tab.Tab; |
| import org.chromium.content.browser.ContentVideoViewEmbedder; |
| @@ -30,21 +35,19 @@ import org.chromium.content_public.common.TopControlsState; |
| import org.chromium.ui.base.LocalizationUtils; |
| import org.chromium.ui.resources.ResourceManager; |
| +import java.util.List; |
| + |
| /** |
| * Controls the Overlay Panel. |
| */ |
| public class OverlayPanel extends OverlayPanelAnimation implements ActivityStateListener, |
| - EdgeSwipeHandler, GestureHandler, OverlayPanelContentFactory { |
| + EdgeSwipeHandler, GestureHandler, OverlayPanelContentFactory, SceneOverlay { |
| - /** |
| - * The extra dp added around the close button touch target. |
| - */ |
| + /** The extra dp added around the close button touch target. */ |
| private static final int CLOSE_BUTTON_TOUCH_SLOP_DP = 5; |
| - /** |
| - * State of the Overlay Panel. |
| - */ |
| - public enum PanelState { |
| + /** State of the Overlay Panel. */ |
| + public static enum PanelState { |
| // TODO(pedrosimonetti): consider removing the UNDEFINED state |
| UNDEFINED, |
| CLOSED, |
| @@ -109,12 +112,15 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| /** Container for content the panel will show. */ |
| private OverlayPanelContent mContent; |
| - /** The {@link OverlayPanelHost} used to communicate with the supported layout. */ |
| - private OverlayPanelHost mOverlayPanelHost; |
| - |
| /** OverlayPanel manager handle for notifications of opening and closing. */ |
| protected OverlayPanelManager mPanelManager; |
| + /** If the base page text controlls have been cleared. */ |
|
David Trainor- moved to gerrit
2016/05/13 16:14:34
controlls -> controls
mdjones
2016/05/13 20:30:07
Done.
|
| + private boolean mDidClearTextControls; |
| + |
| + /** If the panel should be ignoring swipe events (for compatibility mode). */ |
| + private boolean mIgnoreSwipeEvents; |
| + |
| // ============================================================================================ |
| // Constructor |
| // ============================================================================================ |
| @@ -122,15 +128,17 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| /** |
| * @param context The current Android {@link Context}. |
| * @param updateHost The {@link LayoutUpdateHost} used to request updates in the Layout. |
| + * @param eventHost The {@link EventFilterHost} used to propagate events. |
| * @param panelManager The {@link OverlayPanelManager} responsible for showing panels. |
| */ |
| - public OverlayPanel(Context context, LayoutUpdateHost updateHost, |
| + public OverlayPanel(Context context, LayoutUpdateHost updateHost, EventFilterHost eventHost, |
| OverlayPanelManager panelManager) { |
| super(context, updateHost); |
| mContentFactory = this; |
| mPanelManager = panelManager; |
| mPanelManager.registerPanel(this); |
| + mEventFilter = new OverlayPanelEventFilter(mContext, eventHost, this); |
| } |
| /** |
| @@ -151,6 +159,7 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| @Override |
| protected void onClosed(StateChangeReason reason) { |
| + focusBasePage(); |
| destroyComponents(); |
| mPanelManager.notifyPanelClosed(this, reason); |
| } |
| @@ -178,13 +187,6 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| if (!isShowing()) return; |
| super.closePanel(reason, 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 && mOverlayPanelHost != null) { |
| - mOverlayPanelHost.hideLayout(true); |
| - } |
| } |
| /** |
| @@ -285,6 +287,38 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| return -mActivity.getFullscreenManager().getControlOffset() * mPxToDp; |
| } |
| + /** |
| + * Remove focus to the base page. |
| + */ |
| + protected void focusBasePage() { |
|
David Trainor- moved to gerrit
2016/05/13 16:14:34
I know we talked about this, but now that I see it
mdjones
2016/05/13 20:30:07
Changed this to only modify the visibility of the
|
| + if (mActivity == null) return; |
| + ContentViewCore baseContentView = mActivity.getActivityTab().getContentViewCore(); |
| + |
| + // If the panel does not have focus or isn't open, return. |
| + if (!mDidClearTextControls || isPanelOpened() || baseContentView == null) return; |
| + |
| + // Return focus to base page. |
| + mDidClearTextControls = false; |
| + baseContentView.getContainerView().requestFocus(); |
| + baseContentView.updateTextSelectionUI(true); |
| + } |
| + |
| + /** |
| + * Clear focus from the base page. |
| + */ |
| + protected void clearBasePageFocus() { |
| + if (mActivity == null) return; |
| + ContentViewCore baseContentView = mActivity.getActivityTab().getContentViewCore(); |
| + |
| + // If content already has focus, return. |
| + if (mDidClearTextControls || !isPanelOpened()) return; |
|
David Trainor- moved to gerrit
2016/05/13 16:14:34
Do we have to check if baseContentView is null or
mdjones
2016/05/13 20:30:07
The assumption is that if the panel showed up, a b
|
| + |
| + // Remove focus from the base page. |
| + mDidClearTextControls = true; |
| + baseContentView.preserveSelectionOnNextLossOfFocus(); |
| + baseContentView.updateTextSelectionUI(false); |
| + } |
| + |
| // ============================================================================================ |
| // ActivityStateListener |
| // ============================================================================================ |
| @@ -469,35 +503,20 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| } |
| // ============================================================================================ |
| - // Animation Handling |
| + // OverlayPanelBase methods. |
| // ============================================================================================ |
| @Override |
| protected void onAnimationFinished() { |
| super.onAnimationFinished(); |
| - if (shouldHideOverlayPanelLayout()) { |
| - if (mOverlayPanelHost != null) { |
| - mOverlayPanelHost.hideLayout(false); |
| - } |
| + if (getPanelState() == PanelState.PEEKED || getPanelState() == PanelState.CLOSED) { |
| + focusBasePage(); |
| + } else { |
| + clearBasePageFocus(); |
| } |
| } |
| - /** |
| - * Whether the Overlay Panel Layout should be hidden. |
| - * |
| - * @return Whether the Overlay Panel Layout should be hidden. |
| - */ |
| - private boolean shouldHideOverlayPanelLayout() { |
| - final PanelState state = getPanelState(); |
| - return (state == PanelState.PEEKED || state == PanelState.CLOSED) |
| - && getHeight() == getPanelHeightFromState(state); |
| - } |
| - |
| - // ============================================================================================ |
| - // ContextualSearchPanelBase methods. |
| - // ============================================================================================ |
| - |
| @Override |
| protected int getControlContainerHeightResource() { |
| // TODO(mdjones): Investigate passing this in to the constructor instead. |
| @@ -510,35 +529,10 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| // ============================================================================================ |
| /** |
| - * Sets the {@link OverlayPanelHost} used to communicate with the supported layout. |
| - * @param host The {@link OverlayPanelHost}. |
| - */ |
| - public void setHost(OverlayPanelHost host) { |
| - mOverlayPanelHost = host; |
| - } |
| - |
| - /** |
| - * @return The scene layer used to draw this panel. |
| + * Updates the Panel so it preserves its state when the orientation changes. |
| */ |
| - public SceneLayer getSceneLayer() { |
| - return null; |
| - } |
| - |
| - /** |
| - * Update this panel's scene layer. This should be implemented by each panel type. |
| - * @param resourceManager Used to access static resources. |
| - */ |
| - public void updateSceneLayer(ResourceManager resourceManager) { |
| - } |
| - |
| - /** |
| - * Determine if using a second layout for showing the overlay panel is possible. This should |
| - * be overridden by each panel and returns true by default. |
| - * @return True if the layout is supported. |
| - * TODO(mdjones): Rename to supportsOverlayPanelLayout once the corresponding class is renamed. |
| - */ |
| - public boolean supportsContextualSearchLayout() { |
| - return true; |
| + protected void updatePanelForOrientationChange() { |
| + resizePanelToState(getPanelState(), StateChangeReason.UNKNOWN); |
| } |
| // ============================================================================================ |
| @@ -760,21 +754,31 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| @Override |
| public void swipeStarted(ScrollDirection direction, float x, float y) { |
| + if (onInterceptBarSwipe()) { |
| + mIgnoreSwipeEvents = true; |
| + return; |
| + } |
| handleSwipeStart(); |
| } |
| @Override |
| public void swipeUpdated(float x, float y, float dx, float dy, float tx, float ty) { |
| + if (mIgnoreSwipeEvents) return; |
| handleSwipeMove(ty); |
| } |
| @Override |
| public void swipeFinished() { |
| + if (mIgnoreSwipeEvents) { |
| + mIgnoreSwipeEvents = false; |
| + return; |
| + } |
| handleSwipeEnd(); |
| } |
| @Override |
| public void swipeFlingOccurred(float x, float y, float tx, float ty, float vx, float vy) { |
| + if (mIgnoreSwipeEvents) return; |
| handleFling(vy); |
| } |
| @@ -782,4 +786,103 @@ public class OverlayPanel extends OverlayPanelAnimation implements ActivityState |
| public boolean isSwipeEnabled(ScrollDirection direction) { |
| return direction == ScrollDirection.UP && isShowing(); |
| } |
| + |
| + // ============================================================================================ |
| + // SceneOverlay implementation. |
| + // ============================================================================================ |
| + |
| + @Override |
| + public SceneOverlayLayer getUpdatedSceneOverlayTree(LayerTitleCache layerTitleCache, |
| + ResourceManager resourceManager, float yOffset) { |
| + return null; |
| + } |
| + |
| + @Override |
| + public EventFilter getEventFilter() { |
| + return mEventFilter; |
| + } |
| + |
| + @Override |
| + public void onSizeChanged(float width, float height, float visibleViewportOffsetY, |
| + int orientation) { |
| + onSizeChanged(width, height); |
| + } |
| + |
| + @Override |
| + public void getVirtualViews(List<VirtualView> views) { |
| + // TODO(mdjones): Add views for accessibility. |
| + } |
| + |
| + @Override |
| + public boolean handlesTabCreating() { |
| + // If the panel is not opened, do not handle tab creating. |
| + if (!isPanelOpened()) return false; |
| + // Updates TopControls' State so the Toolbar becomes visible. |
| + // TODO(pedrosimonetti): The transition when promoting to a new tab is only smooth |
| + // if the SearchContentView's vertical scroll position is zero. Otherwise the |
| + // ContentView will appear to jump in the screen. Coordinate with @dtrainor to solve |
| + // this problem. |
| + updateTopControlsState(TopControlsState.BOTH, false); |
| + return true; |
| + } |
| + |
| + @Override |
| + public boolean shouldHideAndroidTopControls() { |
| + return isPanelOpened(); |
| + } |
| + |
| + @Override |
| + public boolean updateOverlay(long time, long dt) { |
| + if (isPanelOpened()) clearBasePageFocus(); |
| + return super.onUpdateAnimation(time, false); |
| + } |
| + |
| + @Override |
| + public void onHideLayout() { |
| + if (!isShowing()) return; |
| + closePanel(StateChangeReason.UNKNOWN, false); |
| + } |
| + |
| + @Override |
| + public boolean onBackPressed() { |
| + if (!isPanelOpened()) return false; |
| + closePanel(StateChangeReason.BACK_PRESS, true); |
| + return true; |
| + } |
| + |
| + @Override |
| + public void tabTitleChanged(int tabId, String title) {} |
| + |
| + @Override |
| + public void tabStateInitialized() {} |
| + |
| + @Override |
| + public void tabModelSwitched(boolean incognito) {} |
| + |
| + @Override |
| + public void tabSelected(long time, boolean incognito, int id, int prevId) {} |
| + |
| + @Override |
| + public void tabMoved(long time, boolean incognito, int id, int oldIndex, int newIndex) {} |
| + |
| + @Override |
| + public void tabClosed(long time, boolean incognito, int id) {} |
| + |
| + @Override |
| + public void tabClosureCancelled(long time, boolean incognito, int id) {} |
| + |
| + @Override |
| + public void tabCreated(long time, boolean incognito, int id, int prevId, boolean selected) {} |
| + |
| + @Override |
| + public void tabPageLoadStarted(int id, boolean incognito) {} |
| + |
| + @Override |
| + public void tabPageLoadFinished(int id, boolean incognito) {} |
| + |
| + @Override |
| + public void tabLoadStarted(int id, boolean incognito) {} |
| + |
| + @Override |
| + public void tabLoadFinished(int id, boolean incognito) {} |
| } |