summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/TEST_MAPPING10
-rw-r--r--core/tests/mockingcoretests/Android.bp53
-rw-r--r--core/tests/mockingcoretests/AndroidManifest.xml35
-rw-r--r--core/tests/mockingcoretests/AndroidTest.xml31
-rw-r--r--core/tests/mockingcoretests/README33
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java362
-rw-r--r--tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java2
7 files changed, 526 insertions, 0 deletions
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 14c58e744dac..def1f457fb4a 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 000000000000..ae3ff8612eee
--- /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 000000000000..b9ee0852366d
--- /dev/null
+++ b/core/tests/mockingcoretests/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ android:installLocation="internalOnly"
+ package="com.android.frameworks.mockingcoretests"
+ android:sharedUserId="com.android.uid.test">
+
+ <application android:supportsRtl="true" android:debuggable="true">
+ <uses-library android:name="android.test.runner" />
+
+ <activity android:name="android.app.activity.ActivityThreadClientTest$TestActivity"
+ android:exported="true">
+ </activity>
+
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.frameworks.mockingcoretests"
+ android:label="Frameworks Mocking Core Tests" />
+</manifest>
diff --git a/core/tests/mockingcoretests/AndroidTest.xml b/core/tests/mockingcoretests/AndroidTest.xml
new file mode 100644
index 000000000000..47aa41003336
--- /dev/null
+++ b/core/tests/mockingcoretests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+<configuration description="Runs Frameworks Mocking Core Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="FrameworksMockingCoreTests.apk" />
+ </target_preparer>
+ <option name="test-tag" value="FrameworksMockingCoreTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.frameworks.mockingcoretests" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/core/tests/mockingcoretests/README b/core/tests/mockingcoretests/README
new file mode 100644
index 000000000000..c0f65c29a8a4
--- /dev/null
+++ b/core/tests/mockingcoretests/README
@@ -0,0 +1,33 @@
+* 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.
+
+
+INTRODUCTION
+
+The Android platform core tests that require additional mocking capabilities and use Extended
+Mockito, such as the ability to stub static methods. ExtendedMockito is not fully compatible with
+regular Mockito library, so tests that use it have to be verified and adapted. For that reason a
+separate module is used instead of adding to FrameworksCoreTests.
+
+For more information about ExtendedMockito see documentation of
+com.android.dx.mockito.inline.extended.ExtendedMockito class.
+
+See ../coretests/README for more information on FrameworksCoreTests.
+
+
+INSTRUCTIONS
+
+To build, install and run:
+
+ atest FrameworksMockingCoreTests
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
new file mode 100644
index 000000000000..86d55ea4f5c2
--- /dev/null
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ */
+
+package android.app.activity;
+
+import static android.app.servertransaction.ActivityLifecycleItem.ON_CREATE;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_DESTROY;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_START;
+import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
+import android.app.ActivityThread.ActivityClientRecord;
+import android.app.IActivityTaskManager;
+import android.app.servertransaction.PendingTransactionActions;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.view.WindowManagerGlobal;
+
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+/**
+ * Test for verifying {@link android.app.ActivityThread} class.
+ *
+ * <p>Build/Install/Run:
+ * atest FrameworksMockingCoreTests:android.app.activity.ActivityThreadClientTest
+ *
+ * <p>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 e0d74e0908ee..c9e3404e0f1a 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",