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

Side by Side Diff: chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest2.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 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 2015 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.chrome.browser.infobar;
6
7 import android.graphics.Rect;
8 import android.graphics.Region;
9 import android.test.FlakyTest;
10 import android.test.suitebuilder.annotation.MediumTest;
11 import android.view.ViewGroup;
12 import android.view.ViewTreeObserver;
13
14 import org.chromium.base.ThreadUtils;
15 import org.chromium.base.test.util.Feature;
16 import org.chromium.chrome.browser.ChromeActivity;
17 import org.chromium.chrome.browser.Tab;
18 import org.chromium.chrome.browser.preferences.NetworkPredictionOptions;
19 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
20 import org.chromium.chrome.test.ChromeActivityTestCaseBase;
21 import org.chromium.chrome.test.util.InfoBarTestAnimationListener;
22 import org.chromium.chrome.test.util.InfoBarUtil;
23 import org.chromium.chrome.test.util.TestHttpServerClient;
24 import org.chromium.content.browser.test.util.Criteria;
25 import org.chromium.content.browser.test.util.CriteriaHelper;
26
27 import java.util.ArrayList;
28 import java.util.concurrent.Callable;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.TimeoutException;
31 import java.util.concurrent.atomic.AtomicInteger;
32
33 /**
34 * Tests for InfoBars.
35 *
36 * TODO(newt): merge this with InfoBarTest after upstreaming.
37 */
38 public class InfoBarTest2 extends ChromeActivityTestCaseBase<ChromeActivity> {
39 static class MutableBoolean {
40 public boolean mValue = false;
41 }
42
43 private InfoBarTestAnimationListener mListener;
44
45 public InfoBarTest2() {
46 super(ChromeActivity.class);
47 }
48
49 @Override
50 protected void setUp() throws Exception {
51 super.setUp();
52
53 // Register for animation notifications
54 InfoBarContainer container =
55 getActivity().getActivityTab().getInfoBarContainer();
56 mListener = new InfoBarTestAnimationListener();
57 container.setAnimationListener(mListener);
58 }
59
60 // Adds an infobar to the currrent tab. Blocks until the infobar has been ad ded.
61 protected void addInfoBarToCurrentTab(final InfoBar infoBar) throws Interrup tedException {
62 getInstrumentation().runOnMainSync(new Runnable() {
63 @Override
64 public void run() {
65 Tab tab = getActivity().getActivityTab();
66 assertTrue("Failed to find tab.", tab != null);
67 tab.getInfoBarContainer().addInfoBar(infoBar);
68 }
69 });
70 assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished() );
71 getInstrumentation().waitForIdleSync();
72 }
73
74 // Removes an infobar from the currrent tab. Blocks until the infobar has be en removed.
75 protected void removeInfoBarFromCurrentTab(final InfoBar infoBar) throws Int erruptedException {
76 getInstrumentation().runOnMainSync(new Runnable() {
77 @Override
78 public void run() {
79 Tab tab = getActivity().getActivityTab();
80 assertTrue("Failed to find tab.", tab != null);
81 tab.getInfoBarContainer().removeInfoBar(infoBar);
82 }
83 });
84 assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinis hed());
85 getInstrumentation().waitForIdleSync();
86 }
87
88 // Dismisses the passed infobar. Blocks until the bar has been removed.
89 protected void dismissInfoBar(final InfoBar infoBar) throws InterruptedExcep tion {
90 getInstrumentation().runOnMainSync(new Runnable() {
91 @Override
92 public void run() {
93 infoBar.dismissJavaOnlyInfoBar();
94 }
95 });
96 assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinis hed());
97 getInstrumentation().waitForIdleSync();
98 }
99
100 protected ArrayList<Integer> getInfoBarIdsForCurrentTab() {
101 final ArrayList<Integer> infoBarIds = new ArrayList<Integer>();
102 getInstrumentation().runOnMainSync(new Runnable() {
103 @Override
104 public void run() {
105 Tab tab = getActivity().getActivityTab();
106 assertTrue("Failed to find tab.", tab != null);
107 for (InfoBar infoBar : tab.getInfoBarContainer().getInfoBars()) {
108 infoBarIds.add(infoBar.getId());
109 }
110 }
111 });
112 return infoBarIds;
113 }
114
115 /**
116 * Verifies that infobars added from Java expire or not as expected.
117 */
118 @MediumTest
119 @Feature({"Browser"})
120 public void testInfoBarExpiration() throws InterruptedException {
121 // First add an infobar that expires.
122 final MutableBoolean dismissed = new MutableBoolean();
123 MessageInfoBar expiringInfoBar = new MessageInfoBar("Hello!");
124 expiringInfoBar.setDismissedListener(new InfoBarListeners.Dismiss() {
125 @Override
126 public void onInfoBarDismissed(InfoBar infoBar) {
127 dismissed.mValue = true;
128 }
129 });
130 expiringInfoBar.setExpireOnNavigation(true);
131 addInfoBarToCurrentTab(expiringInfoBar);
132
133 // Verify it's really there.
134 ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
135 assertEquals(1, infoBarIds.size());
136 assertEquals(expiringInfoBar.getId(), infoBarIds.get(0).intValue());
137
138 // Now navigate, it should expire.
139 loadUrl(TestHttpServerClient.getUrl("chrome/test/data/android/google.htm l"));
140 assertTrue("InfoBar not removed.", mListener.removeInfoBarAnimationFinis hed());
141 assertTrue("InfoBar did not expire on navigation.", dismissed.mValue);
142 infoBarIds = getInfoBarIdsForCurrentTab();
143 assertTrue(infoBarIds.isEmpty());
144
145 // Now test a non-expiring infobar.
146 MessageInfoBar persistentInfoBar = new MessageInfoBar("Hello!");
147 persistentInfoBar.setDismissedListener(new InfoBarListeners.Dismiss() {
148 @Override
149 public void onInfoBarDismissed(InfoBar infoBar) {
150 dismissed.mValue = true;
151 }
152 });
153 dismissed.mValue = false;
154 persistentInfoBar.setExpireOnNavigation(false);
155 addInfoBarToCurrentTab(persistentInfoBar);
156
157 // Navigate, it should still be there.
158 loadUrl(TestHttpServerClient.getUrl("chrome/test/data/android/google.htm l"));
159 assertFalse("InfoBar did expire on navigation.", dismissed.mValue);
160 infoBarIds = getInfoBarIdsForCurrentTab();
161 assertEquals(1, infoBarIds.size());
162 assertEquals(persistentInfoBar.getId(), infoBarIds.get(0).intValue());
163
164 // Close the infobar.
165 dismissInfoBar(persistentInfoBar);
166 }
167
168 // Define function to pass parameter to Runnable to be used in testInfoBarEx pirationNoPrerender.
169 private Runnable setNetworkPredictionOptions(
170 final NetworkPredictionOptions networkPredictionOptions) {
171 return new Runnable() {
172 @Override
173 public void run() {
174 PrefServiceBridge.getInstance().setNetworkPredictionOptions(
175 networkPredictionOptions);
176 }
177 };
178 };
179
180 /**
181 * Same as testInfoBarExpiration but with prerender turned-off.
182 * The behavior when prerender is on/off is different as in the prerender ca se the infobars are
183 * added when we swap tabs.
184 * @throws InterruptedException
185 */
186 @MediumTest
187 @Feature({"Browser"})
188 public void testInfoBarExpirationNoPrerender() throws InterruptedException, ExecutionException {
189 // Save prediction preference.
190 NetworkPredictionOptions networkPredictionOption =
191 ThreadUtils.runOnUiThreadBlocking(new Callable<NetworkPrediction Options>() {
192 @Override
193 public NetworkPredictionOptions call() {
194 return PrefServiceBridge.getInstance().getNetworkPredict ionOptions();
195 }
196 });
197 try {
198 ThreadUtils.runOnUiThreadBlocking(setNetworkPredictionOptions(
199 NetworkPredictionOptions.NETWORK_PREDICTION_NEVER));
200 testInfoBarExpiration();
201 } finally {
202 // Make sure we restore prediction preference.
203 ThreadUtils.runOnUiThreadBlocking(setNetworkPredictionOptions(networ kPredictionOption));
204 }
205 }
206
207 /**
208 * Tests that adding and then immediately removing an infobar works as expec ted (and does not
209 * assert).
210 */
211 @MediumTest
212 @Feature({"Browser"})
213 public void testQuickAddOneAndRemove() throws InterruptedException {
214 final InfoBar infoBar = new MessageInfoBar("Hello");
215 addInfoBarToCurrentTab(infoBar);
216 removeInfoBarFromCurrentTab(infoBar);
217 assertTrue(getInfoBarIdsForCurrentTab().isEmpty());
218 }
219
220 /**
221 * Tests that adding and then immediately dismissing an infobar works as exp ected (and does not
222 * assert).
223 */
224 @MediumTest
225 @Feature({"Browser"})
226 public void testQuickAddOneAndDismiss() throws InterruptedException {
227 final InfoBar infoBar = new MessageInfoBar("Hello");
228 addInfoBarToCurrentTab(infoBar);
229 dismissInfoBar(infoBar);
230 assertTrue(getInfoBarIdsForCurrentTab().isEmpty());
231 }
232
233 /**
234 * Tests that adding 2 infobars and then immediately removing the last one w orks as expected.
235 * This scenario is special as the 2nd infobar does not even get added to th e view hierarchy.
236 */
237 @MediumTest
238 @Feature({"Browser"})
239 public void testAddTwoAndRemoveOneQuick() throws InterruptedException {
240 final InfoBar infoBar1 = new MessageInfoBar("One");
241 final InfoBar infoBar2 = new MessageInfoBar("Two");
242 getInstrumentation().runOnMainSync(new Runnable() {
243 @Override
244 public void run() {
245 Tab tab = getActivity().getActivityTab();
246 assertTrue("Failed to find tab.", tab != null);
247 tab.getInfoBarContainer().addInfoBar(infoBar1);
248 tab.getInfoBarContainer().addInfoBar(infoBar2);
249 tab.getInfoBarContainer().removeInfoBar(infoBar2);
250 }
251 });
252
253 // We should get an infobar added event for the first infobar.
254 assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished() );
255
256 // But no infobar removed event as the 2nd infobar was removed before it got added.
257 assertFalse("InfoBar not removed.", mListener.removeInfoBarAnimationFini shed());
258 ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
259 assertEquals(1, infoBarIds.size());
260 assertEquals(infoBar1.getId(), infoBarIds.get(0).intValue());
261 }
262
263 /**
264 * Tests that adding 2 infobars and then immediately dismissing the last one works as expected
265 * This scenario is special as the 2nd infobar does not even get added to th e view hierarchy.
266 */
267 @MediumTest
268 @Feature({"Browser"})
269 public void testAddTwoAndDismissOneQuick() throws InterruptedException {
270 final InfoBar infoBar1 = new MessageInfoBar("One");
271 final InfoBar infoBar2 = new MessageInfoBar("Two");
272 getInstrumentation().runOnMainSync(new Runnable() {
273 @Override
274 public void run() {
275 Tab tab = getActivity().getActivityTab();
276 assertTrue("Failed to find tab.", tab != null);
277 tab.getInfoBarContainer().addInfoBar(infoBar1);
278 tab.getInfoBarContainer().addInfoBar(infoBar2);
279 infoBar2.dismissJavaOnlyInfoBar();
280 }
281 });
282
283 // We should get an infobar added event for the first infobar.
284 assertTrue("InfoBar not added.", mListener.addInfoBarAnimationFinished() );
285
286 // But no infobar removed event as the 2nd infobar was removed before it got added.
287 assertFalse("InfoBar not removed.", mListener.removeInfoBarAnimationFini shed());
288 ArrayList<Integer> infoBarIds = getInfoBarIdsForCurrentTab();
289 assertEquals(1, infoBarIds.size());
290 assertEquals(infoBar1.getId(), infoBarIds.get(0).intValue());
291 }
292
293 /**
294 * Tests that we don't assert when a tab is getting closed while an infobar is being shown and
295 * had been removed.
296 */
297 @MediumTest
298 @Feature({"Browser"})
299 public void testCloseTabOnAdd() throws InterruptedException {
300 loadUrl(TestHttpServerClient.getUrl(
301 "chrome/test/data/android/google.html"));
302
303 final InfoBar infoBar = new MessageInfoBar("Hello");
304 addInfoBarToCurrentTab(infoBar);
305 getInstrumentation().runOnMainSync(new Runnable() {
306 @Override
307 public void run() {
308 Tab tab = getActivity().getActivityTab();
309 assertTrue("Failed to find tab.", tab != null);
310 tab.getInfoBarContainer().removeInfoBar(infoBar);
311 getActivity().getTabModelSelector().closeTab(tab);
312 }
313 });
314 }
315
316 /**
317 * Tests that the x button in the infobar does close the infobar and that th e event is not
318 * propagated to the ContentView.
319 * @MediumTest
320 * @Feature({"Browser"})
321 * Bug: http://crbug.com/172427
322 */
323 @FlakyTest
324 public void testCloseButton() throws InterruptedException, TimeoutException {
325 loadUrl(TestHttpServerClient.getUrl(
326 "chrome/test/data/android/click_listener.html"));
327 final InfoBar infoBar = new MessageInfoBar("Hello");
328 getInstrumentation().runOnMainSync(new Runnable() {
329 @Override
330 public void run() {
331 Tab tab = getActivity().getActivityTab();
332 assertTrue("Failed to find tab.", tab != null);
333 tab.getInfoBarContainer().addInfoBar(infoBar);
334 }
335 });
336 assertTrue("InfoBar not added", mListener.addInfoBarAnimationFinished()) ;
337
338 // Now press the close button.
339 assertTrue("Close button wasn't found", InfoBarUtil.clickCloseButton(inf oBar));
340 assertTrue("Infobar not removed.", mListener.removeInfoBarAnimationFinis hed());
341
342 // The page should not have received the click.
343 assertTrue("The page recieved the click.",
344 !Boolean.parseBoolean(runJavaScriptCodeInCurrentTab("wasClicked" )));
345 }
346
347 /**
348 * Tests that adding and removing correctly manages the transparent region, which allows for
349 * optimizations in SurfaceFlinger (less overlays).
350 */
351 @MediumTest
352 @Feature({"Browser"})
353 public void testAddAndDismissSurfaceFlingerOverlays() throws InterruptedExce ption {
354 final ViewGroup decorView = (ViewGroup) getActivity().getWindow().getDe corView();
355 final InfoBarContainer infoBarContainer =
356 getActivity().getActivityTab().getInfoBarContainer();
357
358 // Detect layouts. Note this doesn't actually need to be atomic (just fi nal).
359 final AtomicInteger layoutCount = new AtomicInteger();
360 getInstrumentation().runOnMainSync(new Runnable() {
361 @Override
362 public void run() {
363 decorView.getViewTreeObserver().addOnGlobalLayoutListener(
364 new ViewTreeObserver.OnGlobalLayoutListener() {
365 @Override
366 public void onGlobalLayout() {
367 layoutCount.incrementAndGet();
368 }
369 });
370 }
371 });
372
373 // First add an infobar.
374 final InfoBar infoBar = new MessageInfoBar("Hello");
375 addInfoBarToCurrentTab(infoBar);
376
377 // A layout must occur to recalculate the transparent region.
378 boolean layoutOccured = CriteriaHelper.pollForUIThreadCriteria(
379 new Criteria() {
380 @Override
381 public boolean isSatisfied() {
382 return layoutCount.get() > 0;
383 }
384 });
385 assertTrue(layoutOccured);
386
387 final Rect fullDisplayFrame = new Rect();
388 final Rect fullDisplayFrameMinusContainer = new Rect();
389 final Rect containerDisplayFrame = new Rect();
390
391 getInstrumentation().runOnMainSync(new Runnable() {
392 @Override
393 public void run() {
394 decorView.getWindowVisibleDisplayFrame(fullDisplayFrame);
395 decorView.getWindowVisibleDisplayFrame(fullDisplayFrameMinusCont ainer);
396 fullDisplayFrameMinusContainer.bottom -= infoBarContainer.getHei ght();
397 int windowLocation[] = new int[2];
398 infoBarContainer.getLocationInWindow(windowLocation);
399 containerDisplayFrame.set(
400 windowLocation[0],
401 windowLocation[1],
402 windowLocation[0] + infoBarContainer.getWidth(),
403 windowLocation[1] + infoBarContainer.getHeight());
404
405 // The InfoBarContainer subtracts itself from the transparent re gion.
406 Region transparentRegion = new Region(fullDisplayFrame);
407 infoBarContainer.gatherTransparentRegion(transparentRegion);
408 assertEquals(transparentRegion.getBounds(), fullDisplayFrameMinu sContainer);
409 }
410 });
411
412 // Now remove the infobar.
413 layoutCount.set(0);
414 dismissInfoBar(infoBar);
415
416 // A layout must occur to recalculate the transparent region.
417 layoutOccured = CriteriaHelper.pollForUIThreadCriteria(
418 new Criteria() {
419 @Override
420 public boolean isSatisfied() {
421 return layoutCount.get() > 0;
422 }
423 });
424 assertTrue(layoutOccured);
425
426 getInstrumentation().runOnMainSync(new Runnable() {
427 @Override
428 public void run() {
429 // The InfoBarContainer should no longer be subtracted from the transparent region.
430 // We really want assertTrue(transparentRegion.contains(containe rDisplayFrame)),
431 // but region doesn't have 'contains(Rect)', so we invert the te st. So, the old
432 // container rect can't touch the bounding rect of the non-trans parent region).
433 Region transparentRegion = new Region();
434 decorView.gatherTransparentRegion(transparentRegion);
435 Region opaqueRegion = new Region(fullDisplayFrame);
436 opaqueRegion.op(transparentRegion, Region.Op.DIFFERENCE);
437 assertFalse(opaqueRegion.getBounds().intersect(containerDisplayF rame));
438 }
439 });
440
441 // Additional manual test that this is working:
442 // - adb shell dumpsys SurfaceFlinger
443 // - Observe that Clank's overlay size changes (or disappears if URLbar is also gone).
444 }
445
446 @Override
447 public void startMainActivity() throws InterruptedException {
448 startMainActivityOnBlankPage();
449 }
450 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698