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