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

Side by Side Diff: content/public/android/junit/src/org/chromium/content/browser/androidoverlay/DialogOverlayCoreTest.java

Issue 2765443004: AndroidOverlay implementation using Dialog. (Closed)
Patch Set: fixed test Created 3 years, 7 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 static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertNotNull;
9 import static org.junit.Assert.assertTrue;
10
11 import android.app.Activity;
12 import android.app.Dialog;
13 import android.os.Binder;
14 import android.os.IBinder;
15 import android.view.Surface;
16 import android.view.SurfaceHolder;
17
18 // TODO(liberato): prior to M, this was ...policy.impl.PhoneWindow
19 import com.android.internal.policy.PhoneWindow;
20
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.robolectric.Robolectric;
25 import org.robolectric.Shadows;
26 import org.robolectric.annotation.Config;
27 import org.robolectric.annotation.Implementation;
28 import org.robolectric.annotation.Implements;
29 import org.robolectric.shadows.ShadowDialog;
30 import org.robolectric.shadows.ShadowPhoneWindow;
31 import org.robolectric.shadows.ShadowSurfaceView;
32
33 import org.chromium.gfx.mojom.Rect;
34 import org.chromium.media.mojom.AndroidOverlayConfig;
35 import org.chromium.testing.local.LocalRobolectricTestRunner;
36
37 /**
38 * Tests for DialogOverlayCore.
39 */
40 @RunWith(LocalRobolectricTestRunner.class)
41 @Config(manifest = Config.NONE)
42 public class DialogOverlayCoreTest {
43 private Activity mActivity;
44
45 AndroidOverlayConfig mConfig = new AndroidOverlayConfig();
46
47 // DialogCore under test.
48 DialogOverlayCore mCore;
49
50 // The dialog that we've provided to |mCore|.
51 Dialog mDialog;
52
53 // Fake window token that we'll send to |mCore|.
54 IBinder mWindowToken = new Binder();
55
56 // Surface that will be provided by |mDialog|.
57 Surface mSurface = new Surface();
58
59 // SurfaceHolder that will be provided by |mDialog|.
60 SurfaceHolder mHolder = new MyFakeSurfaceHolder(mSurface);
61
62 /**
63 * Robolectric shadow for PhoneWindow. This one keeps track of takeSurface( ) calls.
64 * TODO(liberato): the @Impl specifies 'minSdk=M' in the robolectric source.
65 */
66 @Implements(value = PhoneWindow.class, isInAndroidSdk = false)
67 public static class MyPhoneWindowShadow extends ShadowPhoneWindow {
68 public MyPhoneWindowShadow() {}
69
70 private SurfaceHolder.Callback2 mCallback;
71
72 @Implementation
73 public void takeSurface(SurfaceHolder.Callback2 callback) {
74 mCallback = callback;
75 }
76 }
77
78 /**
79 * The default fake surface holder doesn't let us provide a surface.
80 */
81 public static class MyFakeSurfaceHolder extends ShadowSurfaceView.FakeSurfac eHolder {
82 private Surface mSurface;
83
84 // @param surface The Surface that we'll provide via getSurface.
85 public MyFakeSurfaceHolder(Surface surface) {
86 mSurface = surface;
87 }
88
89 @Override
90 public Surface getSurface() {
91 return mSurface;
92 }
93 }
94
95 @Before
96 public void setUp() {
97 mActivity = Robolectric.buildActivity(Activity.class).setup().get();
98
99 mConfig = new AndroidOverlayConfig();
100 mConfig.rect = new Rect();
101 mConfig.rect.x = 0;
102 mConfig.rect.y = 1;
103 mConfig.rect.width = 2;
104 mConfig.rect.height = 3;
105
106 mCore = new DialogOverlayCore();
107 mCore.initialize(mActivity, mConfig, mHost);
108 mDialog = mCore.getDialog();
109
110 // Nothing should be called yet.
111 checkOverlayDidntCall();
112
113 // The dialog should not be shown yet.
114 checkDialogIsNotShown();
115 }
116
117 // Make sure that the overlay didn't provide us with a surface, or notify us that it was
118 // destroyed, or wait for cleanup.
119 void checkOverlayDidntCall() {
120 assertEquals(null, mHost.surface());
121 assertEquals(0, mHost.destroyedCount());
122 assertEquals(0, mHost.cleanupCount());
123 }
124
125 // Return the SurfaceHolder callback that was provided to takeSurface(), if any.
126 SurfaceHolder.Callback2 holderCallback() {
127 return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow())).mCa llback;
128 }
129
130 /**
131 * Host impl that counts calls to it.
132 */
133 class HostMock implements DialogOverlayCore.Host {
134 private Surface mSurface;
135 private int mDestroyedCount;
136 private int mCleanupCount;
137
138 @Override
139 public void onSurfaceReady(Surface surface) {
140 mSurface = surface;
141 }
142
143 @Override
144 public void onOverlayDestroyed() {
145 mDestroyedCount++;
146 }
147
148 @Override
149 public void waitForCleanup() {
150 mCleanupCount++;
151 }
152
153 public Surface surface() {
154 return mSurface;
155 }
156
157 public int destroyedCount() {
158 return mDestroyedCount;
159 }
160
161 public int cleanupCount() {
162 return mCleanupCount;
163 }
164 };
165
166 HostMock mHost = new HostMock();
167
168 // Send a window token and provide the surface, so that the overlay is ready for use.
169 void sendTokenAndSurface() {
170 mCore.onWindowToken(mWindowToken);
171 // Make sure that somebody called takeSurface.
172 assertNotNull(holderCallback());
173
174 checkDialogIsShown();
175
176 // Provide the Android Surface.
177 holderCallback().surfaceCreated(mHolder);
178
179 // The host should have been told about the surface.
180 assertEquals(mSurface, mHost.surface());
181 }
182
183 // Verify that the dialog has been shown.
184 void checkDialogIsShown() {
185 assertEquals(mDialog, ShadowDialog.getShownDialogs().get(0));
186 }
187
188 // Verify that the dialog is not currently shown. Note that dismiss() doesn 't remove it from
189 // the shown dialog list in Robolectric, so we check for "was never shown or was dismissed".
190 void checkDialogIsNotShown() {
191 assertTrue(ShadowDialog.getShownDialogs().size() == 0
192 || Shadows.shadowOf(mDialog).hasBeenDismissed());
193 }
194
195 // Verify that |mCore| signaled that the overlay was lost to|mHost|.
196 void checkOverlayWasDestroyed() {
197 // |mCore| should have notified the host that it has been destroyed, and also waited for
198 // the host to signal that the client released it.
199 assertEquals(1, mHost.destroyedCount());
200 checkDialogIsNotShown();
201 }
202
203 // Check that releasing an overlay before getting a window token works.
204 @Test
205 @Config(shadows = {MyPhoneWindowShadow.class})
206 public void testReleaseImmediately() {
207 // Release the overlay. |mCore| shouldn't notify us, since we released it.
208 mCore.release();
209 checkOverlayDidntCall();
210 checkDialogIsNotShown();
211 }
212
213 // Create a dialog, then send it a token. Verify that it's shown.
214 @Test
215 @Config(shadows = {MyPhoneWindowShadow.class})
216 public void testTokenThenRelease() {
217 mCore.onWindowToken(mWindowToken);
218 checkDialogIsShown();
219
220 // Release the surface. |mHost| shouldn't be notified, nor should it wa it for cleanup.
221 // Note: it might be okay if it checks for cleanup, since cleanup would be complete after
222 // we call release(). However, it's not needed, so we enforce that it i sn't.
223 mCore.release();
224 checkOverlayDidntCall();
225 checkDialogIsNotShown();
226 }
227
228 // Create a dialog, send a token, send a surface, then release it.
229 @Test
230 @Config(shadows = {MyPhoneWindowShadow.class})
231 public void testSurfaceThenRelease() {
232 sendTokenAndSurface();
233
234 mCore.release();
235 assertEquals(0, mHost.destroyedCount());
236 assertEquals(0, mHost.cleanupCount());
237 checkDialogIsNotShown();
238 }
239
240 // Create a dialog, send a surface, then destroy the surface.
241 @Test
242 @Config(shadows = {MyPhoneWindowShadow.class})
243 public void testSurfaceThenDestroy() {
244 sendTokenAndSurface();
245
246 // Destroy the surface.
247 holderCallback().surfaceDestroyed(mHolder);
248 // |mCore| should have waited for cleanup during surfaceDestroyed.
249 assertEquals(1, mHost.cleanupCount());
250 // Since we waited for cleanup, also pretend that the release was posted during the wait and
251 // will arrive after the wait completes.
252 mCore.release();
253
254 checkOverlayWasDestroyed();
255 }
256
257 // Test that we're notified when the window token changes.
258 @Test
259 @Config(shadows = {MyPhoneWindowShadow.class})
260 public void testChangeWindowToken() {
261 sendTokenAndSurface();
262
263 // Change the window token.
264 mCore.onWindowToken(new Binder());
265
266 checkOverlayWasDestroyed();
267 }
268
269 // Test that we're notified when the window token is lost.
270 @Test
271 @Config(shadows = {MyPhoneWindowShadow.class})
272 public void testLoseWindowToken() {
273 sendTokenAndSurface();
274
275 // Remove the window token.
276 mCore.onWindowToken(null);
277
278 checkOverlayWasDestroyed();
279 }
280 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698