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

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: fixed gn 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_shell_apk.ContentShellTestBase;
16 import org.chromium.media.mojom.AndroidOverlayClient;
17 import org.chromium.media.mojom.AndroidOverlayConfig;
18 import org.chromium.mojo.common.mojom.UnguessableToken;
19 import org.chromium.mojo.system.MojoException;
20
21 import java.util.concurrent.ArrayBlockingQueue;
22 import java.util.concurrent.TimeUnit;
23
24 /**
25 * Tests for DialogOverlayImpl.
26 */
27 public class DialogOverlayImplTest extends ContentShellTestBase {
28 private static final String BLANK_URL = "about://blank";
29
30 // The routing token that we'll use to create overlays.
31 UnguessableToken mRoutingToken;
32
33 // overlay-ui thread.
34 HandlerThread mOverlayUiThread;
35 Handler mOverlayUiHandler;
36
37 // Runnable that will be called on the browser UI thread when an overlay is released.
38 Runnable mReleasedRunnable;
39
40 // True if we should create a secure overlay.
41 boolean mSecure;
42
43 /**
44 * AndroidOverlay client that supports waiting operations for callbacks. On e may call
45 * nextEvent() to get the next callback, waiting if needed.
46 */
47 public class Client implements AndroidOverlayClient {
48 // AndroidOverlayClient
49 public static final int SURFACE_READY = 0;
50 public static final int DESTROYED = 1;
51 public static final int CLOSE = 2;
52 public static final int CONNECTION_ERROR = 2;
53 // AndroidOverlayProviderImpl.Callbacks
54 public static final int RELEASED = 100;
55
56 /**
57 * Records one callback event.
58 */
59 public class Event {
60 public Event(int which) {
61 this.which = which;
62 }
63
64 public Event(int which, long surfaceKey) {
65 this.which = which;
66 this.surfaceKey = surfaceKey;
67 }
68
69 public Event(int which, MojoException exception) {
70 this.which = which;
71 this.exception = exception;
72 }
73
74 public int which;
75 public long surfaceKey;
76 public MojoException exception;
77 }
78
79 private ArrayBlockingQueue<Event> mPending;
80
81 public Client() {
82 mPending = new ArrayBlockingQueue<Event>(10);
83 }
84
85 @Override
86 public void onSurfaceReady(long surfaceKey) {
87 mPending.add(new Event(SURFACE_READY, surfaceKey));
88 }
89
90 @Override
91 public void onDestroyed() {
92 mPending.add(new Event(DESTROYED));
93 }
94
95 @Override
96 public void close() {
97 mPending.add(new Event(CLOSE));
98 }
99
100 @Override
101 public void onConnectionError(MojoException exception) {
102 mPending.add(new Event(CONNECTION_ERROR, exception));
103 }
104
105 // This isn't part of the overlay client. It's called by the overlay to indicate that it
106 // has been released by the client, but it's routed to us anyway. It's on the Browser UI
107 // thread, and it's convenient for us to keep track of it here.
108 public void notifyReleased() {
109 mPending.add(new Event(RELEASED));
110 }
111
112 // Wait for something to happen. We enforce a timeout, since the test h arness doesn't
113 // always seem to fail the test when it times out. Plus, it takes ~minu te for that, but
114 // none of our messages should take that long.
115 Event nextEvent() {
116 try {
117 return mPending.poll(500, TimeUnit.MILLISECONDS);
118 } catch (InterruptedException e) {
119 Assert.fail(e.toString());
120 }
121
122 // NOTREACHED
123 return null;
124 }
125
126 boolean isEmpty() {
127 return mPending.size() == 0;
128 }
129 }
130
131 private Client mClient = new Client();
132
133 @Override
134 public void setUp() throws Exception {
135 super.setUp();
136
137 startActivityWithTestUrl(BLANK_URL);
138
139 // Fetch the routing token.
140 mRoutingToken = new UIAction<UnguessableToken>() {
141 public UnguessableToken runOnUiThread() {
142 org.chromium.base.UnguessableToken routingToken =
143 getWebContents().getMainFrame().getAndroidOverlayRouting Token();
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> {
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 Handler handler = new Handler(overlayUiThread.getLooper());
219 DialogOverlayOperations ops =
220 new DialogOverlayOperationsImpl(handler, mReleasedRunnab le);
221 DialogOverlayImpl impl = new DialogOverlayImpl(mClient, config, ops);
222
223 return impl;
224 }
225 }
226 .run();
227 }
228
229 @SmallTest
230 @Feature({"AndroidOverlay"})
231 public void testCreateDestroyOverlay() {
232 final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
233
234 // We should get a new overlay with a valid surface key.
235 Client.Event event = mClient.nextEvent();
236 Assert.assertEquals(Client.SURFACE_READY, event.which);
237 Assert.assertTrue(event.surfaceKey > 0);
238
239 // Close the overlay, and make sure that the provider is notified.
240 // Note that we should not get a 'destroyed' message when we close it.
241 new UIAction<Boolean>() {
242 @Override
243 public Boolean runOnUiThread() {
244 overlay.close();
245 return true;
246 }
247 }
248 .run();
249 Assert.assertEquals(Client.RELEASED, mClient.nextEvent().which);
250 }
251
252 @SmallTest
253 @Feature({"AndroidOverlay"})
254 public void testCreateOverlayFailsIfUnknownRoutingToken() {
255 // Try to create an overlay with a bad routing token.
256 mRoutingToken.high++;
257 DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
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
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