BaseNavigationalTransition { protected void finishCallerDelayed(@NonNull final Activity caller, @IntRange(from = 0) final long delay) { final View decorView = caller.getWindow().getDecorView(); if (decorView != null) decorView.postDelayed(new Runnable() { @Override public void run() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && caller.isDestroyed()) { return; } if (caller.isFinishing()) { return; } onFinishCaller(caller); } }, delay); } BaseNavigationalTransition();  BaseNavigationalTransition(@NonNull final Class<? extends Activity> classOfTransitionActivity); @SuppressWarnings("deprecation") @Nullable final Class<? extends Activity> getActivityClass(); @SuppressWarnings("unchecked") T intentExtras(@Nullable final Bundle extras); @NonNull Bundle intentExtras(); @SuppressWarnings("unchecked") T requestCode(@IntRange(from = RC_NONE) final int requestCode); @IntRange(from = RC_NONE) int requestCode(); @SuppressWarnings("unchecked") T enterTransition(@Nullable final Transition transition); @Nullable Transition enterTransition(); @SuppressWarnings("unchecked") T reenterTransition(@Nullable final Transition transition); @Nullable Transition reenterTransition(); @SuppressWarnings("unchecked") T returnTransition(@Nullable final Transition transition); @Nullable Transition returnTransition(); @SuppressWarnings("unchecked") T exitTransition(@Nullable final Transition transition); @Nullable Transition exitTransition(); @SuppressWarnings("unchecked") T allowEnterTransitionOverlap(final boolean allow); boolean allowEnterTransitionOverlap(); @SuppressWarnings("unchecked") T allowReturnTransitionOverlap(final boolean allow); boolean allowReturnTransitionOverlap(); @SuppressWarnings("unchecked") T sharedElementEnterTransition(@Nullable final Transition transition); @Nullable Transition sharedElementEnterTransition(); @SuppressWarnings("unchecked") T sharedElementReenterTransition(@Nullable final Transition transition); @Nullable Transition sharedElementReenterTransition(); @SuppressWarnings("unchecked") T sharedElementReturnTransition(@Nullable final Transition transition); @Nullable Transition sharedElementReturnTransition(); @SuppressWarnings("unchecked") T sharedElementExitTransition(@Nullable final Transition transition); @Nullable Transition sharedElementExitTransition(); @SuppressWarnings("unchecked") T sharedElementsUseOverlay(final boolean useOverlay); boolean sharedElementsUseOverlay(); @SuppressLint("NewApi") @Nullable Transition inflateTransition(@NonNull final Context context, final int resource); @SuppressLint("NewApi") @Nullable TransitionManager inflateTransitionManager(@NonNull final Context context, final int resource, @NonNull final ViewGroup sceneRoot); @SuppressWarnings("unchecked") @SafeVarargs final T sharedElements(@NonNull final Pair<View, String>... elements); @SuppressWarnings("unchecked") T sharedElement(@NonNull final View element, @NonNull final String elementName); @Nullable List<Pair<View, String>> sharedElements(); @Nullable Pair<View, String> singleSharedElement(); void start(@NonNull final Activity caller); void configureTransitions(@NonNull final Activity activity); void configureIncomingTransitions(@NonNull final Activity activity); void configureOutgoingTransitions(@NonNull final Activity activity); @SuppressLint("NewApi") @SuppressWarnings("unchecked") @Nullable ActivityOptions makeSceneTransitionAnimation(@NonNull final Activity caller); @NonNull Intent createIntent(@NonNull final Activity caller); void finish(@NonNull final Activity caller); static final boolean MATERIAL_SUPPORT; static final int RC_NONE; }
@Config(sdk = Build.VERSION_CODES.LOLLIPOP) @Test public void testFinishCallerDelayedAtLollipopApiLevel() { final Activity mockActivity = mock(TestActivity.class); final Window mockWindow = mock(Window.class); final View decorView = new FrameLayout(context) { @Override public boolean postDelayed(@NonNull final Runnable action, final long delayMillis) { waitFor(delayMillis); action.run(); return true; } }; when(mockWindow.getDecorView()).thenReturn(decorView); when(mockActivity.getWindow()).thenReturn(mockWindow); when(mockActivity.isFinishing()).thenReturn(false); when(mockActivity.isDestroyed()).thenReturn(false); final BaseNavigationalTransition navTransition = new TestTransition(); navTransition.finishCallerDelayed(mockActivity, 100); verify(mockActivity).getWindow(); verify(mockWindow).getDecorView(); verifyNoMoreInteractions(mockWindow); verify(mockActivity).finishAfterTransition(); verify(mockActivity).isDestroyed(); verify(mockActivity).isFinishing(); verifyNoMoreInteractions(mockActivity); }
@Config(sdk = Build.VERSION_CODES.JELLY_BEAN_MR2) @Test public void testFinishCallerDelayedForDestroyedCaller() { final Activity mockActivity = mock(TestActivity.class); final Window mockWindow = mock(Window.class); final View decorView = new FrameLayout(context) { @Override public boolean postDelayed(@NonNull final Runnable action, final long delayMillis) { waitFor(delayMillis); action.run(); return true; } }; when(mockWindow.getDecorView()).thenReturn(decorView); when(mockActivity.getWindow()).thenReturn(mockWindow); when(mockActivity.isDestroyed()).thenReturn(true); final BaseNavigationalTransition navTransition = new TestTransition(); navTransition.finishCallerDelayed(mockActivity, 100); verify(mockActivity).getWindow(); verify(mockWindow).getDecorView(); verifyNoMoreInteractions(mockWindow); verify(mockActivity).isDestroyed(); verifyNoMoreInteractions(mockActivity); }
@Config(sdk = Build.VERSION_CODES.JELLY_BEAN) @Test public void testFinishCallerDelayedForFinishingCallerAtJellyBeanApiLevel() { final Activity mockActivity = mock(TestActivity.class); final Window mockWindow = mock(Window.class); final View decorView = new FrameLayout(context) { @Override public boolean postDelayed(@NonNull final Runnable action, final long delayMillis) { waitFor(delayMillis); action.run(); return true; } }; when(mockWindow.getDecorView()).thenReturn(decorView); when(mockActivity.getWindow()).thenReturn(mockWindow); when(mockActivity.isFinishing()).thenReturn(true); final BaseNavigationalTransition navTransition = new TestTransition(); navTransition.finishCallerDelayed(mockActivity, 100); verify(mockActivity).getWindow(); verify(mockWindow).getDecorView(); verifyNoMoreInteractions(mockWindow); verify(mockActivity).isFinishing(); verifyNoMoreInteractions(mockActivity); }
@Config(sdk = Build.VERSION_CODES.JELLY_BEAN_MR1) @Test public void testFinishCallerDelayedForFinishingCallerOnJellyBeanMR1ApiLevel() { final Activity mockActivity = mock(TestActivity.class); final Window mockWindow = mock(Window.class); final View decorView = new FrameLayout(context) { @Override public boolean postDelayed(@NonNull final Runnable action, final long delayMillis) { waitFor(delayMillis); action.run(); return true; } }; when(mockWindow.getDecorView()).thenReturn(decorView); when(mockActivity.getWindow()).thenReturn(mockWindow); when(mockActivity.isFinishing()).thenReturn(true); when(mockActivity.isDestroyed()).thenReturn(false); final BaseNavigationalTransition navTransition = new TestTransition(); navTransition.finishCallerDelayed(mockActivity, 100); verify(mockActivity).getWindow(); verify(mockWindow).getDecorView(); verifyNoMoreInteractions(mockWindow); verify(mockActivity).isDestroyed(); verify(mockActivity).isFinishing(); verifyNoMoreInteractions(mockActivity); }
@Test public void testFinishCallerDelayedWithoutDecorView() { final Activity mockActivity = mock(TestActivity.class); final Window mockWindow = mock(Window.class); when(mockWindow.getDecorView()).thenReturn(null); when(mockActivity.getWindow()).thenReturn(mockWindow); final BaseNavigationalTransition navTransition = new TestTransition(); navTransition.finishCallerDelayed(mockActivity, 250); waitFor(250); verify(mockActivity).getWindow(); verifyNoMoreInteractions(mockActivity); verify(mockWindow).getDecorView(); verifyNoMoreInteractions(mockWindow); }