diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 14c58e744dacd..def1f457fb4ab 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -27,5 +27,15 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ "file_patterns": ["(/|^)ActivityThreadClientTest.java"],
+ "name": "FrameworksMockingCoreTests"
+ },
+ {
+ "file_patterns": ["(/|^)ActivityThreadTest.java"],
+ "name": "FrameworksCoreTests"
+ }
]
}
diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp
new file mode 100644
index 0000000000000..ae3ff8612eee8
--- /dev/null
+++ b/core/tests/mockingcoretests/Android.bp
@@ -0,0 +1,53 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+android_test {
+ name: "FrameworksMockingCoreTests",
+
+ srcs: [
+ "src/**/*.java",
+ ],
+
+ static_libs: [
+ "frameworks-base-testutils",
+ "services.core",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "mockito-target-extended-minus-junit4",
+ "platform-test-annotations",
+ "truth-prebuilt",
+ "testables",
+ "ub-uiautomator",
+ ],
+
+ libs: [
+ "android.test.base",
+ "android.test.mock",
+ "android.test.runner",
+ ],
+
+ // These are not normally accessible from apps so they must be explicitly included.
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+
+ platform_apis: true,
+ test_suites: ["device-tests"],
+
+ certificate: "platform",
+}
diff --git a/core/tests/mockingcoretests/AndroidManifest.xml b/core/tests/mockingcoretests/AndroidManifest.xml
new file mode 100644
index 0000000000000..b9ee0852366de
--- /dev/null
+++ b/core/tests/mockingcoretests/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
Build/Install/Run: + * atest FrameworksMockingCoreTests:android.app.activity.ActivityThreadClientTest + * + *
This test class is a part of Window Manager Service tests and specified in + * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}. + */ +@RunWith(AndroidJUnit4.class) +@MediumTest +public class ActivityThreadClientTest { + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnCreate() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + clientSession.launchActivity(r); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_CREATE, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnCreate_Finished() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + Activity activity = clientSession.launchActivity(r); + activity.finish(); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_CREATE, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnStart() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + clientSession.launchActivity(r); + clientSession.startActivity(r); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_START, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnStart_Finished() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + Activity activity = clientSession.launchActivity(r); + clientSession.startActivity(r); + activity.finish(); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_START, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnResume() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + clientSession.launchActivity(r); + clientSession.startActivity(r); + clientSession.resumeActivity(r); + assertEquals(ON_RESUME, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_START, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnPause() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + clientSession.launchActivity(r); + clientSession.startActivity(r); + clientSession.resumeActivity(r); + clientSession.pauseActivity(r); + assertEquals(ON_PAUSE, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_START, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testWindowVisibilityChange_OnStop() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + clientSession.launchActivity(r); + clientSession.startActivity(r); + clientSession.resumeActivity(r); + clientSession.pauseActivity(r); + clientSession.stopActivity(r); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.changeVisibility(r, true); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.changeVisibility(r, false); + assertEquals(ON_STOP, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testLifecycleAfterFinished_OnCreate() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + Activity activity = clientSession.launchActivity(r); + activity.finish(); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.startActivity(r); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.resumeActivity(r); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.pauseActivity(r); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.stopActivity(r); + assertEquals(ON_CREATE, r.getLifecycleState()); + + clientSession.destroyActivity(r); + assertEquals(ON_DESTROY, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testLifecycleAfterFinished_OnStart() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + Activity activity = clientSession.launchActivity(r); + clientSession.startActivity(r); + activity.finish(); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.resumeActivity(r); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.pauseActivity(r); + assertEquals(ON_START, r.getLifecycleState()); + + clientSession.stopActivity(r); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.destroyActivity(r); + assertEquals(ON_DESTROY, r.getLifecycleState()); + } + } + + @Test + @UiThreadTest + public void testLifecycleAfterFinished_OnResume() throws Exception { + try (ClientMockSession clientSession = new ClientMockSession()) { + ActivityClientRecord r = clientSession.stubActivityRecord(); + + Activity activity = clientSession.launchActivity(r); + clientSession.startActivity(r); + clientSession.resumeActivity(r); + activity.finish(); + assertEquals(ON_RESUME, r.getLifecycleState()); + + clientSession.pauseActivity(r); + assertEquals(ON_PAUSE, r.getLifecycleState()); + + clientSession.stopActivity(r); + assertEquals(ON_STOP, r.getLifecycleState()); + + clientSession.destroyActivity(r); + assertEquals(ON_DESTROY, r.getLifecycleState()); + } + } + + private class ClientMockSession implements AutoCloseable { + private MockitoSession mMockSession; + private ActivityThread mThread; + + private ClientMockSession() throws RemoteException { + mThread = ActivityThread.currentActivityThread(); + mMockSession = mockitoSession() + .strictness(Strictness.LENIENT) + .spyStatic(ActivityTaskManager.class) + .spyStatic(WindowManagerGlobal.class) + .startMocking(); + doReturn(Mockito.mock(WindowManagerGlobal.class)) + .when(WindowManagerGlobal::getInstance); + IActivityTaskManager mockAtm = Mockito.mock(IActivityTaskManager.class); + doReturn(mockAtm).when(ActivityTaskManager::getService); + when(mockAtm.finishActivity(any(), anyInt(), any(), anyInt())).thenReturn(true); + } + + private Activity launchActivity(ActivityClientRecord r) { + return mThread.handleLaunchActivity(r, null /* pendingActions */, + null /* customIntent */); + } + + private void startActivity(ActivityClientRecord r) { + mThread.handleStartActivity(r, null /* pendingActions */); + } + + private void resumeActivity(ActivityClientRecord r) { + mThread.handleResumeActivity(r.token, true /* finalStateRequest */, + true /* isForward */, "test"); + } + + private void pauseActivity(ActivityClientRecord r) { + mThread.handlePauseActivity(r.token, false /* finished */, + false /* userLeaving */, 0 /* configChanges */, null /* pendingActions */, + "test"); + } + + private void stopActivity(ActivityClientRecord r) { + mThread.handleStopActivity(r.token, false /* show */, 0 /* configChanges */, + new PendingTransactionActions(), false /* finalStateRequest */, "test"); + } + + private void destroyActivity(ActivityClientRecord r) { + mThread.handleDestroyActivity(r.token, true /* finishing */, 0 /* configChanges */, + false /* getNonConfigInstance */, "test"); + } + + private void changeVisibility(ActivityClientRecord r, boolean show) { + mThread.handleWindowVisibility(r.token, show); + } + + private ActivityClientRecord stubActivityRecord() { + ComponentName component = new ComponentName( + InstrumentationRegistry.getInstrumentation().getContext(), TestActivity.class); + ActivityInfo info = new ActivityInfo(); + info.packageName = component.getPackageName(); + info.name = component.getClassName(); + info.exported = true; + info.applicationInfo = new ApplicationInfo(); + info.applicationInfo.packageName = info.packageName; + info.applicationInfo.uid = UserHandle.myUserId(); + + return new ActivityClientRecord(new Binder(), Intent.makeMainActivity(component), + 0 /* ident */, info, new Configuration(), + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null /* referrer */, + null /* voiceInteractor */, null /* state */, null /* persistentState */, + null /* pendingResults */, null /* pendingNewIntents */, true /* isForward */, + null /* profilerInfo */, mThread /* client */); + } + + @Override + public void close() { + mMockSession.finishMocking(); + } + } + + // Test activity + public static class TestActivity extends Activity { + } +} diff --git a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java index e0d74e0908ee3..c9e3404e0f1a0 100644 --- a/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java +++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java @@ -34,6 +34,8 @@ import com.android.test.filters.SelectTest; public final class FrameworksTestsFilter extends SelectTest { private static final String[] SELECTED_TESTS = { + // Test specifications for FrameworksMockingCoreTests. + "android.app.activity.ActivityThreadClientTest", // Test specifications for FrameworksCoreTests. "android.app.servertransaction.", // all tests under the package. "android.view.DisplayCutoutTest",