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

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java

Issue 1206673003: Merge java_staging/src into java/src. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 6 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/CompositorViewHolder.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
deleted file mode 100644
index ef454af67f3c07c6ca6e4338cc7fda6e9600f334..0000000000000000000000000000000000000000
--- a/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/CompositorViewHolder.java
+++ /dev/null
@@ -1,1113 +0,0 @@
-// 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;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
-import android.support.v4.widget.ExploreByTouchHelper;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.MotionEvent;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.FrameLayout;
-
-import org.chromium.base.SysUtils;
-import org.chromium.base.TraceEvent;
-import org.chromium.base.annotations.SuppressFBWarnings;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.EmptyTabObserver;
-import org.chromium.chrome.browser.Tab;
-import org.chromium.chrome.browser.TabObserver;
-import org.chromium.chrome.browser.compositor.Invalidator.Client;
-import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
-import org.chromium.chrome.browser.compositor.layouts.LayoutManagerHost;
-import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
-import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
-import org.chromium.chrome.browser.compositor.layouts.content.ContentOffsetProvider;
-import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
-import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
-import org.chromium.chrome.browser.device.DeviceClassManager;
-import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
-import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener;
-import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
-import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.widget.ControlContainer;
-import org.chromium.content.browser.ContentReadbackHandler;
-import org.chromium.content.browser.ContentViewCore;
-import org.chromium.content.browser.SPenSupport;
-import org.chromium.ui.UiUtils;
-import org.chromium.ui.base.DeviceFormFactor;
-import org.chromium.ui.base.WindowAndroid;
-import org.chromium.ui.resources.ResourceManager;
-import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
-import org.chromium.ui.resources.dynamics.ViewResourceAdapter;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class holds a {@link CompositorView}. This level of indirection is needed to benefit from
- * the {@link android.view.ViewGroup#onInterceptTouchEvent(android.view.MotionEvent)} capability on
- * available on {@link android.view.ViewGroup}s.
- * This class also holds the {@link LayoutManager} responsible to describe the items to be
- * drawn by the UI compositor on the native side.
- */
-public class CompositorViewHolder extends FrameLayout
- implements LayoutManagerHost, LayoutRenderHost, Invalidator.Host, FullscreenListener {
- private static List<View> sCachedViewList = new ArrayList<View>();
- private static List<ContentViewCore> sCachedCVCList = new ArrayList<ContentViewCore>();
-
- private boolean mIsKeyboardShowing = false;
-
- private final Invalidator mInvalidator = new Invalidator();
- private LayoutManager mLayoutManager;
- private LayerTitleCache mLayerTitleCache;
- private CompositorView mCompositorView;
-
- private boolean mContentOverlayVisiblity = true;
-
- private int mPendingSwapBuffersCount;
-
- private final ArrayList<Invalidator.Client> mPendingInvalidations =
- new ArrayList<Invalidator.Client>();
- private boolean mSkipInvalidation = false;
-
- private boolean mSkipNextToolbarTextureUpdate = false;
-
- /**
- * A task to be performed after a resize event.
- */
- private Runnable mPostHideKeyboardTask;
-
- private TabModelSelector mTabModelSelector;
- private ChromeFullscreenManager mFullscreenManager;
- private View mAccessibilityView;
- private CompositorAccessibilityProvider mNodeProvider;
- private boolean mFullscreenTouchEvent = false;
- private float mLastContentOffset = 0;
- private float mLastVisibleContentOffset = 0;
-
- /** The toolbar control container. **/
- private ControlContainer mControlContainer;
-
- /** The currently visible Tab. */
- private Tab mTabVisible;
-
- /** The currently attached View. */
- private View mView;
-
- private TabObserver mTabObserver;
- private boolean mEnableCompositorTabStrip;
-
- // Cache objects that should not be created frequently.
- private final Rect mCacheViewport = new Rect();
- private final Rect mCacheVisibleViewport = new Rect();
-
- // If we've drawn at least one frame.
- private boolean mHasDrawnOnce = false;
-
- /**
- * This view is created on demand to display debugging information.
- */
- private static class DebugOverlay extends View {
- private final List<Pair<Rect, Integer>> mRectangles = new ArrayList<Pair<Rect, Integer>>();
- private final Paint mPaint = new Paint();
- private boolean mFirstPush = true;
-
- /**
- * @param context The current Android's context.
- */
- public DebugOverlay(Context context) {
- super(context);
- }
-
- /**
- * Pushes a rectangle to be drawn on the screen on top of everything.
- *
- * @param rect The rectangle to be drawn on screen
- * @param color The color of the rectangle
- */
- public void pushRect(Rect rect, int color) {
- if (mFirstPush) {
- mRectangles.clear();
- mFirstPush = false;
- }
- mRectangles.add(new Pair<Rect, Integer>(rect, color));
- invalidate();
- }
-
- @SuppressFBWarnings("NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD")
- @Override
- protected void onDraw(Canvas canvas) {
- for (int i = 0; i < mRectangles.size(); i++) {
- mPaint.setColor(mRectangles.get(i).second);
- canvas.drawRect(mRectangles.get(i).first, mPaint);
- }
- mFirstPush = true;
- }
- }
-
- private DebugOverlay mDebugOverlay;
-
- private View mUrlBar;
-
- /**
- * Creates a {@link CompositorView}.
- * @param c The Context to create this {@link CompositorView} in.
- */
- public CompositorViewHolder(Context c) {
- super(c);
-
- internalInit();
- }
-
- /**
- * Creates a {@link CompositorView}.
- * @param c The Context to create this {@link CompositorView} in.
- * @param attrs The AttributeSet used to create this {@link CompositorView}.
- */
- public CompositorViewHolder(Context c, AttributeSet attrs) {
- super(c, attrs);
-
- internalInit();
- }
-
- private void internalInit() {
- mTabObserver = new EmptyTabObserver() {
- @Override
- public void onContentChanged(Tab tab) {
- CompositorViewHolder.this.onContentChanged();
- }
-
- @Override
- public void onOverlayContentViewCoreAdded(Tab tab, ContentViewCore content) {
- initializeContentViewCore(content);
- setSizeOfUnattachedView(content.getContainerView());
- }
- };
-
- mEnableCompositorTabStrip = DeviceFormFactor.isTablet(getContext());
-
- addOnLayoutChangeListener(new OnLayoutChangeListener() {
- @Override
- public void onLayoutChange(View v, int left, int top, int right, int bottom,
- int oldLeft, int oldTop, int oldRight, int oldBottom) {
- propagateViewportToLayouts(right - left, bottom - top);
-
- // If there's an event that needs to occur after the keyboard is hidden, post
- // it as a delayed event. Otherwise this happens in the midst of the
- // ContentView's relayout, which causes the ContentView to relayout on top of the
- // stack view. The 30ms is arbitrary, hoping to let the view get one repaint
- // in so the full page is shown.
- if (mPostHideKeyboardTask != null) {
- new Handler().postDelayed(mPostHideKeyboardTask, 30);
- mPostHideKeyboardTask = null;
- }
- }
- });
-
- mCompositorView = new CompositorView(getContext(), this);
- addView(mCompositorView,
- new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
- }
-
- /**
- * @param layoutManager The {@link LayoutManager} instance that will be driving what
- * shows in this {@link CompositorViewHolder}.
- */
- public void setLayoutManager(LayoutManager layoutManager) {
- mLayoutManager = layoutManager;
- propagateViewportToLayouts(getWidth(), getHeight());
- }
-
- /**
- * @param view The root view of the hierarchy.
- */
- public void setRootView(View view) {
- mCompositorView.setRootView(view);
- }
-
- /**
- * @param controlContainer The ControlContainer.
- */
- public void setControlContainer(ControlContainer controlContainer) {
- DynamicResourceLoader loader = mCompositorView.getResourceManager() != null
- ? mCompositorView.getResourceManager().getDynamicResourceLoader()
- : null;
- if (loader != null && mControlContainer != null) {
- loader.unregisterResource(R.id.control_container);
- loader.unregisterResource(R.id.progress);
- }
- mControlContainer = controlContainer;
- if (loader != null && mControlContainer != null) {
- loader.registerResource(
- R.id.control_container, mControlContainer.getToolbarResourceAdapter());
-
- ViewResourceAdapter progressAdapter = mControlContainer.getProgressResourceAdapter();
- if (progressAdapter != null) {
- loader.registerResource(R.id.progress, progressAdapter);
- }
- }
- }
-
- /**
- * @return The CompositorView.
- */
- public SurfaceHolder.Callback2 getSurfaceHolderCallback2() {
- return mCompositorView;
- }
-
- /**
- * Reset command line flags. This gets called after the native library finishes
- * loading.
- */
- public void resetFlags() {
- mCompositorView.resetFlags();
- }
-
- /**
- * Should be called for cleanup when the CompositorView instance is no longer used.
- */
- public void shutDown() {
- setTab(null);
- if (mLayerTitleCache != null) mLayerTitleCache.shutDown();
- mCompositorView.shutDown();
- }
-
- /**
- * This is called when the native library are ready.
- */
- public void onNativeLibraryReady(
- WindowAndroid windowAndroid, TabContentManager tabContentManager) {
- assert mLayerTitleCache == null : "Should be called once";
-
- if (DeviceClassManager.enableLayerDecorationCache()) {
- mLayerTitleCache = new LayerTitleCache(getContext());
- }
-
- mCompositorView.initNativeCompositor(
- SysUtils.isLowEndDevice(), windowAndroid, mLayerTitleCache, tabContentManager);
-
- if (mLayerTitleCache != null) {
- mLayerTitleCache.setResourceManager(getResourceManager());
- }
-
- if (mControlContainer != null) {
- mCompositorView.getResourceManager().getDynamicResourceLoader().registerResource(
- R.id.control_container, mControlContainer.getToolbarResourceAdapter());
-
- ViewResourceAdapter progressAdapter = mControlContainer.getProgressResourceAdapter();
- if (progressAdapter != null) {
- mCompositorView.getResourceManager().getDynamicResourceLoader().registerResource(
- R.id.progress, progressAdapter);
- }
- }
- }
-
- @Override
- public ResourceManager getResourceManager() {
- return mCompositorView.getResourceManager();
- }
-
- public ContentOffsetProvider getContentOffsetProvider() {
- return mCompositorView;
- }
-
- /**
- * @return The content readback handler.
- */
- public ContentReadbackHandler getContentReadbackHandler() {
- if (mCompositorView == null) return null;
- return mCompositorView.getContentReadbackHandler();
- }
-
- /**
- * @return The {@link DynamicResourceLoader} for registering resources.
- */
- public DynamicResourceLoader getDynamicResourceLoader() {
- return mCompositorView.getResourceManager().getDynamicResourceLoader();
- }
-
- /**
- * @return The {@link Invalidator} instance that is driven by this {@link CompositorViewHolder}.
- */
- public Invalidator getInvalidator() {
- return mInvalidator;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent e) {
- super.onInterceptTouchEvent(e);
-
- if (mLayoutManager == null) return false;
-
- mFullscreenTouchEvent = false;
- if (mFullscreenManager != null && mFullscreenManager.onInterceptMotionEvent(e)
- && !mEnableCompositorTabStrip) {
- // Don't eat the event if the new tab strip is enabled.
- mFullscreenTouchEvent = true;
- return true;
- }
-
- setContentViewMotionEventOffsets(e, false);
- return mLayoutManager.onInterceptTouchEvent(e, mIsKeyboardShowing);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent e) {
- if (mFullscreenManager != null) mFullscreenManager.onMotionEvent(e);
- if (mFullscreenTouchEvent) return true;
- boolean consumed = mLayoutManager != null && mLayoutManager.onTouchEvent(e);
- setContentViewMotionEventOffsets(e, true);
- return consumed;
- }
-
- @Override
- public boolean onInterceptHoverEvent(MotionEvent e) {
- setContentViewMotionEventOffsets(e, true);
- return super.onInterceptHoverEvent(e);
- }
-
- @Override
- public boolean dispatchHoverEvent(MotionEvent e) {
- if (mNodeProvider != null) {
- if (mNodeProvider.dispatchHoverEvent(e)) {
- return true;
- }
- }
- return super.dispatchHoverEvent(e);
- }
-
- /**
- * @return The {@link LayoutManager} associated with this view.
- */
- public LayoutManager getLayoutManager() {
- return mLayoutManager;
- }
-
- /**
- * @return The SurfaceView used by the Compositor.
- */
- public SurfaceView getSurfaceView() {
- return mCompositorView;
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- if (mLayoutManager == null) return;
-
- sCachedViewList.clear();
- mLayoutManager.getActiveLayout().getAllViews(sCachedViewList);
-
- boolean resized = false;
- for (int i = 0; i < sCachedViewList.size(); i++) {
- resized |= setSizeOfUnattachedView(sCachedViewList.get(i));
- }
- sCachedViewList.clear();
-
- if (resized) requestRender();
- }
-
- @Override
- public void onPhysicalBackingSizeChanged(int width, int height) {
- if (mLayoutManager == null) return;
-
- sCachedCVCList.clear();
- mLayoutManager.getActiveLayout().getAllContentViewCores(sCachedCVCList);
-
- for (int i = 0; i < sCachedCVCList.size(); i++) {
- sCachedCVCList.get(i).onPhysicalBackingSizeChanged(width, height);
- }
- sCachedCVCList.clear();
- }
-
- @Override
- public void onOverdrawBottomHeightChanged(int overdrawHeight) {
- if (mLayoutManager == null) return;
-
- sCachedCVCList.clear();
- mLayoutManager.getActiveLayout().getAllContentViewCores(sCachedCVCList);
-
- for (int i = 0; i < sCachedCVCList.size(); i++) {
- sCachedCVCList.get(i).onOverdrawBottomHeightChanged(overdrawHeight);
- }
- sCachedCVCList.clear();
-
- mSkipNextToolbarTextureUpdate = true;
- requestRender();
- }
-
- @Override
- public int getCurrentOverdrawBottomHeight() {
- if (mTabVisible != null) {
- float overdrawBottomHeight = mTabVisible.getFullscreenOverdrawBottomHeightPix();
- if (!Float.isNaN(overdrawBottomHeight)) {
- return (int) overdrawBottomHeight;
- }
- }
- return mCompositorView.getOverdrawBottomHeight();
- }
-
- /**
- * Called whenever the host activity is started.
- */
- public void onStart() {
- if (mFullscreenManager != null) {
- mLastContentOffset = mFullscreenManager.getContentOffset();
- mLastVisibleContentOffset = mFullscreenManager.getVisibleContentOffset();
- mFullscreenManager.addListener(this);
- }
- requestRender();
- }
-
- /**
- * Called whenever the host activity is stopped.
- */
- public void onStop() {
- if (mFullscreenManager != null) mFullscreenManager.removeListener(this);
- }
-
- @Override
- public void onContentOffsetChanged(float offset) {
- mLastContentOffset = offset;
- propagateViewportToLayouts(getWidth(), getHeight());
- }
-
- @Override
- public void onVisibleContentOffsetChanged(float offset) {
- mLastVisibleContentOffset = offset;
- propagateViewportToLayouts(getWidth(), getHeight());
- requestRender();
- }
-
- @Override
- public void onToggleOverlayVideoMode(boolean enabled) {
- if (mCompositorView != null) {
- mCompositorView.setOverlayVideoMode(enabled);
- }
- }
-
- private void setContentViewMotionEventOffsets(MotionEvent e, boolean canClear) {
- // TODO(dtrainor): Factor this out to LayoutDriver.
- if (e == null || mTabVisible == null) return;
-
- ContentViewCore contentViewCore = mTabVisible.getContentViewCore();
- if (contentViewCore == null) return;
-
- int actionMasked = e.getActionMasked();
-
- if (SPenSupport.isSPenSupported(getContext())) {
- actionMasked = SPenSupport.convertSPenEventAction(actionMasked);
- }
-
- if (actionMasked == MotionEvent.ACTION_DOWN
- || actionMasked == MotionEvent.ACTION_HOVER_ENTER) {
- if (mLayoutManager != null) mLayoutManager.getViewportPixel(mCacheViewport);
- contentViewCore.setCurrentMotionEventOffsets(-mCacheViewport.left, -mCacheViewport.top);
- } else if (canClear && (actionMasked == MotionEvent.ACTION_UP
- || actionMasked == MotionEvent.ACTION_CANCEL
- || actionMasked == MotionEvent.ACTION_HOVER_EXIT)) {
- contentViewCore.setCurrentMotionEventOffsets(0.f, 0.f);
- }
- }
-
- private void propagateViewportToLayouts(int contentWidth, int contentHeight) {
- int heightMinusTopControls = contentHeight - getTopControlsHeightPixels();
- mCacheViewport.set(0, (int) mLastContentOffset, contentWidth, contentHeight);
- mCacheVisibleViewport.set(0, (int) mLastVisibleContentOffset, contentWidth, contentHeight);
- // TODO(changwan): check if this can be merged with setContentMotionEventOffsets.
- if (mTabVisible != null && mTabVisible.getContentViewCore() != null) {
- mTabVisible.getContentViewCore().setSmartClipOffsets(
- -mCacheViewport.left, -mCacheViewport.top);
- }
- if (mLayoutManager != null) {
- mLayoutManager.pushNewViewport(
- mCacheViewport, mCacheVisibleViewport, heightMinusTopControls);
- }
- }
-
- /**
- * To be called once a frame before commit.
- */
- @Override
- public void onCompositorLayout() {
- TraceEvent.begin("CompositorViewHolder:layout");
- if (mLayoutManager != null) {
- mLayoutManager.onUpdate();
- mCompositorView.finalizeLayers(mLayoutManager, mSkipNextToolbarTextureUpdate);
- // TODO(changwan): Check if this hack can be removed.
- // This is a hack to draw one more frame if the screen just rotated for Nexus 10 + L.
- // See http://crbug/440469 for more.
- if (mSkipNextToolbarTextureUpdate) {
- requestRender();
- }
- }
-
- TraceEvent.end("CompositorViewHolder:layout");
- mSkipNextToolbarTextureUpdate = false;
- }
-
- @Override
- public void requestRender() {
- mCompositorView.requestRender();
- }
-
- @Override
- public void onSurfaceCreated() {
- mPendingSwapBuffersCount = 0;
- flushInvalidation();
- }
-
- @Override
- public void onSwapBuffersCompleted(int pendingSwapBuffersCount) {
- TraceEvent.instant("onSwapBuffersCompleted");
-
- // Wait until the second frame to turn off the placeholder background on
- // tablets so the tab strip has time to start drawing.
- final ViewGroup controlContainer = (ViewGroup) mControlContainer;
- if (controlContainer != null && controlContainer.getBackground() != null && mHasDrawnOnce) {
- post(new Runnable() {
- @Override
- public void run() {
- controlContainer.setBackgroundResource(0);
- }
- });
- }
-
- mHasDrawnOnce = true;
-
- mPendingSwapBuffersCount = pendingSwapBuffersCount;
-
- if (!mSkipInvalidation || pendingSwapBuffersCount == 0) flushInvalidation();
- mSkipInvalidation = !mSkipInvalidation;
- }
-
- @Override
- public void setContentOverlayVisibility(boolean show) {
- if (show != mContentOverlayVisiblity) {
- mContentOverlayVisiblity = show;
- updateContentOverlayVisibility(mContentOverlayVisiblity);
- }
- }
-
- @Override
- public LayoutRenderHost getLayoutRenderHost() {
- return this;
- }
-
- @Override
- public int getLayoutTabsDrawnCount() {
- return mCompositorView.getLastLayerCount();
- }
-
- @Override
- public void pushDebugRect(Rect rect, int color) {
- if (mDebugOverlay == null) {
- mDebugOverlay = new DebugOverlay(getContext());
- addView(mDebugOverlay);
- }
- mDebugOverlay.pushRect(rect, color);
- }
-
- @Override
- public void loadPersitentTextureDataIfNeeded() {}
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mIsKeyboardShowing = UiUtils.isKeyboardShowing(getContext(), this);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- if (changed) {
- propagateViewportToLayouts(r - l, b - t);
- }
- super.onLayout(changed, l, t, r, b);
-
- invalidateAccessibilityProvider();
- }
-
- @Override
- public void clearChildFocus(View child) {
- // Override this method so that the ViewRoot doesn't go looking for a new
- // view to take focus. It will find the URL Bar, focus it, then refocus this
- // later, causing a keyboard flicker.
- }
-
- @Override
- public ChromeFullscreenManager getFullscreenManager() {
- return mFullscreenManager;
- }
-
- /**
- * Sets a fullscreen handler.
- * @param fullscreen A fullscreen handler.
- */
- public void setFullscreenHandler(ChromeFullscreenManager fullscreen) {
- mFullscreenManager = fullscreen;
- if (mFullscreenManager != null) {
- mLastContentOffset = mFullscreenManager.getContentOffset();
- mLastVisibleContentOffset = mFullscreenManager.getVisibleContentOffset();
- mFullscreenManager.addListener(this);
- }
- propagateViewportToLayouts(getWidth(), getHeight());
- }
-
- /**
- * Note that the returned rect is reused for other calls.
- */
- @Override
- public Rect getVisibleViewport(Rect rect) {
- if (rect == null) rect = new Rect();
- rect.set(0, (int) mLastVisibleContentOffset, getWidth(), getHeight());
- return rect;
- }
-
- @Override
- public boolean areTopControlsPermanentlyHidden() {
- return mFullscreenManager != null && mFullscreenManager.areTopControlsPermanentlyHidden();
- }
-
- @Override
- public int getTopControlsHeightPixels() {
- return mFullscreenManager != null ? mFullscreenManager.getTopControlsHeight() : 0;
- }
-
- /**
- * Sets the URL bar. This is needed so that the ContentViewHolder can find out
- * whether it can claim focus.
- */
- public void setUrlBar(View urlBar) {
- mUrlBar = urlBar;
- }
-
- @Override
- protected void onAttachedToWindow() {
- mInvalidator.set(this);
- super.onAttachedToWindow();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- if (mLayoutManager != null) mLayoutManager.destroy();
- flushInvalidation();
- mInvalidator.set(null);
- super.onDetachedFromWindow();
-
- // Removes the accessibility node provider from this view.
- if (mNodeProvider != null) {
- mAccessibilityView.setAccessibilityDelegate(null);
- mNodeProvider = null;
- removeView(mAccessibilityView);
- mAccessibilityView = null;
- }
- }
-
- /**
- * @return True if the currently active content view is shown in the normal interactive mode.
- */
- public boolean isTabInteractive() {
- return mLayoutManager != null && mLayoutManager.getActiveLayout() != null
- && mLayoutManager.getActiveLayout().isTabInteractive() && mContentOverlayVisiblity
- && mView != null;
- }
-
- /**
- * Hides the the keyboard if it was opened for the ContentView.
- * @param postHideTask A task to run after the keyboard is done hiding and the view's
- * layout has been updated. If the keyboard was not shown, the task will run
- * immediately.
- */
- public void hideKeyboard(Runnable postHideTask) {
- // When this is called we actually want to hide the keyboard whatever owns it.
- // This includes hiding the keyboard, and dropping focus from the URL bar.
- // See http://crbug/236424
- // TODO(aberent) Find a better place to put this, possibly as part of a wider
- // redesign of focus control.
- if (mUrlBar != null) mUrlBar.clearFocus();
- boolean wasVisible = false;
- if (hasFocus()) {
- wasVisible = UiUtils.hideKeyboard(this);
- }
- if (wasVisible) {
- mPostHideKeyboardTask = postHideTask;
- } else {
- postHideTask.run();
- }
- }
-
- /**
- * Sets the appropriate objects this class should represent.
- * @param tabModelSelector The {@link TabModelSelector} this View should hold and
- * represent.
- * @param tabCreatorManager The {@link TabCreatorManager} for this view.
- * @param tabContentManager The {@link TabContentManager} for the tabs.
- * @param androidContentContainer The {@link ViewGroup} the {@link LayoutManager} should bind
- * Android content to.
- * @param contextualSearchManager A {@link ContextualSearchManagementDelegate} instance.
- */
- public void onFinishNativeInitialization(TabModelSelector tabModelSelector,
- TabCreatorManager tabCreatorManager, TabContentManager tabContentManager,
- ViewGroup androidContentContainer,
- ContextualSearchManagementDelegate contextualSearchManager) {
- assert mLayoutManager != null;
- mLayoutManager.init(tabModelSelector, tabCreatorManager, tabContentManager,
- androidContentContainer, contextualSearchManager,
- mCompositorView.getResourceManager().getDynamicResourceLoader());
- mTabModelSelector = tabModelSelector;
- tabModelSelector.addObserver(new EmptyTabModelSelectorObserver() {
- @Override
- public void onChange() {
- onContentChanged();
- }
-
- @Override
- public void onNewTabCreated(Tab tab) {
- initializeTab(tab);
- }
- });
-
- onContentChanged();
- }
-
- private void updateContentOverlayVisibility(boolean show) {
- if (mView == null) return;
-
- sCachedCVCList.clear();
- if (mLayoutManager != null) {
- mLayoutManager.getActiveLayout().getAllContentViewCores(sCachedCVCList);
- }
- if (show) {
- if (mView.getParent() != this) {
- // Make sure the view isn't a child of something else before we attempt to add it.
- if (mView.getParent() != null && mView.getParent() instanceof ViewGroup) {
- ((ViewGroup) mView.getParent()).removeView(mView);
- }
-
- for (int i = 0; i < sCachedCVCList.size(); i++) {
- ContentViewCore content = sCachedCVCList.get(i);
- assert content.isAlive();
- content.getContainerView().setVisibility(View.VISIBLE);
- if (mFullscreenManager != null) {
- mFullscreenManager.updateContentViewViewportSize(content);
- }
- }
-
- FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
- if (mView.getLayoutParams() instanceof MarginLayoutParams) {
- MarginLayoutParams existingLayoutParams =
- (MarginLayoutParams) mView.getLayoutParams();
- layoutParams.leftMargin = existingLayoutParams.leftMargin;
- layoutParams.rightMargin = existingLayoutParams.rightMargin;
- layoutParams.topMargin = existingLayoutParams.topMargin;
- layoutParams.bottomMargin = existingLayoutParams.bottomMargin;
- }
- addView(mView, layoutParams);
-
- setFocusable(false);
- setFocusableInTouchMode(false);
-
- // Claim focus for the new view unless the user is currently using the URL bar.
- if (mUrlBar == null || !mUrlBar.hasFocus()) mView.requestFocus();
- }
- } else {
- if (mView.getParent() == this) {
- setFocusable(true);
- setFocusableInTouchMode(true);
-
- for (int i = 0; i < sCachedCVCList.size(); i++) {
- ContentViewCore content = sCachedCVCList.get(i);
- if (content.isAlive()) content.getContainerView().setVisibility(View.INVISIBLE);
- }
-
- if (hasFocus()) {
- InputMethodManager manager = (InputMethodManager) getContext().getSystemService(
- Context.INPUT_METHOD_SERVICE);
- if (manager.isActive(this)) {
- manager.hideSoftInputFromWindow(getWindowToken(), 0, null);
- }
- }
- removeView(mView);
- }
- }
- sCachedCVCList.clear();
- }
-
- @Override
- public void onContentChanged() {
- if (mTabModelSelector == null) {
- // Not yet initialized, onContentChanged() will eventually get called by
- // setTabModelSelector.
- return;
- }
- Tab tab = mTabModelSelector.getCurrentTab();
- setTab(tab);
- }
-
- @Override
- public void onContentViewCoreAdded(ContentViewCore content) {
- // TODO(dtrainor): Look into rolling this into onContentChanged().
- initializeContentViewCore(content);
- setSizeOfUnattachedView(content.getContainerView());
- }
-
- private void setTab(Tab tab) {
- if (tab != null && tab.isFrozen()) tab.unfreezeContents();
-
- View newView = tab != null ? tab.getView() : null;
- if (mView == newView) return;
-
- // TODO(dtrainor): Look into changing this only if the views differ, but still parse the
- // ContentViewCore list even if they're the same.
- updateContentOverlayVisibility(false);
-
- if (mTabVisible != tab) {
- if (mTabVisible != null) mTabVisible.removeObserver(mTabObserver);
- if (tab != null) tab.addObserver(mTabObserver);
- }
-
- mTabVisible = tab;
- mView = newView;
-
- updateContentOverlayVisibility(mContentOverlayVisiblity);
-
- if (mTabVisible != null) initializeTab(mTabVisible);
- }
-
- /**
- * Sets the correct size for all {@link View}s on {@code tab} and sets the correct rendering
- * parameters on all {@link ContentViewCore}s on {@code tab}.
- * @param tab The {@link Tab} to initialize.
- */
- private void initializeTab(Tab tab) {
- sCachedCVCList.clear();
- if (mLayoutManager != null) {
- mLayoutManager.getActiveLayout().getAllContentViewCores(sCachedCVCList);
- }
-
- for (int i = 0; i < sCachedCVCList.size(); i++) {
- initializeContentViewCore(sCachedCVCList.get(i));
- }
- sCachedCVCList.clear();
-
- sCachedViewList.clear();
- tab.getAllViews(sCachedViewList);
-
- for (int i = 0; i < sCachedViewList.size(); i++) {
- View view = sCachedViewList.get(i);
- // Calling View#measure() and View#layout() on a View before adding it to the view
- // hierarchy seems to cause issues with compound drawables on some versions of Android.
- // We don't need to proactively size the NTP as we don't need the Android view to render
- // if it's not actually attached to the view hierarchy (http://crbug.com/462114).
- if (view == tab.getView() && tab.isNativePage()) continue;
- setSizeOfUnattachedView(view);
- }
- sCachedViewList.clear();
- }
-
- /**
- * Initializes the rendering surface parameters of {@code contentViewCore}. Note that this does
- * not size the actual {@link ContentViewCore}.
- * @param contentViewCore The {@link ContentViewCore} to initialize.
- */
- private void initializeContentViewCore(ContentViewCore contentViewCore) {
- contentViewCore.setCurrentMotionEventOffsets(0.f, 0.f);
- contentViewCore.setTopControlsHeight(
- getTopControlsHeightPixels(), contentViewCore.doTopControlsShrinkBlinkSize());
- contentViewCore.onPhysicalBackingSizeChanged(
- mCompositorView.getWidth(), mCompositorView.getHeight());
- contentViewCore.onOverdrawBottomHeightChanged(mCompositorView.getOverdrawBottomHeight());
- }
-
- /**
- * Resize {@code view} to match the size of this {@link FrameLayout}. This will only happen if
- * {@code view} is not {@code null} and if {@link View#getWindowToken()} returns {@code null}
- * (the {@link View} is not part of the view hierarchy).
- * @param view The {@link View} to resize.
- * @return Whether or not {@code view} was resized.
- */
- private boolean setSizeOfUnattachedView(View view) {
- // Need to call layout() for the following View if it is not attached to the view hierarchy.
- // Calling onSizeChanged() is dangerous because if the View has a different size than the
- // ContentViewCore it might think a future size update is a NOOP and not call
- // onSizeChanged() on the ContentViewCore.
- if (view == null || view.getWindowToken() != null) return false;
- int width = getWidth();
- int height = getHeight();
- view.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
- view.layout(0, 0, width, height);
- return true;
- }
-
- @Override
- public TitleCache getTitleCache() {
- return mLayerTitleCache;
- }
-
- @Override
- public void deferInvalidate(Client client) {
- if (mPendingSwapBuffersCount <= 0) {
- client.doInvalidate();
- } else if (!mPendingInvalidations.contains(client)) {
- mPendingInvalidations.add(client);
- }
- }
-
- private void flushInvalidation() {
- if (mPendingInvalidations.isEmpty()) return;
- TraceEvent.instant("CompositorViewHolder.flushInvalidation");
- for (int i = 0; i < mPendingInvalidations.size(); i++) {
- mPendingInvalidations.get(i).doInvalidate();
- }
- mPendingInvalidations.clear();
- }
-
- @Override
- public void invalidateAccessibilityProvider() {
- if (mNodeProvider != null) {
- mNodeProvider.invalidateRoot();
- }
- }
-
- /**
- * Called when the accessibility enabled state changes.
- * @param enabled Whether accessibility is enabled.
- */
- public void onAccessibilityStatusChanged(boolean enabled) {
- // Instantiate and install the accessibility node provider on this view if necessary.
- // This overrides any hover event listeners or accessibility delegates
- // that may have been added elsewhere.
- if (enabled && (mNodeProvider == null)) {
- mAccessibilityView = new View(getContext());
- addView(mAccessibilityView);
- mNodeProvider = new CompositorAccessibilityProvider(mAccessibilityView);
- ViewCompat.setAccessibilityDelegate(mAccessibilityView, mNodeProvider);
- }
- }
-
- /**
- * Class used to provide a virtual view hierarchy to the Accessibility
- * framework for this view and its contained items.
- * <p>
- * <strong>NOTE:</strong> This class is fully backwards compatible for
- * compilation, but will only provide touch exploration on devices running
- * Ice Cream Sandwich and above.
- * </p>
- */
- private class CompositorAccessibilityProvider extends ExploreByTouchHelper {
- private final float mDpToPx;
- List<VirtualView> mVirtualViews = new ArrayList<VirtualView>();
- private final Rect mPlaceHolderRect = new Rect(0, 0, 1, 1);
- private static final String PLACE_HOLDER_STRING = "";
- private final RectF mTouchTarget = new RectF();
- private final Rect mPixelRect = new Rect();
-
- public CompositorAccessibilityProvider(View forView) {
- super(forView);
- mDpToPx = getContext().getResources().getDisplayMetrics().density;
- }
-
- @Override
- protected int getVirtualViewAt(float x, float y) {
- if (mVirtualViews == null) return INVALID_ID;
- for (int i = 0; i < mVirtualViews.size(); i++) {
- if (mVirtualViews.get(i).checkClicked(x / mDpToPx, y / mDpToPx)) {
- return i;
- }
- }
- return INVALID_ID;
- }
-
- @Override
- protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
- if (mLayoutManager == null) return;
- mVirtualViews.clear();
- mLayoutManager.getVirtualViews(mVirtualViews);
- for (int i = 0; i < mVirtualViews.size(); i++) {
- virtualViewIds.add(i);
- }
- }
-
- @Override
- protected boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments) {
- switch (action) {
- case AccessibilityNodeInfoCompat.ACTION_CLICK:
- return true;
- }
-
- return false;
- }
-
- @Override
- protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
- if (mVirtualViews == null || mVirtualViews.size() <= virtualViewId) {
- // TODO(clholgat): Remove this work around when the Android bug is fixed.
- // crbug.com/420177
- event.setContentDescription(PLACE_HOLDER_STRING);
- return;
- }
- VirtualView view = mVirtualViews.get(virtualViewId);
-
- event.setContentDescription(view.getAccessibilityDescription());
- event.setClassName(CompositorViewHolder.class.getName());
- }
-
- @Override
- protected void onPopulateNodeForVirtualView(
- int virtualViewId, AccessibilityNodeInfoCompat node) {
- if (mVirtualViews == null || mVirtualViews.size() <= virtualViewId) {
- // TODO(clholgat): Remove this work around when the Android bug is fixed.
- // crbug.com/420177
- node.setBoundsInParent(mPlaceHolderRect);
- node.setContentDescription(PLACE_HOLDER_STRING);
- return;
- }
- VirtualView view = mVirtualViews.get(virtualViewId);
- view.getTouchTarget(mTouchTarget);
-
- node.setBoundsInParent(rectToPx(mTouchTarget));
- node.setContentDescription(view.getAccessibilityDescription());
- node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
- node.addAction(AccessibilityNodeInfoCompat.ACTION_FOCUS);
- node.addAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK);
- }
-
- private Rect rectToPx(RectF rect) {
- rect.roundOut(mPixelRect);
- mPixelRect.left = (int) (mPixelRect.left * mDpToPx);
- mPixelRect.top = (int) (mPixelRect.top * mDpToPx);
- mPixelRect.right = (int) (mPixelRect.right * mDpToPx);
- mPixelRect.bottom = (int) (mPixelRect.bottom * mDpToPx);
-
- // Don't let any zero sized rects through, they'll cause parent
- // size errors in L.
- if (mPixelRect.width() == 0) {
- mPixelRect.right = mPixelRect.left + 1;
- }
- if (mPixelRect.height() == 0) {
- mPixelRect.bottom = mPixelRect.top + 1;
- }
- return mPixelRect;
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698