OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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.content.browser.androidoverlay; | 5 package org.chromium.content.browser.androidoverlay; |
6 | 6 |
7 import android.content.Context; | 7 import android.content.Context; |
8 import android.os.Handler; | |
9 import android.os.HandlerThread; | |
8 | 10 |
9 import org.chromium.media.mojom.AndroidOverlay; | 11 import org.chromium.media.mojom.AndroidOverlay; |
10 import org.chromium.media.mojom.AndroidOverlayClient; | 12 import org.chromium.media.mojom.AndroidOverlayClient; |
11 import org.chromium.media.mojom.AndroidOverlayConfig; | 13 import org.chromium.media.mojom.AndroidOverlayConfig; |
12 import org.chromium.media.mojom.AndroidOverlayProvider; | 14 import org.chromium.media.mojom.AndroidOverlayProvider; |
13 import org.chromium.mojo.bindings.InterfaceRequest; | 15 import org.chromium.mojo.bindings.InterfaceRequest; |
14 import org.chromium.mojo.system.MojoException; | 16 import org.chromium.mojo.system.MojoException; |
15 import org.chromium.services.service_manager.InterfaceFactory; | 17 import org.chromium.services.service_manager.InterfaceFactory; |
16 | 18 |
17 /** | 19 /** |
18 * Default impl of AndroidOverlayProvider. Creates AndroidOverlayImpls. | 20 * Default impl of AndroidOverlayProvider. Creates AndroidOverlayImpls. We're a singleton, in the |
21 * sense that all provider clients talk to the same instance in the browser. | |
19 */ | 22 */ |
20 public class AndroidOverlayProviderImpl implements AndroidOverlayProvider { | 23 public class AndroidOverlayProviderImpl implements AndroidOverlayProvider { |
21 private static final String TAG = "AndroidOverlayProvider"; | 24 private static final String TAG = "AndroidOverlayProvider"; |
22 | 25 |
26 // Maximum number of concurrent overlays that we allow. | |
27 private static final int MAX_OVERLAYS = 1; | |
28 | |
29 // We maintain a thread with a Looper for the AndroidOverlays to use, since Dialog requires one. | |
30 // We don't want this to be the native thread that's used to create them (th e browser UI thread) | |
31 // since we don't want to block that waiting for sync callbacks from Android , such as | |
32 // surfaceDestroyed. Instead, we run all AndroidOverlays on one shared over lay-ui thread. | |
33 private HandlerThread mOverlayUiThread; | |
34 private Handler mHandler; | |
35 | |
36 // Number of AndroidOverlays that have been created but not released. | |
37 private int mNumOverlays; | |
38 | |
39 // Runnable that notifies us that a client has been released. | |
40 private Runnable mNotifyReleasedRunnable = new Runnable() { | |
41 @Override | |
42 public void run() { | |
43 notifyReleased(); | |
44 } | |
45 }; | |
46 | |
23 /** | 47 /** |
24 * Create an overlay matching |config| for |client|, and bind it to |request |. Remember that | 48 * Create an overlay matching |config| for |client|, and bind it to |request |. Remember that |
25 * potentially many providers are created. | 49 * potentially many providers are created. |
26 */ | 50 */ |
51 @Override | |
27 public void createOverlay(InterfaceRequest<AndroidOverlay> request, AndroidO verlayClient client, | 52 public void createOverlay(InterfaceRequest<AndroidOverlay> request, AndroidO verlayClient client, |
28 AndroidOverlayConfig config) { | 53 AndroidOverlayConfig config) { |
29 client.onDestroyed(); | 54 // Limit the number of concurrent surfaces. |
55 if (mNumOverlays >= MAX_OVERLAYS) { | |
56 client.onDestroyed(); | |
57 return; | |
58 } | |
59 | |
60 startThreadIfNeeded(); | |
61 mNumOverlays++; | |
boliu
2017/04/22 00:22:43
add thread asserts to this file as well? eg it's n
liberato (no reviews please)
2017/04/24 22:19:41
Done.
| |
62 | |
63 DialogOverlayOperations ops = | |
64 new DialogOverlayOperationsImpl(mHandler, mNotifyReleasedRunnabl e); | |
65 | |
66 DialogOverlayImpl impl = new DialogOverlayImpl(client, config, ops); | |
67 DialogOverlayImpl.MANAGER.bind(impl, request); | |
30 } | 68 } |
31 | 69 |
70 /** | |
71 * Make sure that mOverlayUiThread and mHandler are ready for use, if needed . | |
72 */ | |
73 private void startThreadIfNeeded() { | |
74 if (mOverlayUiThread != null) return; | |
75 | |
76 mOverlayUiThread = new HandlerThread("AndroidOverlayThread"); | |
77 mOverlayUiThread.start(); | |
78 mHandler = new Handler(mOverlayUiThread.getLooper()); | |
79 } | |
80 | |
81 /** | |
82 * Called by AndroidOverlays when they no longer need the thread via |mNotif yReleasedRunnable|. | |
83 */ | |
84 private void notifyReleased() { | |
85 assert mNumOverlays > 0; | |
86 mNumOverlays--; | |
87 | |
88 // We don't stop the looper thread here, else android can get mad when i t tries to send | |
89 // a message from the dialog on this thread. AndroidOverlay might have to notify us | |
90 // separately to tell us when it's done with the thread, if we don't wan t to wait until | |
91 // then to start creating a new SV. | |
92 // Instead, we just avoid shutting down the thread at all for now. | |
93 } | |
94 | |
95 // Remember that we can't tell which client disconnected. | |
32 @Override | 96 @Override |
33 public void close() {} | 97 public void close() {} |
34 | 98 |
99 // Remember that we can't tell which client disconnected. | |
35 @Override | 100 @Override |
36 public void onConnectionError(MojoException e) {} | 101 public void onConnectionError(MojoException e) {} |
37 | 102 |
38 /** | 103 /** |
39 * Mojo factory. | 104 * Mojo factory. |
40 */ | 105 */ |
41 public static class Factory implements InterfaceFactory<AndroidOverlayProvid er> { | 106 public static class Factory implements InterfaceFactory<AndroidOverlayProvid er> { |
107 private static AndroidOverlayProviderImpl sImpl; | |
42 public Factory(Context context) {} | 108 public Factory(Context context) {} |
43 | 109 |
44 @Override | 110 @Override |
45 public AndroidOverlayProvider createImpl() { | 111 public AndroidOverlayProvider createImpl() { |
46 return new AndroidOverlayProviderImpl(); | 112 if (sImpl == null) sImpl = new AndroidOverlayProviderImpl(); |
113 return sImpl; | |
47 } | 114 } |
48 } | 115 } |
49 } | 116 } |
OLD | NEW |