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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.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/layouts/Layout.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d2c08ab214bc26014752a430942de352c9dbe3a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -0,0 +1,1181 @@
+// 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.layouts;
+
+import static org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.AnimatableAnimation.createAnimation;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Interpolator;
+
+import org.chromium.base.VisibleForTesting;
+import org.chromium.base.annotations.SuppressFBWarnings;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.compositor.LayerTitleCache;
+import org.chromium.chrome.browser.compositor.bottombar.contextualsearch.ContextualSearchPanel;
+import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animatable;
+import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animation;
+import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
+import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
+import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEventFilter.ScrollDirection;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
+import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
+import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.compositor.scene_layer.SceneOverlayLayer;
+import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelUtils;
+import org.chromium.content.browser.ContentViewCore;
+import org.chromium.ui.resources.ResourceManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Abstract representation of an OpenGL layout tailored to draw tabs. It is a framework used as an
+ * alternative to the Android UI for lower level hardware accelerated rendering.
+ * This layout also pass through all the events that may happen.
+ */
+
+public abstract class Layout implements TabContentManager.ThumbnailChangeListener {
+ /**
+ * The orientation of the device.
+ */
+ public interface Orientation {
+ public static final int UNSET = 0;
+ public static final int PORTRAIT = 1;
+ public static final int LANDSCAPE = 2;
+ }
+
+ /**
+ * The sizing requirements of each layout. These flags allow each layout to specify certain
+ * sizing allowances/constraints by combining them.
+ *
+ * TODO(dtrainor): Flesh out support for all of these flag combinations.
+ */
+ public interface SizingFlags {
+ /**
+ * The toolbar is allowed to be hidden.
+ */
+ public static final int ALLOW_TOOLBAR_HIDE = 0x1;
+
+ /**
+ * The toolbar is allowed to be shown.
+ */
+ public static final int ALLOW_TOOLBAR_SHOW = 0x10;
+
+ /**
+ * The toolbar is allowed to animate between the transitions. Note that this flag is not
+ * completely supported in all combinations with the other flags. As functionality is
+ * added and required this will be improved.
+ */
+ public static final int ALLOW_TOOLBAR_ANIMATE = 0x100;
+
+ /**
+ * The layout requires a fullscreen size regardless of the toolbar position.
+ */
+ public static final int REQUIRE_FULLSCREEN_SIZE = 0x1000;
+
+ /**
+ * The layout does not support fullscreen and it should animate the toolbar away.
+ * A helper flag to make it easier to specify restrictions.
+ */
+ public static final int HELPER_NO_FULLSCREEN_SUPPORT =
+ ALLOW_TOOLBAR_SHOW | ALLOW_TOOLBAR_ANIMATE;
+
+ /**
+ * The layout supports persistent fullscreen and should hide the toolbar immediately.
+ * A helper flag to make it easier to specify restrictions.
+ */
+ public static final int HELPER_HIDE_TOOLBAR_IMMEDIATE = ALLOW_TOOLBAR_HIDE;
+
+ /**
+ * The layout fully supports fullscreen and the toolbar is allowed to show, hide, and
+ * animate.
+ * A helper flag to make it easier to specify restrictions.
+ */
+ public static final int HELPER_SUPPORTS_FULLSCREEN =
+ ALLOW_TOOLBAR_HIDE | ALLOW_TOOLBAR_SHOW | ALLOW_TOOLBAR_ANIMATE;
+ }
+
+ // Defines to make the code easier to read.
+ public static final boolean NEED_TITLE = true;
+ public static final boolean NO_TITLE = false;
+ public static final boolean SHOW_CLOSE_BUTTON = true;
+ public static final boolean NO_CLOSE_BUTTON = false;
+
+ /** Length of the unstalling animation. **/
+ public static final long UNSTALLED_ANIMATION_DURATION_MS = 500;
+
+ // Drawing area properties.
+ private float mWidth;
+ private float mHeight;
+ private float mHeightMinusTopControls;
+
+ /** A {@link Context} instance. */
+ private Context mContext;
+
+ /** The current {@link Orientation} of the layout. */
+ private int mCurrentOrientation;
+
+ // Tabs
+ protected TabModelSelector mTabModelSelector;
+ protected TabContentManager mTabContentManager;
+
+ private ChromeAnimation<Animatable<?>> mLayoutAnimations;
+
+ // Tablet tab strip managers.
+ private final List<SceneOverlay> mSceneOverlays = new ArrayList<SceneOverlay>();
+
+ // Helpers
+ private final LayoutUpdateHost mUpdateHost;
+ protected final LayoutRenderHost mRenderHost;
+ private EventFilter mEventFilter;
+
+ /** The tabs currently being rendered as part of this layout. The tabs are
+ * drawn using the same ordering as this array. */
+ protected LayoutTab[] mLayoutTabs;
+
+ // True means that the layout is going to hide as soon as the animation finishes.
+ private boolean mIsHiding;
+
+ // The next id to show when the layout is hidden, or TabBase#INVALID_TAB_ID if no change.
+ private int mNextTabId = Tab.INVALID_TAB_ID;
+
+ /**
+ * The {@link Layout} is not usable until sizeChanged is called.
+ * This is convenient this way so we can pre-create the layout before the host is fully defined.
+ * @param context The current Android's context.
+ * @param updateHost The parent {@link LayoutUpdateHost}.
+ * @param renderHost The parent {@link LayoutRenderHost}.
+ * @param eventFilter The {@link EventFilter} this {@link Layout} is listening to.
+ */
+ public Layout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost,
+ EventFilter eventFilter) {
+ mContext = context;
+ mUpdateHost = updateHost;
+ mRenderHost = renderHost;
+ mEventFilter = eventFilter;
+
+ // Invalid sizes
+ mWidth = -1;
+ mHeight = -1;
+ mHeightMinusTopControls = -1;
+
+ mCurrentOrientation = Orientation.UNSET;
+ }
+
+ /**
+ * Adds a {@link SceneOverlay} that can potentially be shown on top of this {@link Layout}. The
+ * {@link SceneOverlay}s added to this {@link Layout} will be cascaded in the order they are
+ * added. The {@link SceneOverlay} added first will become the content of the
+ * {@link SceneOverlay} added second, and so on.
+ * @param helper A {@link SceneOverlay} to add as a potential overlay for this {@link Layout}.
+ */
+ public void addSceneOverlay(SceneOverlay helper) {
+ assert !mSceneOverlays.contains(helper);
+ mSceneOverlays.add(helper);
+ }
+
+ /**
+ * Cleans up any internal state. This object should not be used after this call.
+ */
+ public void destroy() {
+ }
+
+ /**
+ * @return The current {@link Context} instance associated with this {@link Layout}.
+ */
+ public Context getContext() {
+ return mContext;
+ }
+
+ /**
+ * @return Whether the {@link Layout} is currently active.
+ */
+ public boolean isActive() {
+ return mUpdateHost.isActiveLayout(this);
+ }
+
+ /**
+ * @return A {@link View} that should be the one the user can interact with. This can be
+ * {@code null} if there is no {@link View} representing {@link Tab} content that should
+ * be interacted with at this time.
+ */
+ public View getViewForInteraction() {
+ if (!shouldDisplayContentOverlay()) return null;
+
+ Tab tab = mTabModelSelector.getCurrentTab();
+ if (tab == null) return null;
+
+ return tab.getView();
+ }
+
+ /**
+ * Used to get a list of Android {@link View}s that represent both the normal content as well as
+ * overlays.
+ * @param views A {@link List} that will be populated with {@link View}s that represent all of
+ * the content in this {@link Layout}.
+ */
+ public void getAllViews(List<View> views) {
+ Tab tab = mTabModelSelector.getCurrentTab();
+ if (tab == null) return;
+ tab.getAllViews(views);
+ }
+
+ /**
+ * Used to get a list of {@link ContentViewCore}s that represent both the normal content as well
+ * as overlays. These are all {@link ContentViewCore}s currently showing or rendering content
+ * for this {@link Layout}.
+ * @param contents A {@link List} that will be populated with {@link ContentViewCore}s currently
+ * rendering content related to this {@link Layout}.
+ */
+ public void getAllContentViewCores(List<ContentViewCore> contents) {
+ Tab tab = mTabModelSelector.getCurrentTab();
+ if (tab == null) return;
+ tab.getAllContentViewCores(contents);
+ }
+
+ /**
+ * Get a list of virtual views for accessibility.
+ *
+ * @param views A List to populate with virtual views.
+ */
+ public void getVirtualViews(List<VirtualView> views) {
+ // TODO(dtrainor): Investigate order.
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).getVirtualViews(views);
+ }
+ }
+
+ /**
+ * Creates a {@link LayoutTab}.
+ * @param id The id of the reference {@link Tab} in the {@link TabModel}.
+ * @param isIncognito Whether the new tab is incognito.
+ * @param showCloseButton True to show and activate a close button on the border.
+ * @param isTitleNeeded Whether a title will be shown.
+ * @return The newly created {@link LayoutTab}.
+ */
+ public LayoutTab createLayoutTab(int id, boolean isIncognito,
+ boolean showCloseButton, boolean isTitleNeeded) {
+ return createLayoutTab(id, isIncognito, showCloseButton, isTitleNeeded, -1.f, -1.f);
+ }
+
+ /**
+ * Creates a {@link LayoutTab}.
+ * @param id The id of the reference {@link Tab} in the {@link TabModel}.
+ * @param isIncognito Whether the new tab is incognito.
+ * @param showCloseButton True to show and activate a close button on the border.
+ * @param isTitleNeeded Whether a title will be shown.
+ * @param maxContentWidth The max content width of the tab. Negative numbers will use the
+ * original content width.
+ * @param maxContentHeight The max content height of the tab. Negative numbers will use the
+ * original content height.
+ * @return The newly created {@link LayoutTab}.
+ */
+ public LayoutTab createLayoutTab(int id, boolean isIncognito, boolean showCloseButton,
+ boolean isTitleNeeded, float maxContentWidth, float maxContentHeight) {
+ LayoutTab layoutTab = mUpdateHost.createLayoutTab(
+ id, isIncognito, showCloseButton, isTitleNeeded, maxContentWidth, maxContentHeight);
+ initLayoutTabFromHost(layoutTab);
+ return layoutTab;
+ }
+
+ /**
+ * Releases the data we keep for that {@link LayoutTab}.
+ * @param layoutTab The {@link LayoutTab} to release.
+ */
+ public void releaseTabLayout(LayoutTab layoutTab) {
+ mUpdateHost.releaseTabLayout(layoutTab.getId());
+ }
+
+ /**
+ * Update the animation and give chance to cascade the changes.
+ * @param time The current time of the app in ms.
+ * @param dt The delta time between update frames in ms.
+ * @return Whether the layout is done updating.
+ */
+ public final boolean onUpdate(long time, long dt) {
+ final boolean doneAnimating = onUpdateAnimation(time, false);
+
+ // Don't update the layout if onUpdateAnimation ended up making a new layout active.
+ if (mUpdateHost.isActiveLayout(this)) updateLayout(time, dt);
+
+ return doneAnimating;
+ }
+
+ /**
+ * Layout-specific updates. Cascades the values updated by the animations.
+ * @param time The current time of the app in ms.
+ * @param dt The delta time between update frames in ms.
+ */
+ protected void updateLayout(long time, long dt) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).updateOverlay(time, dt);
+ }
+ }
+
+ /**
+ * Request that the renderer render a frame (after the current frame). This
+ * should be called whenever a new frame should be rendered.
+ */
+ public void requestRender() {
+ mRenderHost.requestRender();
+ }
+
+ /**
+ * Requests one more frame of refresh for the transforms and changing properties. Primarily,
+ * this is so animations can continue to animate.
+ */
+ public void requestUpdate() {
+ mUpdateHost.requestUpdate();
+ }
+
+ /**
+ * Called when the context and size of the view has changed.
+ *
+ * @param context The current Android's context.
+ */
+ public void contextChanged(Context context) {
+ mContext = context;
+ LayoutTab.resetDimensionConstants(context);
+ }
+
+ /**
+ * Called when the size of the viewport has changed.
+ * @param availableViewport The actual viewport this {@link Layout} should be rendering to.
+ * @param visibleViewport The visible viewport that represents the area on the screen
+ * this {@link Layout} gets to draw to (potentially takes into
+ * account top controls).
+ * @param screenViewport The viewport of the screen.
+ * @param heightMinusTopControls The height the {@link Layout} gets excluding the height of the
+ * top controls. TODO(dtrainor): Look at getting rid of this.
+ * @param orientation The new orientation. Valid values are defined by
+ * {@link Orientation}.
+ */
+ public final void sizeChanged(RectF availableViewport, RectF visibleViewport,
+ RectF screenViewport, float heightMinusTopControls, int orientation) {
+ // 1. Pull out this Layout's specific width and height properties based on the available
+ // viewport.
+ float width = availableViewport.width();
+ float height = availableViewport.height();
+
+ // 2. Check if any Layout-specific properties have changed.
+ boolean layoutPropertiesChanged = mWidth != width
+ || mHeight != height
+ || mHeightMinusTopControls != heightMinusTopControls
+ || mCurrentOrientation != orientation;
+
+ // 3. Update the internal sizing properties.
+ mWidth = width;
+ mHeight = height;
+ mHeightMinusTopControls = heightMinusTopControls;
+ mCurrentOrientation = orientation;
+
+ // 4. Notify the actual Layout if necessary.
+ if (layoutPropertiesChanged) {
+ notifySizeChanged(width, height, orientation);
+ }
+
+ // 5. TODO(dtrainor): Notify the overlay objects.
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).onSizeChanged(width, height, visibleViewport.top);
+ }
+ }
+
+ /**
+ * Notifies when the size or the orientation of the view has actually changed.
+ *
+ * @param width The new width in dp.
+ * @param height The new height in dp.
+ * @param orientation The new orientation.
+ */
+ protected void notifySizeChanged(float width, float height, int orientation) { }
+
+ /**
+ * Notify the a title has changed.
+ *
+ * @param tabId The id of the tab that has changed.
+ * @param title The new title.
+ */
+ public void tabTitleChanged(int tabId, String title) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabTitleChanged(tabId, title);
+ }
+ }
+
+ /**
+ * Sets the managers needed to for the layout to get information from outside. The managers
+ * are tailored to be called from the GL thread.
+ *
+ * @param modelSelector The {@link TabModelSelector} to be set on the layout.
+ * @param manager The {@link TabContentManager} to get tab display content.
+ */
+ public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) {
+ if (mTabContentManager != null) mTabContentManager.removeThumbnailChangeListener(this);
+ mTabModelSelector = modelSelector;
+ mTabContentManager = manager;
+ if (mTabContentManager != null) mTabContentManager.addThumbnailChangeListener(this);
+ }
+
+ /**
+ * @return Information about the sizing requirements of this layout.
+ */
+ public int getSizingFlags() {
+ return SizingFlags.HELPER_NO_FULLSCREEN_SUPPORT;
+ }
+
+ /**
+ * Informs this cache of the relevant {@link Tab} {@code id}s that will be used in the
+ * near future.
+ */
+ protected void updateCacheVisibleIds(List<Integer> priority) {
+ if (mTabContentManager != null) mTabContentManager.updateVisibleIds(priority);
+ }
+
+ /**
+ * To be called when the layout is starting a transition out of the view mode.
+ * @param nextTabId The id of the next tab.
+ * @param hintAtTabSelection Whether or not the new tab selection should be broadcast as a hint
+ * potentially before this {@link Layout} is done hiding and the
+ * selection occurs.
+ */
+ public void startHiding(int nextTabId, boolean hintAtTabSelection) {
+ getLayoutTab(nextTabId);
+ mUpdateHost.startHiding(nextTabId, hintAtTabSelection);
+ mIsHiding = true;
+ mNextTabId = nextTabId;
+ }
+
+ /**
+ * @return True is the layout is in the process of hiding itself.
+ */
+ public boolean isHiding() {
+ return mIsHiding;
+ }
+
+ /**
+ * @return The incognito state of the layout.
+ */
+ public boolean isIncognito() {
+ return mTabModelSelector.isIncognitoSelected();
+ }
+
+ /**
+ * To be called when the transition into the layout is done.
+ */
+ public void doneShowing() {
+ mUpdateHost.doneShowing();
+ }
+
+ /**
+ * To be called when the transition out of the view mode is done.
+ * This is currently called by the renderer when all the animation are done while hiding.
+ */
+ public void doneHiding() {
+ mIsHiding = false;
+ if (mNextTabId != Tab.INVALID_TAB_ID) {
+ TabModel model = mTabModelSelector.getModelForTabId(mNextTabId);
+ if (model != null) {
+ TabModelUtils.setIndex(model, TabModelUtils.getTabIndexById(model, mNextTabId));
+ }
+ mNextTabId = Tab.INVALID_TAB_ID;
+ }
+ mUpdateHost.doneHiding();
+ }
+
+ /**
+ * Called when a tab is getting selected. Typically when exiting the overview mode.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the selected tab.
+ */
+ public void onTabSelecting(long time, int tabId) {
+ startHiding(tabId, true);
+ }
+
+ /**
+ * Initialize the layout to be shown.
+ * @param time The current time of the app in ms.
+ * @param animate Whether to play an entry animation.
+ */
+ public void show(long time, boolean animate) {
+ mIsHiding = false;
+ mNextTabId = Tab.INVALID_TAB_ID;
+ }
+
+ /**
+ * Hands the layout an Android view to attach it's views to.
+ * @param container The Android View to attach the layout's views to.
+ */
+ public void attachViews(ViewGroup container) { }
+
+ /**
+ * Signal to the Layout to detach it's views from the container.
+ */
+ public void detachViews() { }
+
+ /**
+ * Called when the swipe animation get initiated. It gives a chance to initialize everything.
+ * @param time The current time of the app in ms.
+ * @param direction The direction the swipe is in.
+ * @param x The horizontal coordinate the swipe started at in dp.
+ * @param y The vertical coordinate the swipe started at in dp.
+ */
+ public void swipeStarted(long time, ScrollDirection direction, float x, float y) { }
+
+ /**
+ * Updates a swipe gesture.
+ * @param time The current time of the app in ms.
+ * @param x The horizontal coordinate the swipe is currently at in dp.
+ * @param y The vertical coordinate the swipe is currently at in dp.
+ * @param dx The horizontal delta since the last update in dp.
+ * @param dy The vertical delta since the last update in dp.
+ * @param tx The horizontal difference between the start and the current position in dp.
+ * @param ty The vertical difference between the start and the current position in dp.
+ */
+ public void swipeUpdated(long time, float x, float y, float dx, float dy, float tx, float ty) {
+ }
+
+ /**
+ * Called when the swipe ends; most likely on finger up event. It gives a chance to start
+ * an ending animation to exit the mode gracefully.
+ * @param time The current time of the app in ms.
+ */
+ public void swipeFinished(long time) { }
+
+ /**
+ * Called when the user has cancelled a swipe; most likely if they have dragged their finger
+ * back to the starting position. Some handlers will throw swipeFinished() instead.
+ * @param time The current time of the app in ms.
+ */
+ public void swipeCancelled(long time) { }
+
+ /**
+ * Fling from a swipe gesture.
+ * @param time The current time of the app in ms.
+ * @param x The horizontal coordinate the swipe is currently at in dp.
+ * @param y The vertical coordinate the swipe is currently at in dp.
+ * @param tx The horizontal difference between the start and the current position in dp.
+ * @param ty The vertical difference between the start and the current position in dp.
+ * @param vx The horizontal velocity of the fling.
+ * @param vy The vertical velocity of the fling.
+ */
+ public void swipeFlingOccurred(long time, float x, float y, float tx, float ty, float vx,
+ float vy) { }
+
+ /**
+ * Forces the current animation to finish and broadcasts the proper event.
+ */
+ protected void forceAnimationToFinish() {
+ if (mLayoutAnimations != null) {
+ mLayoutAnimations.updateAndFinish();
+ mLayoutAnimations = null;
+ onAnimationFinished();
+ }
+ }
+
+ /**
+ * @return The width of the drawing area.
+ */
+ public float getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * @return The height of the drawing area.
+ */
+ public float getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * @return The height of the drawing area minus the top controls.
+ */
+ public float getHeightMinusTopControls() {
+ return mHeightMinusTopControls;
+ }
+
+ /**
+ * @see Orientation
+ * @return The orientation of the screen (portrait or landscape). Values are defined by
+ * {@link Orientation}.
+ */
+ public int getOrientation() {
+ return mCurrentOrientation;
+ }
+
+ /**
+ * @return Whether or not any tabs in this layer use the toolbar resource.
+ */
+ public boolean usesToolbarLayer() {
+ if (mLayoutTabs == null) return false;
+ for (int i = 0; i < mLayoutTabs.length; i++) {
+ if (mLayoutTabs[i].showToolbar()) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether or not the native Contextual Search layout is showing. Layouts supporting
+ * Contextual Search should override this method and return "true", indicating that
+ * the layout has already been swapped from an Android View to a native cc::Layer.
+ * @return Whether or not the Contextual Search bar is showing.
+ */
+ public boolean isContextualSearchLayoutShowing() {
+ return false;
+ }
+
+ /**
+ * @return The {@link ContextualSearchPanel} or "null" if there is none for this layout.
+ */
+ public ContextualSearchPanel getContextualSearchPanel() {
+ return null;
+ }
+
+ /**
+ * @param currentOffset The current top controls offset in dp.
+ * @return {@link Float#NaN} if no offset should be used, or a value in dp if the top controls
+ * offset should be overridden.
+ */
+ public float getTopControlsOffset(float currentOffset) {
+ return Float.NaN;
+ }
+
+ /**
+ * Initializes a {@link LayoutTab} with data from the {@link LayoutUpdateHost}. This function
+ * eventually needs to be called but may be overridden to manage the posting traffic.
+ *
+ * @param layoutTab The {@link LayoutTab} To initialize from a
+ * {@link Tab} on the UI thread.
+ * @return Whether the asynchronous initialization of the {@link LayoutTab} has really
+ * been posted.
+ */
+ protected boolean initLayoutTabFromHost(LayoutTab layoutTab) {
+ if (layoutTab.isInitFromHostNeeded()) {
+ mUpdateHost.initLayoutTabFromHost(layoutTab.getId());
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Called on touch drag event.
+ * @param time The current time of the app in ms.
+ * @param x The y coordinate of the end of the drag event.
+ * @param y The y coordinate of the end of the drag event.
+ * @param deltaX The number of pixels dragged in the x direction.
+ * @param deltaY The number of pixels dragged in the y direction.
+ */
+ public void drag(long time, float x, float y, float deltaX, float deltaY) { }
+
+ /**
+ * Called on touch fling event. This is called before the onUpOrCancel event.
+ *
+ * @param time The current time of the app in ms.
+ * @param x The y coordinate of the start of the fling event.
+ * @param y The y coordinate of the start of the fling event.
+ * @param velocityX The amount of velocity in the x direction.
+ * @param velocityY The amount of velocity in the y direction.
+ */
+ public void fling(long time, float x, float y, float velocityX, float velocityY) { }
+
+ /**
+ * Called on onDown event.
+ *
+ * @param time The time stamp in millisecond of the event.
+ * @param x The x position of the event.
+ * @param y The y position of the event.
+ */
+ public void onDown(long time, float x, float y) { }
+
+ /**
+ * Called on long press touch event.
+ * @param time The current time of the app in ms.
+ * @param x The x coordinate of the position of the press event.
+ * @param y The y coordinate of the position of the press event.
+ */
+ public void onLongPress(long time, float x, float y) { }
+
+ /**
+ * Called on click. This is called before the onUpOrCancel event.
+ * @param time The current time of the app in ms.
+ * @param x The x coordinate of the position of the click.
+ * @param y The y coordinate of the position of the click.
+ */
+ public void click(long time, float x, float y) { }
+
+ /**
+ * Called on up or cancel touch events. This is called after the click and fling event if any.
+ * @param time The current time of the app in ms.
+ */
+ public void onUpOrCancel(long time) { }
+
+ /**
+ * Called when at least 2 touch events are detected.
+ * @param time The current time of the app in ms.
+ * @param x0 The x coordinate of the first touch event.
+ * @param y0 The y coordinate of the first touch event.
+ * @param x1 The x coordinate of the second touch event.
+ * @param y1 The y coordinate of the second touch event.
+ * @param firstEvent The pinch is the first of a sequence of pinch events.
+ */
+ public void onPinch(long time, float x0, float y0, float x1, float y1, boolean firstEvent) { }
+
+ /**
+ * Called by the LayoutManager when an animation should be killed.
+ */
+ public void unstallImmediately() { }
+
+ /**
+ * Called by the LayoutManager when an animation should be killed.
+ * @param tabId The tab that the kill signal is associated with
+ */
+ public void unstallImmediately(int tabId) { }
+
+ /**
+ * Called by the LayoutManager when they system back button is pressed.
+ * @return Whether or not the layout consumed the event.
+ */
+ public boolean onBackPressed() {
+ return false;
+ }
+
+ /**
+ * Called when a tab get selected. Typically when a tab get closed and the new current tab get
+ * selected.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the selected tab.
+ * @param prevId The id of the previously selected tab.
+ * @param incognito Whether or not the affected model was incognito.
+ */
+ public void onTabSelected(long time, int tabId, int prevId, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabSelected(time, incognito, tabId, prevId);
+ }
+ }
+
+ /**
+ * Called when a tab is about to be closed. When called, the closing tab will still
+ * be part of the model.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the tab being closed
+ */
+ public void onTabClosing(long time, int tabId) {
+ }
+
+ /**
+ * Called when a tab is being closed. When called, the closing tab will not
+ * be part of the model.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the tab being closed.
+ * @param nextTabId The id if the tab that is being switched to.
+ * @param incognito Whether or not the affected model was incognito.
+ */
+ public void onTabClosed(long time, int tabId, int nextTabId, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabClosed(time, incognito, tabId);
+ }
+ }
+
+ /**
+ * Called when all the tabs in the current stack need to be closed.
+ * When called, the tabs will still be part of the model.
+ * @param time The current time of the app in ms.
+ * @param incognito True if this the incognito tab model should close all tabs, false otherwise.
+ */
+ public void onTabsAllClosing(long time, boolean incognito) {
+ }
+
+ /**
+ * Called before a tab is created from the top left button.
+ *
+ * @param sourceTabId The id of the source tab.
+ */
+ public void onTabCreating(int sourceTabId) { }
+
+ /**
+ * Called when a tab is created from the top left button.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the newly created tab.
+ * @param tabIndex The index of the newly created tab.
+ * @param sourceTabId The id of the source tab.
+ * @param newIsIncognito Whether the new tab is incognito.
+ * @param background Whether the tab is created in the background.
+ * @param originX The X screen coordinate in dp of the last touch down event that spawned
+ * this tab.
+ * @param originY The Y screen coordinate in dp of the last touch down event that spawned
+ * this tab.
+ */
+ public void onTabCreated(long time, int tabId, int tabIndex, int sourceTabId,
+ boolean newIsIncognito, boolean background, float originX, float originY) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabCreated(time, newIsIncognito, tabId, sourceTabId, !background);
+ }
+ }
+
+ /**
+ * Called when the current tabModel switched (e.g. standard -> incognito).
+ *
+ * @param incognito True if the new model is incognito.
+ */
+ public void onTabModelSwitched(boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabModelSwitched(incognito);
+ }
+ }
+
+ /**
+ * Called when a tab has been moved in the tabModel.
+ * @param time The current time of the app in ms.
+ * @param tabId The id of the Tab.
+ * @param oldIndex The old index of the tab in the tabModel.
+ * @param newIndex The new index of the tab in the tabModel.
+ * @param incognito True if the tab is incognito.
+ */
+ public void onTabMoved(long time, int tabId, int oldIndex, int newIndex, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabMoved(time, incognito, tabId, oldIndex, newIndex);
+ }
+ }
+
+ /**
+ * Called when a tab has started loading.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito.
+ */
+ public void onTabPageLoadStarted(int id, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabPageLoadStarted(id, incognito);
+ }
+ }
+
+ /**
+ * Called when a tab has finished loading.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito.
+ */
+ public void onTabPageLoadFinished(int id, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabPageLoadFinished(id, incognito);
+ }
+ }
+
+ /**
+ * Called when a tab has started loading resources.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito.
+ */
+ public void onTabLoadStarted(int id, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabLoadStarted(id, incognito);
+ }
+ }
+
+ /**
+ * Called when a tab has stopped loading resources.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito.
+ */
+ public void onTabLoadFinished(int id, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabLoadFinished(id, incognito);
+ }
+ }
+
+ /**
+ * Called when a tab close has been undone and the tab has been restored.
+ * @param time The current time of the app in ms.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito
+ */
+ public void onTabClosureCancelled(long time, int id, boolean incognito) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ mSceneOverlays.get(i).tabClosureCancelled(time, incognito, id);
+ }
+ }
+
+ /**
+ * Called when a tab is finally closed if the action was previously undoable.
+ * @param time The current time of the app in ms.
+ * @param id The id of the Tab.
+ * @param incognito True if the tab is incognito
+ */
+ public void onTabClosureCommitted(long time, int id, boolean incognito) { }
+
+ @Override
+ public void onThumbnailChange(int id) {
+ requestUpdate();
+ }
+
+ /**
+ * Steps the animation forward and updates all the animated values.
+ * @param time The current time of the app in ms.
+ * @param jumpToEnd Whether to finish the animation.
+ * @return Whether the animation was finished.
+ */
+ protected boolean onUpdateAnimation(long time, boolean jumpToEnd) {
+ boolean finished = true;
+ if (mLayoutAnimations != null) {
+ if (jumpToEnd) {
+ finished = mLayoutAnimations.finished();
+ mLayoutAnimations.updateAndFinish();
+ } else {
+ finished = mLayoutAnimations.update(time);
+ }
+
+ if (finished || jumpToEnd) {
+ mLayoutAnimations = null;
+ onAnimationFinished();
+ }
+ requestUpdate();
+ }
+ return finished;
+ }
+
+ /**
+ * @return Whether or not there is an animation currently being driven by this {@link Layout}.
+ */
+ @VisibleForTesting
+ public boolean isLayoutAnimating() {
+ return mLayoutAnimations != null && !mLayoutAnimations.finished();
+ }
+
+ /**
+ * Called when layout-specific actions are needed after the animation finishes.
+ */
+ protected void onAnimationStarted() {
+ }
+
+ /**
+ * Called when layout-specific actions are needed after the animation finishes.
+ */
+ protected void onAnimationFinished() {
+ }
+
+ /**
+ * Creates an {@link org.chromium.chrome.browser.compositor.layouts.ChromeAnimation
+ * .AnimatableAnimation} and adds it to the animation.
+ * Automatically sets the start value at the beginning of the animation.
+ */
+ protected <T extends Enum<?>> void addToAnimation(Animatable<T> object, T prop, float start,
+ float end, long duration, long startTime) {
+ addToAnimation(object, prop, start, end, duration, startTime, false);
+ }
+
+ /**
+ * Creates an {@link org.chromium.chrome.browser.compositor.layouts.ChromeAnimation
+ * .AnimatableAnimation} and it to the animation. Uses a deceleration interpolator by default.
+ */
+ protected <T extends Enum<?>> void addToAnimation(Animatable<T> object, T prop, float start,
+ float end, long duration, long startTime, boolean setStartValueAfterDelay) {
+ addToAnimation(object, prop, start, end, duration, startTime, setStartValueAfterDelay,
+ ChromeAnimation.getDecelerateInterpolator());
+ }
+
+ /**
+ * Creates an {@link org.chromium.chrome.browser.compositor.layouts.ChromeAnimation
+ * .AnimatableAnimation} and
+ * adds it to the animation.
+ *
+ * @param <T> The Enum type of the Property being used
+ * @param object The object being animated
+ * @param prop The property being animated
+ * @param start The starting value of the animation
+ * @param end The ending value of the animation
+ * @param duration The duration of the animation in ms
+ * @param startTime The start time in ms
+ * @param setStartValueAfterDelay See {@link Animation#setStartValueAfterStartDelay(boolean)}
+ * @param interpolator The interpolator to use for the animation
+ */
+ protected <T extends Enum<?>> void addToAnimation(Animatable<T> object, T prop, float start,
+ float end, long duration, long startTime, boolean setStartValueAfterDelay,
+ Interpolator interpolator) {
+ ChromeAnimation.Animation<Animatable<?>> component = createAnimation(object, prop, start,
+ end, duration, startTime, setStartValueAfterDelay, interpolator);
+ addToAnimation(component);
+ }
+
+ /**
+ * Appends an Animation to the current animation set and starts it immediately. If the set is
+ * already finished or doesn't exist, the animation set is also started.
+ */
+ protected void addToAnimation(ChromeAnimation.Animation<Animatable<?>> component) {
+ if (mLayoutAnimations == null || mLayoutAnimations.finished()) {
+ onAnimationStarted();
+ mLayoutAnimations = new ChromeAnimation<Animatable<?>>();
+ mLayoutAnimations.start();
+ }
+ component.start();
+ mLayoutAnimations.add(component);
+ requestUpdate();
+ }
+
+ /**
+ * @return whether or not the animation is currently being run.
+ */
+ protected boolean animationIsRunning() {
+ return mLayoutAnimations != null && !mLayoutAnimations.finished();
+ }
+
+ /**
+ * Cancels any animation for the given object and property.
+ * @param object The object being animated.
+ * @param prop The property to search for.
+ */
+ protected <T extends Enum<?>> void cancelAnimation(Animatable<T> object, T prop) {
+ if (mLayoutAnimations != null) {
+ mLayoutAnimations.cancel(object, prop);
+ }
+ }
+
+ /**
+ * @return The {@link LayoutTab}s to be drawn.
+ */
+ @SuppressFBWarnings("EI_EXPOSE_REP")
+ public LayoutTab[] getLayoutTabsToRender() {
+ return mLayoutTabs;
+ }
+
+ /**
+ * @param id The id of the {@link LayoutTab} to search for.
+ * @return A {@link LayoutTab} represented by a {@link Tab} with an id of {@code id}.
+ */
+ public LayoutTab getLayoutTab(int id) {
+ if (mLayoutTabs != null) {
+ for (int i = 0; i < mLayoutTabs.length; i++) {
+ if (mLayoutTabs[i].getId() == id) return mLayoutTabs[i];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @return Whether the layout is handling the model updates when a tab is closing.
+ */
+ public boolean handlesTabClosing() {
+ return false;
+ }
+
+ /**
+ * @return Whether the layout is handling the model updates when a tab is creating.
+ */
+ public boolean handlesTabCreating() {
+ return false;
+ }
+
+ /**
+ * @return Whether the layout is handling the model updates when closing all the tabs.
+ */
+ public boolean handlesCloseAll() {
+ return false;
+ }
+
+ /**
+ * @return True if the content decoration layer should be shown.
+ */
+ public boolean shouldDisplayContentOverlay() {
+ return false;
+ }
+
+ /**
+ * @return True if the currently active content view is shown in the normal interactive mode.
+ */
+ public boolean isTabInteractive() {
+ return false;
+ }
+
+ /**
+ * @return The number of drawn tabs. This does not count the one culled out.
+ */
+ @VisibleForTesting
+ public int getLayoutTabsDrawnCount() {
+ return mRenderHost.getLayoutTabsDrawnCount();
+ }
+
+ /**
+ * Setting this will only take effect the next time this layout is shown. If it is currently
+ * showing the original filter will still be used.
+ * @param filter
+ */
+ public void setEventFilter(EventFilter filter) {
+ mEventFilter = filter;
+ }
+
+ /**
+ * @param e The {@link MotionEvent} to consider.
+ * @param offsets The current touch offsets that should be applied to the
+ * {@link EventFilter}s.
+ * @param isKeyboardShowing Whether or not the keyboard is showing.
+ * @return The {@link EventFilter} the {@link Layout} is listening to.
+ */
+ public EventFilter findInterceptingEventFilter(
+ MotionEvent e, Point offsets, boolean isKeyboardShowing) {
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ EventFilter eventFilter = mSceneOverlays.get(i).getEventFilter();
+ if (offsets != null) eventFilter.setCurrentMotionEventOffsets(offsets.x, offsets.y);
+ if (eventFilter.onInterceptTouchEvent(e, isKeyboardShowing)) return eventFilter;
+ }
+
+ if (mEventFilter != null) {
+ if (offsets != null) mEventFilter.setCurrentMotionEventOffsets(offsets.x, offsets.y);
+ if (mEventFilter.onInterceptTouchEvent(e, isKeyboardShowing)) return mEventFilter;
+ }
+ return null;
+ }
+
+ /**
+ * Build a {@link SceneLayer} if it hasn't already been built, and update it and return it.
+ *
+ * @param contentViewport A viewport in which to display content.
+ * @param layerTitleCache A layer title cache.
+ * @param tabContentManager A tab content manager.
+ * @param resourceManager A resource manager.
+ * @param fullscreenManager A fullscreen manager.
+ * @return A {@link SceneLayer} that represents the content for this
+ * {@link Layout}.
+ */
+ public final SceneLayer getUpdatedSceneLayer(Rect viewport,
+ Rect contentViewport, LayerTitleCache layerTitleCache,
+ TabContentManager tabContentManager, ResourceManager resourceManager,
+ ChromeFullscreenManager fullscreenManager) {
+ updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager,
+ resourceManager, fullscreenManager);
+
+ SceneLayer content = getSceneLayer();
+ for (int i = 0; i < mSceneOverlays.size(); i++) {
+ SceneOverlayLayer overlayLayer = mSceneOverlays.get(i).getUpdatedSceneOverlayTree(
+ layerTitleCache, resourceManager, fullscreenManager);
+
+ overlayLayer.setContentTree(content);
+ content = overlayLayer;
+ }
+
+ return content;
+ }
+
+ /**
+ * Get an instance of {@link SceneLayer}. Any class inheriting {@link Layout}
+ * should override this function in order for other functions to work.
+ *
+ * @return The scene layer for this {@link Layout}.
+ */
+ protected abstract SceneLayer getSceneLayer();
+
+ /**
+ * Update {@link SceneLayer} instance this layout holds. Any class inheriting {@link Layout}
+ * should override this function in order for other functions to work.
+ */
+ protected void updateSceneLayer(Rect viewport, Rect contentViewport,
+ LayerTitleCache layerTitleCache, TabContentManager tabContentManager,
+ ResourceManager resourceManager, ChromeFullscreenManager fullscreenManager) {
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698