OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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.media; |
| 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.base.annotations.JNINamespace; |
| 15 |
| 16 /** |
| 17 * Singleton class to create and manage DialogSurface. Normally, you won't need |
| 18 * to access this directly. Instead, see the native wrappers in |
| 19 * dialog_surface_manager.cc for usage. |
| 20 * |
| 21 * The wrappers do roughly the following on the gpu side: |
| 22 * - Create an IDialogSurfaceCallback. For native, DialogSurfaceCallback hides |
| 23 * the threading issues and provides the java peer. |
| 24 * - Get an IDialogSurfaceManager from the browser via ChildProcessCallback . |
| 25 * - dialogSurface = IDialogSurfaceManager.createSurface(callback) |
| 26 * This calls into the browser, and returns an IDialogSurface IBinder. |
| 27 * - Wrap the DialogSurface in a DialogSurfaceWrapper. This provides the JNI |
| 28 * bindings for native. |
| 29 * - Expect callbacks on the callback to let you know when the underlying |
| 30 * android surface state changes. |
| 31 * - Use the surface. |
| 32 * - Call IDialogSurface::release() to destroy the surface when done. |
| 33 */ |
| 34 @JNINamespace("media") |
| 35 public class DialogSurfaceManager extends IDialogSurfaceManager.Stub { |
| 36 private static final String TAG = "cr_media"; |
| 37 private static DialogSurfaceManager sInstance; |
| 38 |
| 39 private final Context mContext; |
| 40 |
| 41 // We maintain a thread with a Looper for the DialogSurfaces to use, |
| 42 // since Dialog requires one. We don't want this to be the native thread |
| 43 // that's used to create them, because it probably also has a native message |
| 44 // loop. Including a looper on it is not a good idea. |
| 45 private HandlerThread mThread; |
| 46 private Handler mHandler; |
| 47 private IDialogSurfaceActivityMapper mMapper; |
| 48 |
| 49 // Number of DialogSurfaces that have been created but not released. |
| 50 private int mNumSurfaces; |
| 51 |
| 52 // Maximum number of concurrent surfaces we allow. |
| 53 private static final int sMaxSurfaces = 1; |
| 54 |
| 55 private DialogSurfaceManager(IDialogSurfaceActivityMapper mapper) { |
| 56 mContext = ContextUtils.getApplicationContext(); |
| 57 mMapper = mapper; |
| 58 mNumSurfaces = 0; |
| 59 } |
| 60 |
| 61 public static IBinder instance(IDialogSurfaceActivityMapper mapper) { |
| 62 if (sInstance == null) sInstance = new DialogSurfaceManager(mapper); |
| 63 |
| 64 return sInstance.asBinder(); |
| 65 } |
| 66 |
| 67 @Override |
| 68 @CalledByNative |
| 69 public IDialogSurface createSurface(int rendererPid, int renderFrameId, |
| 70 IDialogSurfaceCallback callback, int x, int y, int width, int height
) { |
| 71 // Limit the number of concurrent surfaces. |
| 72 if (mNumSurfaces >= sMaxSurfaces) return null; |
| 73 |
| 74 ensureThread(); |
| 75 |
| 76 mNumSurfaces++; |
| 77 |
| 78 return new DialogSurface(rendererPid, renderFrameId, mContext, this, mHa
ndler, callback, x, |
| 79 y, width, height); |
| 80 } |
| 81 |
| 82 /** |
| 83 * Called by DialogSurfaces when they no longer need the thread. |
| 84 */ |
| 85 public void notifyReleased(DialogSurface dialogSurface) { |
| 86 if (mNumSurfaces > 0) mNumSurfaces--; |
| 87 |
| 88 // We don't stop the looper thread here, else android can get mad when |
| 89 // it tries to send a message from the dialog on this thread. |
| 90 // DialogSurface might have to notify us separately to tell us |
| 91 // when it's done with the thread, if we don't want to wait until then |
| 92 // to start creating a new SV. |
| 93 // Instead, we just avoid shutting down the thread at all for now. |
| 94 /* |
| 95 if (mNumSurfaces == 0) { |
| 96 mThread.quitSafely(); |
| 97 mThread = null; |
| 98 mHandler = null; |
| 99 } |
| 100 */ |
| 101 } |
| 102 |
| 103 /** |
| 104 * Make sure that mThread and mHandler are ready for use. |
| 105 */ |
| 106 private void ensureThread() { |
| 107 // Called on main thread only. |
| 108 if (mThread != null) return; |
| 109 |
| 110 mThread = new HandlerThread("DialogSurfaceThread"); |
| 111 mThread.start(); |
| 112 mHandler = new Handler(mThread.getLooper()); |
| 113 } |
| 114 |
| 115 /** |
| 116 * Return the activity mapper. |
| 117 */ |
| 118 public IDialogSurfaceActivityMapper getMapper() { |
| 119 return mMapper; |
| 120 } |
| 121 } |
OLD | NEW |