diff options
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.java | 309 |
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())); + } +} |