summaryrefslogtreecommitdiffstats
path: root/chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java')
-rw-r--r--chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java309
1 files changed, 309 insertions, 0 deletions
diff --git a/chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java b/chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java
new file mode 100644
index 00000000000..71d1cbbaaf5
--- /dev/null
+++ b/chromium/base/android/junit/src/org/chromium/base/ApplicationStatusTest.java
@@ -0,0 +1,309 @@
+// Copyright 2015 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.view.ActionMode;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SearchEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+
+import androidx.annotation.RequiresApi;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.Shadows;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowActivity;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+
+import java.util.List;
+
+/** Unit tests for {@link ApplicationStatus}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, shadows = {ApplicationStatusTest.TrackingShadowActivity.class})
+public class ApplicationStatusTest {
+ private static class WindowCallbackWrapper implements Window.Callback {
+ final Window.Callback mWrapped;
+
+ public WindowCallbackWrapper(Window.Callback wrapped) {
+ mWrapped = wrapped;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return mWrapped.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ return mWrapped.dispatchKeyShortcutEvent(event);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ return mWrapped.dispatchTouchEvent(event);
+ }
+
+ @Override
+ public boolean dispatchTrackballEvent(MotionEvent event) {
+ return mWrapped.dispatchTrackballEvent(event);
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent event) {
+ return mWrapped.dispatchGenericMotionEvent(event);
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ return mWrapped.dispatchPopulateAccessibilityEvent(event);
+ }
+
+ @Override
+ public View onCreatePanelView(int featureId) {
+ return mWrapped.onCreatePanelView(featureId);
+ }
+
+ @Override
+ public boolean onCreatePanelMenu(int featureId, Menu menu) {
+ return mWrapped.onCreatePanelMenu(featureId, menu);
+ }
+
+ @Override
+ public boolean onPreparePanel(int featureId, View view, Menu menu) {
+ return mWrapped.onPreparePanel(featureId, view, menu);
+ }
+
+ @Override
+ public boolean onMenuOpened(int featureId, Menu menu) {
+ return mWrapped.onMenuOpened(featureId, menu);
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ return mWrapped.onMenuItemSelected(featureId, item);
+ }
+
+ @Override
+ public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
+ mWrapped.onWindowAttributesChanged(attrs);
+ }
+
+ @Override
+ public void onContentChanged() {
+ mWrapped.onContentChanged();
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ mWrapped.onWindowFocusChanged(hasFocus);
+ }
+
+ @Override
+ public void onAttachedToWindow() {
+ mWrapped.onAttachedToWindow();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ mWrapped.onDetachedFromWindow();
+ }
+
+ @Override
+ public void onPanelClosed(int featureId, Menu menu) {
+ mWrapped.onPanelClosed(featureId, menu);
+ }
+
+ @RequiresApi(23)
+ @Override
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ return mWrapped.onSearchRequested(searchEvent);
+ }
+
+ @Override
+ public boolean onSearchRequested() {
+ return mWrapped.onSearchRequested();
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
+ return mWrapped.onWindowStartingActionMode(callback);
+ }
+
+ @RequiresApi(23)
+ @Override
+ public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
+ return mWrapped.onWindowStartingActionMode(callback, type);
+ }
+
+ @Override
+ public void onActionModeStarted(ActionMode mode) {
+ mWrapped.onActionModeStarted(mode);
+ }
+
+ @Override
+ public void onActionModeFinished(ActionMode mode) {
+ mWrapped.onActionModeFinished(mode);
+ }
+
+ @RequiresApi(24)
+ @Override
+ public void onProvideKeyboardShortcuts(
+ List<KeyboardShortcutGroup> data, Menu menu, int deviceId) {
+ mWrapped.onProvideKeyboardShortcuts(data, menu, deviceId);
+ }
+
+ @RequiresApi(26)
+ @Override
+ public void onPointerCaptureChanged(boolean hasCapture) {
+ mWrapped.onPointerCaptureChanged(hasCapture);
+ }
+ }
+
+ private static class SubclassedCallbackWrapper extends WindowCallbackWrapper {
+ public SubclassedCallbackWrapper(Window.Callback callback) {
+ super(callback);
+ }
+ }
+
+ /** Shadow that tracks calls to onWindowFocusChanged and dispatchKeyEvent. */
+ @Implements(Activity.class)
+ public static class TrackingShadowActivity extends ShadowActivity {
+ private int mWindowFocusCalls;
+ private int mDispatchKeyEventCalls;
+ private boolean mReturnValueForKeyDispatch;
+
+ @Implementation
+ public void onWindowFocusChanged(@SuppressWarnings("unused") boolean hasFocus) {
+ mWindowFocusCalls++;
+ }
+
+ @Implementation
+ public boolean dispatchKeyEvent(@SuppressWarnings("unused") KeyEvent event) {
+ mDispatchKeyEventCalls++;
+ return mReturnValueForKeyDispatch;
+ }
+ }
+
+ @Test
+ public void testWindowsFocusChanged() {
+ ApplicationStatus.WindowFocusChangedListener mock =
+ mock(ApplicationStatus.WindowFocusChangedListener.class);
+ ApplicationStatus.registerWindowFocusChangedListener(mock);
+
+ ActivityController<Activity> controller =
+ Robolectric.buildActivity(Activity.class).create().start().visible();
+ TrackingShadowActivity shadow = (TrackingShadowActivity) Shadows.shadowOf(controller.get());
+
+ controller.get().getWindow().getCallback().onWindowFocusChanged(true);
+ // Assert that listeners were notified.
+ verify(mock).onWindowFocusChanged(controller.get(), true);
+ // Also ensure that the original activity is forwarded the notification.
+ Assert.assertEquals(1, shadow.mWindowFocusCalls);
+ }
+
+ @Test
+ public void testNullCallback() {
+ Assert.assertFalse(ApplicationStatus.reachesWindowCallback(null));
+ }
+
+ @Test
+ public void testOtherCallback() {
+ Assert.assertFalse(ApplicationStatus.reachesWindowCallback(mock(Window.Callback.class)));
+ }
+
+ private Window.Callback createWindowCallbackProxy() {
+ return ApplicationStatus.createWindowCallbackProxy(
+ mock(Activity.class), mock(Window.Callback.class));
+ }
+
+ @Test
+ public void testNotWrappedCallback() {
+ Assert.assertTrue(ApplicationStatus.reachesWindowCallback(createWindowCallbackProxy()));
+ }
+
+ @Test
+ public void testSingleWrappedCallback() {
+ Assert.assertTrue(ApplicationStatus.reachesWindowCallback(
+ new WindowCallbackWrapper(createWindowCallbackProxy())));
+ }
+
+ @Test
+ public void testDoubleWrappedCallback() {
+ Assert.assertTrue(ApplicationStatus.reachesWindowCallback(
+ new WindowCallbackWrapper(new WindowCallbackWrapper(createWindowCallbackProxy()))));
+ }
+
+ @Test
+ public void testSubclassWrappedCallback() {
+ Assert.assertTrue(ApplicationStatus.reachesWindowCallback(
+ new SubclassedCallbackWrapper(createWindowCallbackProxy())));
+ }
+
+ @Test
+ public void testTaskVisibilityForCreatedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create();
+ Assert.assertFalse(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+
+ @Test
+ public void testTaskVisibilityForStartedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create().start();
+ Assert.assertFalse(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+
+ @Test
+ public void testTaskVisibilityForResumedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create().resume();
+ Assert.assertTrue(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+
+ @Test
+ public void testTaskVisibilityForPausedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create().pause();
+ Assert.assertTrue(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+
+ @Test
+ public void testTaskVisibilityForStoppedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create().stop();
+ Assert.assertFalse(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+
+ @Test
+ public void testTaskVisibilityForDestroyedActivity() {
+ ActivityController<Activity> controller = Robolectric.buildActivity(Activity.class);
+
+ controller.create().destroy();
+ Assert.assertFalse(ApplicationStatus.isTaskVisible(controller.get().getTaskId()));
+ }
+}