1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package androidx.lifecycle; 18 19import static androidx.lifecycle.Lifecycle.Event.ON_CREATE; 20import static androidx.lifecycle.Lifecycle.Event.ON_DESTROY; 21import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE; 22import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; 23import static androidx.lifecycle.Lifecycle.Event.ON_START; 24import static androidx.lifecycle.Lifecycle.Event.ON_STOP; 25 26import static org.hamcrest.CoreMatchers.instanceOf; 27import static org.hamcrest.CoreMatchers.is; 28import static org.hamcrest.CoreMatchers.notNullValue; 29import static org.hamcrest.MatcherAssert.assertThat; 30 31import android.app.Instrumentation; 32import android.content.Intent; 33import android.support.test.InstrumentationRegistry; 34import android.support.test.filters.MediumTest; 35import android.support.test.rule.ActivityTestRule; 36 37import androidx.fragment.app.Fragment; 38import androidx.lifecycle.activity.FragmentLifecycleActivity; 39 40import org.junit.Before; 41import org.junit.Rule; 42import org.junit.Test; 43import org.junit.runner.RunWith; 44import org.junit.runners.Parameterized; 45 46import java.util.Arrays; 47import java.util.concurrent.TimeUnit; 48 49@MediumTest 50@RunWith(Parameterized.class) 51public class FragmentLifecycleInActivityTest { 52 53 private static final long TIMEOUT = 2; //sec 54 55 @Rule 56 public ActivityTestRule<FragmentLifecycleActivity> mActivityRule = 57 new ActivityTestRule<>(FragmentLifecycleActivity.class, false, false); 58 59 private Instrumentation mInstrumentation; 60 61 @SuppressWarnings("WeakerAccess") 62 @Parameterized.Parameter 63 public boolean mNested; 64 65 @Parameterized.Parameters(name = "nested_{0}") 66 public static Object[][] params() { 67 return new Object[][]{new Object[]{false}, new Object[]{true}}; 68 } 69 70 @Before 71 public void getInstrumentation() { 72 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 73 } 74 75 private void reset() { 76 mActivityRule.getActivity().resetEvents(); 77 } 78 79 @Test 80 public void testFullEvents() throws Throwable { 81 final FragmentLifecycleActivity activity = launchActivity(); 82 waitForIdle(); 83 assertEvents(ON_CREATE, ON_START, ON_RESUME); 84 reset(); 85 finishActivity(activity); 86 assertEvents(ON_PAUSE, ON_STOP, ON_DESTROY); 87 } 88 89 @Test 90 public void testStopStart() throws Throwable { 91 final FragmentLifecycleActivity activity = launchActivity(); 92 waitForIdle(); 93 assertEvents(ON_CREATE, ON_START, ON_RESUME); 94 reset(); 95 mActivityRule.runOnUiThread(new Runnable() { 96 @Override 97 public void run() { 98 mInstrumentation.callActivityOnPause(activity); 99 mInstrumentation.callActivityOnStop(activity); 100 } 101 }); 102 waitForIdle(); 103 assertEvents(ON_PAUSE, ON_STOP); 104 reset(); 105 mActivityRule.runOnUiThread(new Runnable() { 106 @Override 107 public void run() { 108 mInstrumentation.callActivityOnStart(activity); 109 mInstrumentation.callActivityOnResume(activity); 110 } 111 }); 112 waitForIdle(); 113 assertEvents(ON_START, ON_RESUME); 114 } 115 116 private FragmentLifecycleActivity launchActivity() throws Throwable { 117 Intent intent = FragmentLifecycleActivity.intentFor(mInstrumentation.getTargetContext(), 118 mNested); 119 final FragmentLifecycleActivity activity = mActivityRule.launchActivity(intent); 120 mActivityRule.runOnUiThread(new Runnable() { 121 @Override 122 public void run() { 123 Fragment main = activity.getSupportFragmentManager() 124 .findFragmentByTag(FragmentLifecycleActivity.MAIN_TAG); 125 assertThat("test sanity", main, notNullValue()); 126 Fragment nestedFragment = main.getChildFragmentManager() 127 .findFragmentByTag(FragmentLifecycleActivity.NESTED_TAG); 128 assertThat("test sanity", nestedFragment != null, is(mNested)); 129 } 130 }); 131 assertThat(activity.getObservedOwner(), instanceOf( 132 mNested ? FragmentLifecycleActivity.NestedFragment.class 133 : FragmentLifecycleActivity.MainFragment.class 134 )); 135 return activity; 136 } 137 138 private void waitForIdle() { 139 mInstrumentation.waitForIdleSync(); 140 } 141 142 private void finishActivity(final FragmentLifecycleActivity activity) 143 throws InterruptedException { 144 mInstrumentation.runOnMainSync(new Runnable() { 145 @Override 146 public void run() { 147 activity.finish(); 148 } 149 }); 150 assertThat(activity.awaitForDestruction(TIMEOUT, TimeUnit.SECONDS), is(true)); 151 } 152 153 private void assertEvents(Lifecycle.Event... events) { 154 assertThat(mActivityRule.getActivity().getLoggedEvents(), is(Arrays.asList(events))); 155 } 156} 157