Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/DialogSurfaceWindowTokenProviderImpl.java

Issue 2178973004: DialogSurfaceManager implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: removed IDialogSurfaceActivityMapper from common.aidl Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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.content.browser;
6
7 import android.app.Activity;
8 import android.os.IBinder;
9
10 import org.chromium.base.annotations.CalledByNative;
11 import org.chromium.base.annotations.JNINamespace;
12 import org.chromium.media.DialogSurfaceWindowTokenProvider;
13 import org.chromium.ui.base.WindowAndroid;
14
15 import java.util.HashMap;
16 import java.util.HashSet;
17
18 /**
19 * Implementation of DialogSurfaceWindowTokenProvider. Asks ContentViewCore to
20 * provide updates on token changes.
21 */
22 @JNINamespace("content")
23 public class DialogSurfaceWindowTokenProviderImpl
boliu 2017/01/04 23:14:39 I can see why the Manager is singleton, but I don'
liberato (no reviews please) 2017/01/11 22:17:56 most of the code is to look up WebContents given (
boliu 2017/01/12 20:24:18 You can put it in a static method or something.
liberato (no reviews please) 2017/02/03 21:28:32 per our offline discussion, this class is not in P
24 implements DialogSurfaceWindowTokenProvider, ContentViewCore.Observer {
25 private static final String TAG = "cr_DialogSurfaceWTP";
26
27 private class ClientSet extends HashSet<DialogSurfaceWindowTokenProvider.Cli ent> {}
boliu 2017/01/04 01:48:43 these classes should be static
liberato (no reviews please) 2017/01/11 22:17:56 Done.
28 private class ClientMap extends HashMap<ContentViewCore, ClientSet> {}
29 private class ReverseClientMap
30 extends HashMap<DialogSurfaceWindowTokenProvider.Client, ContentView Core> {}
31
32 // Access |mClients| and |mReverseClients| with |mClientLock| held. These
33 // let us associate clients with the ContentViewCore that they're interested
34 // in listening to.
35 private final Object mClientLock = new Object();
36 private final ClientMap mClients = new ClientMap();
37 private final ReverseClientMap mReverseClients = new ReverseClientMap();
38
39 // This may be called on any thread.
40 @Override
41 public void registerClient(
42 int rendererPid, int renderFrameId, DialogSurfaceWindowTokenProvider .Client client) {
43 nativeCallBackWithContentViewCore(rendererPid, renderFrameId, this, clie nt);
44 }
45
46 // This may be called on any thread.
47 @Override
48 public void unregisterClient(DialogSurfaceWindowTokenProvider.Client client) {
49 synchronized (mClientLock) {
50 unregisterClientLocked(client);
51 }
52 }
53
54 // Unregister |client| for updates, with |mClientLock| held. This may be
55 // called on any thread.
56 private void unregisterClientLocked(DialogSurfaceWindowTokenProvider.Client client) {
57 // If we switched threads here, then we could remove mClientLock and
58 // also unregister for callbacks with CVC.
59 // Remove client from both the forward and reverse tables.
60 ContentViewCore cvc = mReverseClients.get(client);
61 if (cvc == null) return;
62
63 mReverseClients.remove(client);
64
65 ClientSet clients = mClients.get(cvc);
66 if (clients != null) {
67 clients.remove(client);
68 if (clients.size() == 0) {
69 // We can't cvc.removeObserver(this) here, since we can be on
70 // the wrong thread. Instead, simply ignore it and skip the
71 // callbacks if needed. We could probably remove it on the
72 // next callback, which will be on the correct thread.
73 // Do not post a remove, though, since we might re-attach in
74 // the interim.
75 mClients.remove(cvc);
76 }
77 }
78 }
79
80 /**
81 * Receive a callback from native with a previously requested ContentViewCor e.
82 * This is called on the UI thread.
83 */
84 @CalledByNative
85 private void onContentViewCore(
86 DialogSurfaceWindowTokenProvider.Client client, ContentViewCore cvc) {
87 IBinder token = null;
88
89 if (cvc != null) {
90 WindowAndroid windowAndroid = cvc.getWindowAndroid();
91 if (windowAndroid != null) {
92 token = windowAndroid.getWindowToken();
93 }
94
95 // Register to get updates about window changes, so that we know
96 // when the token changes.
97 // Note that we might actually already be a client of this, if we
98 // unregistered the last client for |cvc| and then a new one came
99 // along before we got around to unregistering. That's okay. We
100 // could prevent it, but it's not worth the book-keeping right now.
101 // We're the only observer anyway.
102 cvc.addObserver(this);
103 }
104
105 client.onWindowToken(token);
106 addClient(cvc, client);
107 }
108
109 // This will be called on the UI thread.
110 @Override
111 public void onContentViewCoreDestroyed(ContentViewCore cvc) {
112 synchronized (mClientLock) {
113 onContentViewCoreDestroyedLocked(cvc);
114 }
115 }
116
117 private void onContentViewCoreDestroyedLocked(ContentViewCore cvc) {
118 ClientSet clients = mClients.get(cvc);
119 if (clients == null) return;
120
121 // Why not just send back the CVC, and have the client manager setting
122 // up callbacks? It's only a little weird, because (a) media/ can't
123 // access ContentViewCore. So, we do it here. Plus, if we ever want
124 // to move the DialogSurface implementation into the gpu process, we'll
125 // be still running in the browser anyway. So, we do it here.
126 for (DialogSurfaceWindowTokenProvider.Client client : clients) {
127 mReverseClients.remove(client);
128 // We might want to notify them that the CVC was destroyed,
129 // rather than telling them that there's simply no token.
130 client.onWindowToken(null);
131 }
132
133 mClients.remove(cvc);
134 }
135
136 // This will be called on the UI thread.
137 @Override
138 public void onAttachedToWindowAndroid(ContentViewCore cvc) {
139 Activity activity = cvc.getWindowAndroid().getActivity().get();
boliu 2017/01/04 23:14:39 call getWindowToken?
liberato (no reviews please) 2017/01/11 22:17:56 erm, good point.
140 IBinder token = null;
141 if (activity != null) {
142 token = activity.getWindow().getDecorView().getRootView().getWindowT oken();
143 }
144
145 // Don't bother to call back if there's no token anyway.
146 if (token == null) return;
147
148 synchronized (mClientLock) {
149 ClientSet clients = mClients.get(cvc);
150 if (clients == null) {
151 // We no longer have any clients, so remove this observer.
152 cvc.removeObserver(this);
153 return;
154 }
155
156 for (DialogSurfaceWindowTokenProvider.Client client : clients) {
157 client.onWindowToken(token);
158 }
159 }
160 }
161
162 // This will be called on the UI thread.
163 @Override
164 public void onDetachedFromWindowAndroid(ContentViewCore cvc) {
165 synchronized (mClientLock) {
166 ClientSet clients = mClients.get(cvc);
167 if (clients == null) {
168 // We no longer have any clients, so remove this observer.
169 cvc.removeObserver(this);
170 return;
171 }
172
173 for (DialogSurfaceWindowTokenProvider.Client client : clients) {
174 client.onWindowToken(null);
175 }
176 }
177 }
178
179 // |client| is now a client of |cvc|, so that it receives future updates
180 // about the window token for |cvc|'s activity.
181 // This will be called on the UI thread.
182 private void addClient(ContentViewCore cvc, DialogSurfaceWindowTokenProvider .Client client) {
183 synchronized (mClientLock) {
184 ClientSet clients = mClients.get(cvc);
185 if (clients == null) {
186 clients = new ClientSet();
187 mClients.put(cvc, clients);
188 }
189 clients.add(client);
190 mReverseClients.put(client, cvc);
191 }
192 }
193
194 // Look up the ContentViewCore for (rendererPid, renderFrameId), and call
195 // back onContentViewCore with it and |client|. The callback will happen
196 // on the browser UI thread.
197 private static native void nativeCallBackWithContentViewCore(int rendererPid , int renderFrameId,
198 DialogSurfaceWindowTokenProvider provider,
199 DialogSurfaceWindowTokenProvider.Client client);
200 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698