Commit f2a5c5c6 authored by Shimi Zhang's avatar Shimi Zhang Committed by Commit Bot

Reland "[Android] Pass SurfaceView to HandleObserver for Chrome"

The original CL is http://crrev/c/923021, we split ClassRegister out
from that CL. This is the rest part.

Since Chrome uses SurfaceView for compositing, we will get nothing from
the ContentView passed to |SelectionPopupController| in
|HandleObserver|.

In this CL, we are passing SurfaceView to HandleObserver from
|CompositorViewHolder| through |WindowAndroid| if it's Chrome's case.

We set a flag to |SelectionPopupController| to let it know whether we
need to use SurfaceView.

Bug: 805531
Change-Id: I2c732231dd161a92d73b29be7f1ab546140eb41b
Reviewed-on: https://chromium-review.googlesource.com/953172Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarMichael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarChangwan Ryu <changwan@chromium.org>
Commit-Queue: Shimi Zhang <ctzsm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541869}
parent 33e25ec3
......@@ -398,6 +398,8 @@ public abstract class ChromeActivity extends AsyncInitializationActivity
final long begin = SystemClock.elapsedRealtime();
TraceEvent.begin("onCreate->setContentView()");
SelectionPopupController.setShouldGetReadbackViewFromWindowAndroid();
enableHardwareAcceleration();
setLowEndTheme();
int controlContainerLayoutId = getControlContainerLayoutId();
......
......@@ -5,6 +5,7 @@
package org.chromium.chrome.browser;
import android.app.Activity;
import android.view.View;
import org.chromium.chrome.browser.infobar.InfoBarIdentifier;
import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder;
......@@ -26,6 +27,16 @@ public class ChromeWindow extends ActivityWindowAndroid {
super(activity);
}
@Override
public View getReadbackView() {
assert getActivity().get() instanceof ChromeActivity;
ChromeActivity chromeActivity = (ChromeActivity) getActivity().get();
return chromeActivity.getCompositorViewHolder() == null
? null
: chromeActivity.getCompositorViewHolder().getActiveSurfaceView();
}
@Override
protected void logUMAOnRequestPermissionDenied(String permission) {
Activity activity = getActivity().get();
......
......@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.compositor;
import android.graphics.drawable.Drawable;
import android.view.Surface;
import android.view.View;
/**
* Manages Surface(s), and SurfaceView(s) when necessary, for the compositor.
......@@ -63,4 +64,9 @@ public interface CompositorSurfaceManager {
* Set the visibility of the Managed SurfaceViews.
*/
void setVisibility(int visibility);
/**
* Gets the active {@link SurfaceView}.
*/
View getActiveSurfaceView();
}
......@@ -346,6 +346,11 @@ class CompositorSurfaceManagerImpl implements SurfaceHolder.Callback2, Composito
mOpaque.surfaceView.setVisibility(visibility);
}
@Override
public View getActiveSurfaceView() {
return mOwnedByClient == null ? null : mOwnedByClient.surfaceView;
}
/**
* Return the SurfaceState for |holder|, or null if it isn't either.
*/
......
......@@ -149,6 +149,13 @@ public class CompositorView
return mResourceManager;
}
/**
* @return The active {@link SurfaceView} of this compositor.
*/
public View getActiveSurfaceView() {
return mCompositorSurfaceManager.getActiveSurfaceView();
}
/**
* Should be called for cleanup when the CompositorView instance is no longer used.
*/
......
......@@ -396,6 +396,13 @@ public class CompositorViewHolder extends FrameLayout
return mCompositorView;
}
/**
* @return The active {@link SurfaceView} of the Compositor.
*/
public View getActiveSurfaceView() {
return mCompositorView.getActiveSurfaceView();
}
private Tab getCurrentTab() {
if (mLayoutManager == null || mTabModelSelector == null) return null;
Tab currentTab = mTabModelSelector.getCurrentTab();
......
......@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ChromeStrictMode;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ClassRegister;
import org.chromium.chrome.browser.FileProviderHelper;
import org.chromium.chrome.browser.crash.LogcatExtractionRunnable;
import org.chromium.chrome.browser.download.DownloadManagerService;
......@@ -377,6 +378,7 @@ public class ChromeBrowserInitializer {
AppHooks.get().registerPolicyProviders(CombinedPolicyProvider.get());
SpeechRecognition.initialize(mApplication);
ClassRegister.get().registerContentClassFactory();
}
private void onFinishNativeInitialization() {
......
......@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.vr_shell;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntDef;
import android.view.Surface;
import android.view.View;
import org.chromium.chrome.browser.compositor.CompositorSurfaceManager;
......@@ -103,4 +104,9 @@ public class VrCompositorSurfaceManager implements CompositorSurfaceManager {
@Override
public void setVisibility(int visibility) {}
@Override
public View getActiveSurfaceView() {
return null;
}
}
......@@ -8,6 +8,7 @@ import android.view.View;
import org.chromium.base.ThreadUtils;
import org.chromium.content.browser.selection.SelectionInsertionHandleObserver;
import org.chromium.content.browser.selection.SelectionPopupControllerImpl;
/**
* A class factory for downstream injecting code to content layer.
......@@ -42,6 +43,16 @@ public class ContentClassFactory {
/**
* Creates HandleObserver object.
*/
public SelectionInsertionHandleObserver createHandleObserver(
SelectionPopupControllerImpl.ReadbackViewCallback callback) {
// Implemented by a subclass.
return null;
}
/**
* Creates HandleObserver object.
*/
// TODO(ctzsm): Remove this overload after we removed all usage of it.
public SelectionInsertionHandleObserver createHandleObserver(View view) {
// Implemented by a subclass.
return null;
......
......@@ -90,6 +90,11 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
// does not require ordering information.
private static final int MENU_ITEM_ORDER_TEXT_PROCESS_START = 100;
// A flag to determine if we should get readback view from WindowAndroid.
// The readback view could be the ContainerView, which WindowAndroid has no control on that.
// Embedders should set this properly to use the correct view for readback.
private static boolean sShouldGetReadbackViewFromWindowAndroid = false;
private static final class UserDataFactoryLazyHolder {
private static final UserDataFactory<SelectionPopupControllerImpl> INSTANCE =
SelectionPopupControllerImpl::new;
......@@ -163,6 +168,23 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
*/
private SelectionInsertionHandleObserver mHandleObserver;
/**
* An interface for getting {@link View} for readback.
*/
public interface ReadbackViewCallback {
/**
* Gets the {@link View} for readback.
*/
View getReadbackView();
}
/**
* Sets to use the readback view from {@link WindowAndroid}.
*/
public static void setShouldGetReadbackViewFromWindowAndroid() {
sShouldGetReadbackViewFromWindowAndroid = true;
}
/**
* Create {@link SelectionPopupController} instance.
* @param context Context for action mode.
......@@ -241,7 +263,7 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
mLastSelectedText = "";
mHandleObserver = ContentClassFactory.get().createHandleObserver(view);
initHandleObserver();
if (initializeNative) nativeInit(mWebContents);
......@@ -270,6 +292,7 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
destroyPastePopup();
mView = view;
initHandleObserver();
}
// ImeEventObserver
......@@ -537,6 +560,7 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
@Override
public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) {
mWindowAndroid = newWindowAndroid;
initHandleObserver();
}
// WindowEventObserver
......@@ -1292,6 +1316,16 @@ public class SelectionPopupControllerImpl extends ActionModeCallbackHelper
mHandleObserver = handleObserver;
}
private void initHandleObserver() {
mHandleObserver = ContentClassFactory.get().createHandleObserver(() -> {
if (sShouldGetReadbackViewFromWindowAndroid) {
return mWindowAndroid == null ? null : mWindowAndroid.getReadbackView();
} else {
return mView;
}
});
}
@CalledByNative
private void onShowUnhandledTapUIIfNeeded(int x, int y) {
if (x < 0 || y < 0 || mView.getWidth() < x || mView.getHeight() < y) return;
......
......@@ -32,6 +32,13 @@ public interface SelectionPopupController {
return SelectionPopupControllerImpl.fromWebContents(webContents);
}
/**
* Makes {@link SelectionPopupcontroller} to use the readback view from {@link WindowAndroid}
*/
static void setShouldGetReadbackViewFromWindowAndroid() {
SelectionPopupControllerImpl.setShouldGetReadbackViewFromWindowAndroid();
}
/**
* Set {@link ActionMode.Callback} used by {@link SelectionPopupController}.
* @param callback ActionMode.Callback instance.
......
......@@ -138,6 +138,13 @@ public class WindowAndroid {
void onContextMenuClosed();
}
/**
* Gets the view for readback.
*/
public View getReadbackView() {
return null;
}
private final ObserverList<OnCloseContextMenuListener> mContextMenuCloseListeners =
new ObserverList<>();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment