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 DialogSurfaceControllers. Normally, | |
18 * you won't need to access this directly. Instead, see the native wrappers | |
19 * in 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 * - controller = IDialogSurfaceManager.createSurface(callback) | |
26 * This calls into the browser, and returns an IDialogController IBinder. | |
27 * - Wrap the controller in a DialogSurfaceControllerWrapper. This provides | |
28 * the JNI 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 IDialogSurfaceController::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 DialogSurfaceControllers to us e, | |
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 | |
48 // Number of SurfaceControllers that have been created but not released. | |
49 private int mNumSurfaces; | |
50 | |
51 // Maximum number of concurrent surfaces we allow. | |
52 private static int sMaxSurfaces = 1; | |
watk
2016/06/10 21:46:38
final
liberato (no reviews please)
2016/06/10 22:50:05
Done.
| |
53 | |
54 private DialogSurfaceManager() { | |
55 mContext = ContextUtils.getApplicationContext(); | |
56 mNumSurfaces = 0; | |
57 } | |
58 | |
59 public static IBinder instance() { | |
60 if (sInstance == null) sInstance = new DialogSurfaceManager(); | |
61 | |
62 return sInstance.asBinder(); | |
63 } | |
64 | |
65 @Override | |
66 @CalledByNative | |
67 public IDialogSurfaceController createSurface( | |
68 IDialogSurfaceCallback callback, int x, int y, int width, int height ) { | |
69 // Limit the number of concurrent surfaces. | |
70 if (mNumSurfaces >= sMaxSurfaces) return null; | |
71 | |
72 ensureThread(); | |
73 | |
74 mNumSurfaces++; | |
75 return new DialogSurfaceController(mContext, this, mHandler, callback, x , y, width, height); | |
76 } | |
77 | |
78 /** | |
79 * Called by controllers when they no longer need the thread. | |
80 */ | |
81 public void notifyReleased(DialogSurfaceController controller) { | |
82 if (mNumSurfaces > 0) mNumSurfaces--; | |
83 | |
84 // We don't stop the looper thread here, else android can get mad when | |
85 // it tries to send a message from the dialog on this thread. | |
86 // DialogSurfaceController might have to notify us separately to tell us | |
87 // when it's done with the thread, if we don't want to wait until then | |
88 // to start creating a new SV. | |
89 // Instead, we just avoid shutting down the thread at all for now. | |
90 /* | |
91 if (mNumSurfaces == 0) { | |
92 mThread.quitSafely(); | |
93 mThread = null; | |
94 mHandler = null; | |
95 } | |
96 */ | |
97 } | |
98 | |
99 /** | |
100 * Make sure that mThread and mHandler are ready for use. | |
101 */ | |
102 private void ensureThread() { | |
103 // Called on main thread only. | |
104 if (mThread != null) return; | |
105 | |
106 mThread = new HandlerThread("DialogSurfaceThread"); | |
107 mThread.start(); | |
108 mHandler = new Handler(mThread.getLooper()); | |
109 } | |
110 } | |
OLD | NEW |