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

Side by Side Diff: content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java

Issue 2765443004: AndroidOverlay implementation using Dialog. (Closed)
Patch Set: cl feedback, except surface_tracker refactor Created 3 years, 8 months 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 2017 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.androidoverlay;
6
7 import android.os.Handler;
8 import android.os.HandlerThread;
9 import android.support.test.filters.SmallTest;
10
11 import org.junit.Assert;
12
13 import org.chromium.base.test.util.CallbackHelper;
14 import org.chromium.base.test.util.Feature;
15 import org.chromium.content.browser.framehost.RenderFrameHostImpl;
16 import org.chromium.content_shell_apk.ContentShellTestBase;
17 import org.chromium.media.mojom.AndroidOverlayClient;
18 import org.chromium.media.mojom.AndroidOverlayConfig;
19 import org.chromium.mojo.common.mojom.UnguessableToken;
20 import org.chromium.mojo.system.MojoException;
21
22 import java.util.concurrent.ArrayBlockingQueue;
23 import java.util.concurrent.TimeUnit;
24
25 /**
26 * Tests for DialogOverlayImpl.
27 */
28 public class DialogOverlayImplTest extends ContentShellTestBase {
29 private static final String BLANK_URL = "about://blank";
30
31 // The routing token that we'll use to create overlays.
32 UnguessableToken mRoutingToken;
33
34 // overlay-ui thread.
35 HandlerThread mOverlayUiThread;
36 Handler mOverlayUiHandler;
37
38 // Runnable that will be called on the browser UI thread when an overlay is released.
39 Runnable mReleasedRunnable;
40
41 // True if we should create a secure overlay.
42 boolean mSecure;
43
44 /**
45 * AndroidOverlay client that supports waiting operations for callbacks. On e may call
46 * nextEvent() to get the next callback, waiting if needed.
47 */
48 public static class Client implements AndroidOverlayClient {
49 // AndroidOverlayClient
50 public static final int SURFACE_READY = 0;
51 public static final int DESTROYED = 1;
52 public static final int CLOSE = 2;
53 public static final int CONNECTION_ERROR = 2;
54 // AndroidOverlayProviderImpl.Callbacks
55 public static final int RELEASED = 100;
56
57 /**
58 * Records one callback event.
59 */
60 public static class Event {
61 public Event(int which) {
62 this.which = which;
63 }
64
65 public Event(int which, long surfaceKey) {
66 this.which = which;
67 this.surfaceKey = surfaceKey;
68 }
69
70 public Event(int which, MojoException exception) {
71 this.which = which;
72 }
73
74 public int which;
75 public long surfaceKey;
76 }
77
78 private ArrayBlockingQueue<Event> mPending;
79
80 public Client() {
81 mPending = new ArrayBlockingQueue<Event>(10);
82 }
83
84 @Override
85 public void onSurfaceReady(long surfaceKey) {
86 mPending.add(new Event(SURFACE_READY, surfaceKey));
87 }
88
89 @Override
90 public void onDestroyed() {
91 mPending.add(new Event(DESTROYED));
92 }
93
94 @Override
95 public void close() {
96 mPending.add(new Event(CLOSE));
97 }
98
99 @Override
100 public void onConnectionError(MojoException exception) {
101 mPending.add(new Event(CONNECTION_ERROR, exception));
102 }
103
104 // This isn't part of the overlay client. It's called by the overlay to indicate that it
105 // has been released by the client, but it's routed to us anyway. It's on the Browser UI
106 // thread, and it's convenient for us to keep track of it here.
107 public void notifyReleased() {
108 mPending.add(new Event(RELEASED));
109 }
110
111 // Wait for something to happen. We enforce a timeout, since the test h arness doesn't
112 // always seem to fail the test when it times out. Plus, it takes ~minu te for that, but
113 // none of our messages should take that long.
114 Event nextEvent() {
115 try {
116 return mPending.poll(500, TimeUnit.MILLISECONDS);
117 } catch (InterruptedException e) {
118 Assert.fail(e.toString());
119 }
120
121 // NOTREACHED
122 return null;
123 }
124
125 boolean isEmpty() {
126 return mPending.size() == 0;
127 }
128 }
129
130 private Client mClient = new Client();
131
132 @Override
133 public void setUp() throws Exception {
134 super.setUp();
135
136 startActivityWithTestUrl(BLANK_URL);
137
138 // Fetch the routing token.
139 mRoutingToken = new UIAction<UnguessableToken>() {
140 public UnguessableToken runOnUiThread() {
141 RenderFrameHostImpl host = (RenderFrameHostImpl) getWebContents( ).getMainFrame();
142 org.chromium.base.UnguessableToken routingToken =
143 host.getAndroidOverlayRoutingToken();
144 UnguessableToken mojoToken = new UnguessableToken();
145 mojoToken.high = routingToken.getHighForSerialization();
dcheng 2017/04/03 19:12:40 +tguilbert... I don't know much about the Java glu
liberato (no reviews please) 2017/04/04 17:49:29 Acknowledged.
tguilbert 2017/04/05 01:03:55 There doesn't seem to be an obvious way to do this
146 mojoToken.low = routingToken.getLowForSerialization();
147 return mojoToken;
148 }
149 }.run();
150
151 // Set up the overlay UI thread
152 mOverlayUiThread = new HandlerThread("TestOverlayUI");
153 mOverlayUiThread.start();
154 mOverlayUiHandler = new Handler(mOverlayUiThread.getLooper());
155
156 // Just delegate to |mClient| when an overlay is released.
157 mReleasedRunnable = new Runnable() {
158 @Override
159 public void run() {
160 mClient.notifyReleased();
161 }
162 };
163 }
164
165 // Handly class to compute something on the UI thread and return a value. T o use:
166 // T result = new UIAction<T> {
167 // @Override
168 // public T runOnUiThread() {
169 // // Do stuff.
170 // return (something of type T);
171 // }}.run();
172 abstract class UIAction<T> {
173 private CallbackHelper mCallbackHelper;
174 private Runnable mRunnable;
175 private T mReturnValue;
176
177 public UIAction() {
178 mCallbackHelper = new CallbackHelper();
179 mRunnable = new Runnable() {
180 @Override
181 public void run() {
182 mReturnValue = UIAction.this.runOnUiThread();
183 mCallbackHelper.notifyCalled();
184 }
185 };
186 }
187
188 // Fill this in with whatever you'd like to run on the UI thread.
189 public abstract T runOnUiThread();
190
191 // Run runOnUiThread() on the UI thread, and return the result. For con venience, we don't
192 // send along errors. We just fail.
193 public T run() {
194 try {
195 handleBlockingCallbackAction(mCallbackHelper, mRunnable);
196 } catch (Throwable t) {
197 Assert.fail(t.toString());
198 }
199 return mReturnValue;
200 }
201 }
202
203 // Create an overlay with the given parameters and return it.
204 DialogOverlayImpl createOverlay(final int x, final int y, final int width, f inal int height) {
205 return new UIAction<DialogOverlayImpl>() {
206 @Override
207 public DialogOverlayImpl runOnUiThread() {
208 AndroidOverlayConfig config = new AndroidOverlayConfig();
209 config.routingToken = mRoutingToken;
210 config.rect = new org.chromium.gfx.mojom.Rect();
211 config.rect.x = x;
212 config.rect.y = y;
213 config.rect.width = width;
214 config.rect.height = height;
215 config.secure = mSecure;
216 HandlerThread overlayUiThread = new HandlerThread("TestOverlayUI ");
217 overlayUiThread.start();
218 DialogOverlayOperations ops =
219 new DialogOverlayOperationsImpl(mOverlayUiHandler, mRele asedRunnable);
220 DialogOverlayImpl impl = new DialogOverlayImpl(mClient, config, ops);
221
222 return impl;
223 }
224 }
225 .run();
226 }
227
228 @SmallTest
229 @Feature({"AndroidOverlay"})
230 public void testCreateDestroyOverlay() {
231 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
232
233 // We should get a new overlay with a valid surface key.
234 Client.Event event = mClient.nextEvent();
235 Assert.assertEquals(Client.SURFACE_READY, event.which);
236 Assert.assertTrue(event.surfaceKey > 0);
237
238 // Close the overlay, and make sure that the provider is notified.
239 // Note that we should not get a 'destroyed' message when we close it.
240 new UIAction<Boolean>() {
241 @Override
242 public Boolean runOnUiThread() {
243 overlay.close();
244 return true;
245 }
246 }
247 .run();
248 Assert.assertEquals(Client.RELEASED, mClient.nextEvent().which);
249 }
250
251 @SmallTest
252 @Feature({"AndroidOverlay"})
253 public void testCreateOverlayFailsIfUnknownRoutingToken() {
254 // Try to create an overlay with a bad routing token.
255 mRoutingToken.high++;
256 DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
257 Assert.assertNotNull(overlay);
258
259 // We should be notified that the overlay is destroyed.
260 Client.Event event = mClient.nextEvent();
261 Assert.assertEquals(Client.DESTROYED, event.which);
262 }
263
264 @SmallTest
265 @Feature({"AndroidOverlay"})
266 public void testScheduleLayoutDoesntCrash() {
267 // Make sure that we don't get any messages due to scheduleLayout, and w e don't crash.
268 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
269
270 // Wait for the surface.
271 Assert.assertEquals(Client.SURFACE_READY, mClient.nextEvent().which);
272 final org.chromium.gfx.mojom.Rect rect = new org.chromium.gfx.mojom.Rect ();
273 rect.x = 100;
274 rect.y = 200;
275 rect.width = 100;
276 rect.height = 100;
277 new UIAction<Boolean>() {
278 @Override
279 public Boolean runOnUiThread() {
280 overlay.scheduleLayout(rect);
281 return true;
282 }
283 }
284 .run();
285
286 // No additional messages should have arrived.
287 Assert.assertTrue(mClient.isEmpty());
288 }
289
290 @SmallTest
291 @Feature({"AndroidOverlay"})
292 public void testCreateSecureSurface() {
293 // Test that creating a secure overlay creates an overlay. We can't rea lly tell if it's
294 // secure or not, until we can do a screen shot test.
295 mSecure = true;
296 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
297 Assert.assertNotNull(overlay);
298
299 // We should get a new overlay with a valid surface key.
300 Client.Event event = mClient.nextEvent();
301 Assert.assertEquals(Client.SURFACE_READY, event.which);
302 Assert.assertTrue(event.surfaceKey > 0);
303 }
304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698