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

Unified Diff: content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogAndroidOverlay.java

Issue 2178973004: DialogSurfaceManager implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 3 years, 10 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: content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogAndroidOverlay.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogAndroidOverlay.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogAndroidOverlay.java
new file mode 100644
index 0000000000000000000000000000000000000000..76a91aeb8fbe0f0013a36873a9f2cf2507a7b307
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogAndroidOverlay.java
@@ -0,0 +1,177 @@
+// Copyright 2017 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.content.browser.androidoverlay;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.IBinder;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.media.IAndroidOverlay;
+import org.chromium.media.IAndroidOverlayCallback;
+
+/**
+ * Provide access to Dialog-based Surfaces. It is unlikely that you want to
+ * use this class directly. Instead, use the native wrappers for it in
+ * dialog_surface_holder.h . If you must use these from Java, then it's likely
+ * that you should be using IAndroidOverlay instead.
+ *
+ * This class is thread-safe, since it gets calls from random binder threads and
+ * callbacks on the UI thread. It interacts with DialogAndroidOverlayCore to do the
+ * actual work of managing the AndroidOverlay. It also hides all the threading
+ * by posting messages to a single thread for DialogAndroidOverlayCore.
+ */
+@JNINamespace("content")
+class DialogAndroidOverlay extends IAndroidOverlay.Stub {
+ private static final String TAG = "DSImpl";
+
+ private final Handler mHandler;
+
+ private long mNativeHandle;
+
+ // Note that we never do any work in response to a binder call with mLock
+ // held. We always post elsewhere, which prevents reentrant calls from
+ // the client from deadlocking on mLock.
+ private final Object mLock = new Object();
+ private AndroidOverlayProviderImpl mOwner;
+ private DialogAndroidOverlayCore mDialogCore;
+
+ /**
+ * Called from a random thread.
+ * Note that (pid, frameId) might be replaced by a token.
+ * @param rendererPid pid of owning renderer process
+ * @param renderFrameId render frame ID owned by Pid
+ * @param context Context that we use.
+ * @param owner Owning manager that we'll notify on release().
+ * @param handler handler for a thread with a looper.
+ * @param callback callback object to notify about state changes.
+ * @param x initial x position in chrome compositor (not screen) coords.
+ * @param y initial y position in chrome compositor (not screen) coords.
+ * @param width initial width.
+ * @param height initial height.
+ */
+ public DialogAndroidOverlay(int rendererPid, int renderFrameId, final Context context,
+ AndroidOverlayProviderImpl owner, Handler handler,
+ final IAndroidOverlayCallback callback, final int x, final int y, final int width,
+ final int height) {
+ mOwner = owner;
+ mHandler = handler;
+
+ mDialogCore = new DialogAndroidOverlayCore();
+
+ // Runnable that |mDialogCore| will use to notify us that it has shut down. This is useful
+ // so that we know if it shuts down by itself, generally due to loss of the surface.
+ final Runnable releaseCallback = new Runnable() {
+ @Override
+ public void run() {
+ release();
+ }
+ };
+
+ // Post init to the proper thread.
+ final DialogAndroidOverlayCore dialogCore = mDialogCore;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ dialogCore.initialize(context, callback, x, y, width, height, releaseCallback);
+ }
+ };
+ mHandler.post(r);
+
+ // Register to get token updates.
+ mNativeHandle = nativeInit(rendererPid, renderFrameId);
+ }
+
+ /**
+ * Release the underlying surface, and generally clean up, in response to
+ * the client releasing the IAndroidOverlay.
+ */
+ @Override
+ public void release() {
+ synchronized (mLock) {
+ // If we've already been released, then do nothing. Remember that |mDialogCore| will
+ // call the release callback in response to us asking it to shut down. |mDialogCore|
+ // will be null in those cases. We only process the callback if it notifies us before
+ // we've asked it to shut down, e.g., if it loses the surface.
+ if (mDialogCore == null) return;
+
+ // Unregister for token callbacks.
+ if (mNativeHandle != 0) {
+ nativeShutdown(mNativeHandle);
+ mNativeHandle = 0;
+ }
+
+ // Post a release on the proper thread to |mDialogCore|. Note that it will call us back
+ // when it gets the message, which is fine.
+ final DialogAndroidOverlayCore dialogCore = mDialogCore;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ dialogCore.release();
+ }
+ };
+ mHandler.post(r);
+
+ // Notify our owner. We don't bother to wait until the post completes, since it'll get
+ // cleaned up shortly anyway.
+ mOwner.notifyReleased();
+ mOwner = null;
+
+ mDialogCore = null;
+ }
+ }
+
+ @Override
+ public void scheduleLayoutSurface(final int x, final int y, final int width, final int height) {
+ // Random thread.
+ synchronized (mLock) {
+ if (mDialogCore == null) return;
+
+ final DialogAndroidOverlayCore dialogCore = mDialogCore;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ dialogCore.layoutSurface(x, y, width, height);
+ }
+ };
+
+ mHandler.post(r);
+ }
+ }
+
+ @CalledByNative
+ public void onWindowToken(final IBinder token) {
+ synchronized (mLock) {
+ // Forward this change.
+ // Note that if we don't have a window token, then we could wait
+ // until we do, simply by skipping sending null if we haven't sent
+ // any non-null token yet. If we're transitioning between windows,
+ // that might make the client's job easier, since it wouldn't have
+ // to guess when a new token is available.
+ final DialogAndroidOverlayCore dialogCore = mDialogCore;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ dialogCore.onWindowToken(token);
+ }
+ };
+
+ mHandler.post(r);
+ }
+ }
+
+ // We're not getting any more window tokens.
+ @CalledByNative
+ public void onDismissed() {
+ release();
+ }
+
+ // Initializes native side. Will register for onWindowToken callbacks.
+ native long nativeInit(int rendererPid, int renderFrameId);
+
+ // Stops native side.
+ native void nativeShutdown(long handle);
+}

Powered by Google App Engine
This is Rietveld 408576698