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

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: removed a TODO that wouldn't work 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();
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> {
boliu 2017/04/26 00:19:08 ThreadUtils.runOnUiThreadBlockingNoException :p
liberato (no reviews please) 2017/04/26 17:26:35 shiny! Done.
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 DialogOverlayImpl impl = new DialogOverlayImpl(
219 mClient, config, mOverlayUiHandler, mReleasedRunnable);
220
221 return impl;
222 }
223 }
224 .run();
225 }
226
227 @SmallTest
228 @Feature({"AndroidOverlay"})
229 public void testCreateDestroyOverlay() {
230 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
231
232 // We should get a new overlay with a valid surface key.
233 Client.Event event = mClient.nextEvent();
234 Assert.assertEquals(Client.SURFACE_READY, event.which);
235 Assert.assertTrue(event.surfaceKey > 0);
236
237 // Close the overlay, and make sure that the provider is notified.
238 // Note that we should not get a 'destroyed' message when we close it.
239 new UIAction<Boolean>() {
240 @Override
241 public Boolean runOnUiThread() {
242 overlay.close();
243 return true;
244 }
245 }
246 .run();
247 Assert.assertEquals(Client.RELEASED, mClient.nextEvent().which);
248 }
249
250 @SmallTest
251 @Feature({"AndroidOverlay"})
252 public void testCreateOverlayFailsIfUnknownRoutingToken() {
253 // Try to create an overlay with a bad routing token.
254 mRoutingToken.high++;
255 DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
256 Assert.assertNotNull(overlay);
257
258 // We should be notified that the overlay is destroyed.
259 Client.Event event = mClient.nextEvent();
260 Assert.assertEquals(Client.DESTROYED, event.which);
261 }
262
263 @SmallTest
264 @Feature({"AndroidOverlay"})
265 public void testScheduleLayoutDoesntCrash() {
266 // Make sure that we don't get any messages due to scheduleLayout, and w e don't crash.
267 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
268
269 // Wait for the surface.
270 Assert.assertEquals(Client.SURFACE_READY, mClient.nextEvent().which);
271 final org.chromium.gfx.mojom.Rect rect = new org.chromium.gfx.mojom.Rect ();
272 rect.x = 100;
273 rect.y = 200;
274 rect.width = 100;
275 rect.height = 100;
276 new UIAction<Boolean>() {
277 @Override
278 public Boolean runOnUiThread() {
279 overlay.scheduleLayout(rect);
280 return true;
281 }
282 }
283 .run();
284
285 // No additional messages should have arrived.
286 Assert.assertTrue(mClient.isEmpty());
287 }
288
289 @SmallTest
290 @Feature({"AndroidOverlay"})
291 public void testCreateSecureSurface() {
292 // Test that creating a secure overlay creates an overlay. We can't rea lly tell if it's
293 // secure or not, until we can do a screen shot test.
294 mSecure = true;
295 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
296 Assert.assertNotNull(overlay);
297
298 // We should get a new overlay with a valid surface key.
299 Client.Event event = mClient.nextEvent();
300 Assert.assertEquals(Client.SURFACE_READY, event.which);
301 Assert.assertTrue(event.surfaceKey > 0);
302 }
303 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698