Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.content.browser.androidoverlay; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.os.Handler; | |
| 9 import android.os.HandlerThread; | |
| 10 import android.os.IBinder; | |
| 11 | |
| 12 import org.chromium.base.ContextUtils; | |
| 13 import org.chromium.base.annotations.CalledByNative; | |
| 14 import org.chromium.media.IAndroidOverlay; | |
| 15 import org.chromium.media.IAndroidOverlayCallback; | |
| 16 import org.chromium.media.IAndroidOverlayProvider; | |
| 17 | |
| 18 /** | |
| 19 * Singleton class to create and manage AndroidOverlay. Normally, you won't nee d | |
| 20 * to access this directly. Instead, see the native wrappers in | |
| 21 * dialog_surface_manager.cc for usage. | |
| 22 * | |
| 23 * The wrappers do roughly the following on the gpu side: | |
| 24 * - Create an IAndroidOverlayCallback. For native, AndroidOverlayCallback hid es | |
| 25 * the threading issues and provides the java peer. | |
| 26 * - Get an IAndroidOverlayManager from the browser via ChildProcessCallback . | |
| 27 * - dialogSurface = IAndroidOverlayManager.createOverlay(callback) | |
| 28 * This calls into the browser, and returns an IAndroidOverlay IBinder. | |
| 29 * - Wrap the AndroidOverlay in a AndroidOverlayWrapper. This provides the JNI | |
| 30 * bindings for native. | |
| 31 * - Expect callbacks on the callback to let you know when the underlying | |
| 32 * android surface state changes. | |
| 33 * - Use the surface. | |
| 34 * - Call IAndroidOverlay::release() to destroy the surface when done. | |
| 35 */ | |
| 36 public class AndroidOverlayProviderImpl extends IAndroidOverlayProvider.Stub { | |
| 37 private static final String TAG = "AOProviderImpl"; | |
| 38 private static AndroidOverlayProviderImpl sInstance; | |
| 39 private static final Object sLock = new Object(); | |
| 40 | |
| 41 private final Context mContext; | |
| 42 | |
| 43 // We maintain a thread with a Looper for the AndroidOverlays to use, | |
| 44 // since Dialog requires one. We don't want this to be the native thread | |
| 45 // that's used to create them, because it probably also has a native message | |
| 46 // loop. Including a looper on it is not a good idea. We don't want to use | |
| 47 // the UI thread, since it will process synchronous callbacks from Android. | |
| 48 private final Object mLock = new Object(); | |
| 49 private HandlerThread mThread; | |
| 50 private Handler mHandler; | |
| 51 | |
| 52 // Number of AndroidOverlays that have been created but not released. | |
| 53 private int mNumOverlays; | |
| 54 | |
| 55 // Maximum number of concurrent surfaces we allow. | |
| 56 private static final int MAX_SURFACES = 1; | |
| 57 | |
| 58 private AndroidOverlayProviderImpl() { | |
| 59 mContext = ContextUtils.getApplicationContext(); | |
| 60 mNumOverlays = 0; | |
| 61 } | |
| 62 | |
| 63 // Return the singleton instance, as a convenience. | |
| 64 public static IBinder getInstance() { | |
| 65 synchronized (sLock) { | |
| 66 if (sInstance == null) sInstance = new AndroidOverlayProviderImpl(); | |
| 67 | |
| 68 return sInstance.asBinder(); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 @Override | |
| 73 @CalledByNative | |
|
boliu
2017/02/08 00:01:58
not needed, this doesn't generate jni headers
| |
| 74 public IAndroidOverlay createOverlay(int rendererPid, int renderFrameId, | |
| 75 IAndroidOverlayCallback callback, int x, int y, int width, int heigh t) { | |
| 76 // Note that we may be called on any random binder thread, so lock. | |
| 77 synchronized (mLock) { | |
| 78 // Limit the number of concurrent surfaces. | |
| 79 if (mNumOverlays >= MAX_SURFACES) return null; | |
| 80 | |
| 81 startThreadIfNeededLocked(); | |
| 82 | |
| 83 mNumOverlays++; | |
| 84 } | |
| 85 | |
| 86 return new DialogAndroidOverlay(rendererPid, renderFrameId, mContext, th is, mHandler, | |
| 87 callback, x, y, width, height); | |
| 88 } | |
| 89 | |
| 90 /** | |
| 91 * Called by AndroidOverlays when they no longer need the thread. | |
| 92 * Called on some random thread. | |
| 93 */ | |
| 94 public void notifyReleased() { | |
| 95 synchronized (mLock) { | |
| 96 assert mNumOverlays > 0; | |
| 97 mNumOverlays--; | |
| 98 | |
| 99 // We don't stop the looper thread here, else android can get mad wh en | |
| 100 // it tries to send a message from the dialog on this thread. | |
| 101 // AndroidOverlay might have to notify us separately to tell us | |
| 102 // when it's done with the thread, if we don't want to wait until th en | |
| 103 // to start creating a new SV. | |
| 104 // Instead, we just avoid shutting down the thread at all for now. | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 /** | |
| 109 * Make sure that mThread and mHandler are ready for use. Do nothing if | |
| 110 * they already are. | |
| 111 */ | |
| 112 private void startThreadIfNeededLocked() { | |
| 113 // Called with mLock held only. | |
|
boliu
2017/02/08 00:01:58
synhronized blocks are re-entrant safe, so rather
| |
| 114 if (mThread != null) return; | |
| 115 | |
| 116 mThread = new HandlerThread("AndroidOverlayThread"); | |
| 117 mThread.start(); | |
| 118 mHandler = new Handler(mThread.getLooper()); | |
| 119 } | |
| 120 } | |
| OLD | NEW |