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

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

Powered by Google App Engine
This is Rietveld 408576698