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

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.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/compositor/layouts/StaticLayout.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
new file mode 100644
index 0000000000000000000000000000000000000000..e19647598e58e8a8fbf866c3cd6f38e74b6a14dd
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/StaticLayout.java
@@ -0,0 +1,336 @@
+// 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 android.content.Context;
+import android.graphics.Rect;
+import android.os.Handler;
+
+import com.google.android.apps.chrome.R;
+
+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.components.LayoutTab;
+import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
+import org.chromium.chrome.browser.compositor.scene_layer.ReaderModeSceneLayer;
+import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayer;
+import org.chromium.chrome.browser.dom_distiller.ReaderModePanel;
+import org.chromium.chrome.browser.dom_distiller.ReaderModePanel.ReaderModePanelLayoutDelegate;
+import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
+import org.chromium.chrome.browser.tab.ChromeTab;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelBase;
+import org.chromium.ui.resources.ResourceManager;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+
+/**
+ * A {@link Layout} that shows a single tab at full screen. This tab is chosen based on the
+ * {@link #tabSelecting(long, int)} call, and is used to show a thumbnail of a {@link ChromeTab}
+ * until that {@link ChromeTab} is ready to be shown.
+ */
+public class StaticLayout extends ContextualSearchSupportedLayout {
+ public static final String TAG = "StaticLayout";
+
+ private static final int HIDE_TIMEOUT_MS = 2000;
+ private static final int HIDE_DURATION_MS = 500;
+
+ private boolean mHandlesTabLifecycles;
+
+ private class UnstallRunnable implements Runnable {
+ @Override
+ public void run() {
+ mUnstalling = false;
+ if (mLayoutTabs == null || mLayoutTabs.length == 0) return;
+ addToAnimation(mLayoutTabs[0], LayoutTab.Property.SATURATION,
+ mLayoutTabs[0].getSaturation(), 1.0f, HIDE_DURATION_MS, 0);
+ addToAnimation(mLayoutTabs[0], LayoutTab.Property.STATIC_TO_VIEW_BLEND,
+ mLayoutTabs[0].getStaticToViewBlend(), 0.0f, HIDE_DURATION_MS, 0);
+ mLayoutTabs[0].setShouldStall(false);
+ }
+ }
+
+ private final UnstallRunnable mUnstallRunnable;
+ private final Handler mHandler;
+ private boolean mUnstalling;
+ private StaticTabSceneLayer mSceneLayer;
+
+ // TODO(aruslan): look into moving this to an overlay/it's own layout.
+ private ReaderModeSceneLayer mReaderModeSceneLayer;
+ private ReaderModePanel mReaderModePanel;
+
+ /**
+ * Creates an instance of the {@link StaticLayout}.
+ * @param context The current Android's context.
+ * @param updateHost The {@link LayoutUpdateHost} view for this layout.
+ * @param renderHost The {@link LayoutRenderHost} view for this layout.
+ * @param eventFilter The {@link EventFilter} that is needed for this view.
+ */
+ public StaticLayout(Context context, LayoutUpdateHost updateHost, LayoutRenderHost renderHost,
+ EventFilter eventFilter, ContextualSearchPanel panel) {
+ super(context, updateHost, renderHost, eventFilter, panel);
+
+ mHandler = new Handler();
+ mUnstallRunnable = new UnstallRunnable();
+ mUnstalling = false;
+ mSceneLayer = new StaticTabSceneLayer(R.id.control_container);
+
+ float dpToPx = context.getResources().getDisplayMetrics().density;
+ mReaderModeSceneLayer = new ReaderModeSceneLayer(dpToPx);
+ }
+
+ /**
+ * @param handlesTabLifecycles Whether or not this {@link Layout} should handle tab closing and
+ * creating events.
+ */
+ public void setLayoutHandlesTabLifecycles(boolean handlesTabLifecycles) {
+ mHandlesTabLifecycles = handlesTabLifecycles;
+ }
+
+ @Override
+ public int getSizingFlags() {
+ return SizingFlags.HELPER_SUPPORTS_FULLSCREEN;
+ }
+
+ @Override
+ public float getTopControlsOffset(float currentOffsetDp) {
+ if (mReaderModePanel == null) return super.getTopControlsOffset(currentOffsetDp);
+ return mReaderModePanel.getTopControlsOffset(currentOffsetDp);
+ }
+
+ /**
+ * Initialize the layout to be shown.
+ * @param time The current time of the app in ms.
+ * @param animate Whether to play an entry animation.
+ */
+ @Override
+ public void show(long time, boolean animate) {
+ super.show(time, animate);
+
+ mLayoutTabs = null;
+ setStaticTab(mTabModelSelector.getCurrentTabId());
+ }
+
+ @Override
+ protected void updateLayout(long time, long dt) {
+ super.updateLayout(time, dt);
+ if (mLayoutTabs != null && mLayoutTabs.length > 0) mLayoutTabs[0].updateSnap(dt);
+ }
+
+ @Override
+ public void onTabSelected(long time, int id, int prevId, boolean incognito) {
+ setStaticTab(id);
+ super.onTabSelected(time, id, prevId, incognito);
+ }
+
+ @Override
+ public void onTabSelecting(long time, int id) {
+ setStaticTab(id);
+ super.onTabSelecting(time, id);
+ }
+
+ @Override
+ public void onTabCreated(long time, int tabId, int tabIndex, int sourceTabId,
+ boolean newIsIncognito, boolean background, float originX, float originY) {
+ super.onTabCreated(
+ time, tabId, tabIndex, sourceTabId, newIsIncognito, background, originX, originY);
+ if (!background) setStaticTab(tabId);
+ }
+
+ @Override
+ public void onTabModelSwitched(boolean incognito) {
+ super.onTabModelSwitched(incognito);
+ setStaticTab(mTabModelSelector.getCurrentTabId());
+ }
+
+ @Override
+ public void onTabPageLoadFinished(int id, boolean incognito) {
+ super.onTabPageLoadFinished(id, incognito);
+ unstallImmediately(id);
+ }
+
+ private void setPreHideState() {
+ mHandler.removeCallbacks(mUnstallRunnable);
+ mLayoutTabs[0].setStaticToViewBlend(1.0f);
+ mLayoutTabs[0].setSaturation(0.0f);
+ mUnstalling = true;
+ }
+
+ private void setPostHideState() {
+ mHandler.removeCallbacks(mUnstallRunnable);
+ mLayoutTabs[0].setStaticToViewBlend(0.0f);
+ mLayoutTabs[0].setSaturation(1.0f);
+ mUnstalling = false;
+ }
+
+ private void setStaticTab(final int id) {
+ if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].getId() == id) {
+ if (!mLayoutTabs[0].shouldStall()) setPostHideState();
+ return;
+ }
+ TabModel model = mTabModelSelector.getModelForTabId(id);
+ if (model == null) return;
+ updateCacheVisibleIds(new LinkedList<Integer>(Arrays.asList(id)));
+ if (mLayoutTabs == null || mLayoutTabs.length != 1) mLayoutTabs = new LayoutTab[1];
+ mLayoutTabs[0] = createLayoutTab(id, model.isIncognito(), NO_CLOSE_BUTTON, NO_TITLE);
+ mLayoutTabs[0].setDrawDecoration(false);
+ if (mLayoutTabs[0].shouldStall()) {
+ setPreHideState();
+ mHandler.postDelayed(mUnstallRunnable, HIDE_TIMEOUT_MS);
+ } else {
+ setPostHideState();
+ }
+ mReaderModePanel = ReaderModePanel.getReaderModePanel(mTabModelSelector.getTabById(id));
+ if (mReaderModePanel != null) {
+ mReaderModePanel.setLayoutDelegate(new ReaderModePanelLayoutDelegate() {
+ @Override
+ public void requestUpdate() {
+ StaticLayout.this.requestUpdate();
+ }
+
+ @Override
+ public void setLayoutTabBrightness(float v) {
+ if (mLayoutTabs != null && mLayoutTabs.length > 0
+ && mLayoutTabs[0].getId() == id) {
+ mLayoutTabs[0].setBrightness(v);
+ }
+ }
+
+ @Override
+ public void setLayoutTabY(float v) {
+ if (mLayoutTabs != null && mLayoutTabs.length > 0
+ && mLayoutTabs[0].getId() == id) {
+ mLayoutTabs[0].setY(v);
+ }
+ }
+ });
+ final boolean isToolbarVisible = getHeight() == getHeightMinusTopControls();
+ final float dpToPx = getContext().getResources().getDisplayMetrics().density;
+ mReaderModePanel.onSizeChanged(getWidth(), getHeight(), isToolbarVisible, dpToPx);
+ }
+ requestRender();
+ }
+
+ /**
+ * @return Currently active reader mode panel, or null.
+ */
+ public ReaderModePanel getReaderModePanel() {
+ return mReaderModePanel;
+ }
+
+ @Override
+ public void unstallImmediately(int tabId) {
+ if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].getId() == tabId) {
+ unstallImmediately();
+ }
+ }
+
+ @Override
+ public void unstallImmediately() {
+ if (mLayoutTabs != null && mLayoutTabs.length > 0 && mLayoutTabs[0].shouldStall()
+ && mUnstalling) {
+ mHandler.removeCallbacks(mUnstallRunnable);
+ mUnstallRunnable.run();
+ }
+ }
+
+ @Override
+ public boolean handlesTabCreating() {
+ return mHandlesTabLifecycles;
+ }
+
+ @Override
+ public boolean handlesTabClosing() {
+ return mHandlesTabLifecycles;
+ }
+
+ @Override
+ public boolean handlesCloseAll() {
+ return mHandlesTabLifecycles;
+ }
+
+ @Override
+ public boolean shouldDisplayContentOverlay() {
+ return true;
+ }
+
+ @Override
+ public boolean isTabInteractive() {
+ return mLayoutTabs != null && mLayoutTabs.length > 0;
+ }
+
+ @Override
+ protected SceneLayer getSceneLayer() {
+ return mSceneLayer;
+ }
+
+ @Override
+ protected void notifySizeChanged(float width, float height, int orientation) {
+ super.notifySizeChanged(width, height, orientation);
+ if (mReaderModePanel == null) return;
+
+ final boolean isToolbarVisible = getHeight() == getHeightMinusTopControls();
+ final float dpToPx = getContext().getResources().getDisplayMetrics().density;
+ mReaderModePanel.onSizeChanged(width, height, isToolbarVisible, dpToPx);
+ }
+
+ @Override
+ protected boolean onUpdateAnimation(long time, boolean jumpToEnd) {
+ boolean parentAnimating = super.onUpdateAnimation(time, jumpToEnd);
+ boolean panelAnimating = mReaderModePanel != null
+ ? mReaderModePanel.onUpdateAnimation(time, jumpToEnd)
+ : false;
+ return panelAnimating || parentAnimating;
+ }
+
+ @Override
+ protected void updateSceneLayer(Rect viewport, Rect contentViewport,
+ LayerTitleCache layerTitleCache, TabContentManager tabContentManager,
+ ResourceManager resourceManager, ChromeFullscreenManager fullscreenManager) {
+ super.updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager,
+ resourceManager, fullscreenManager);
+ assert mSceneLayer != null;
+
+ final LayoutTab[] tabs = getLayoutTabsToRender();
+ if (tabs == null || tabs.length != 1 || tabs[0].getId() == Tab.INVALID_TAB_ID) {
+ return;
+ }
+ LayoutTab layoutTab = tabs[0];
+ final float dpToPx = getContext().getResources().getDisplayMetrics().density;
+
+ mReaderModeSceneLayer.update(mReaderModePanel, resourceManager);
+
+ mSceneLayer.update(dpToPx, contentViewport, layerTitleCache, tabContentManager,
+ fullscreenManager, layoutTab);
+
+ // TODO(pedrosimonetti): Coordinate w/ dtrainor@ to improve integration with TreeProvider.
+ SceneLayer overlayLayer = null;
+ if (mSearchPanel.isShowing()) {
+ overlayLayer = super.getSceneLayer();
+ } else if (mReaderModePanel != null && mReaderModePanel.isShowing()) {
+ overlayLayer = mReaderModeSceneLayer;
+ }
+ mSceneLayer.setContentSceneLayer(overlayLayer);
+
+ // TODO(dtrainor): Find the best way to properly track this metric for cold starts.
+ // We should probably erase the thumbnail when we select a tab that we need to restore.
+ if (tabContentManager != null
+ && tabContentManager.hasFullCachedThumbnail(layoutTab.getId())) {
+ TabModelBase.logPerceivedTabSwitchLatencyMetric();
+ }
+ }
+
+ @Override
+ public void destroy() {
+ if (mSceneLayer != null) {
+ mSceneLayer.destroy();
+ mSceneLayer = null;
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698