cts: test config changes
Check that app either gets relaunched if it doesn't handle the change,
or receives onConfigurationChanged().
bug: 29367672
Change-Id: I370b82a3315a04939e10a90d04f8292d9738737d
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 809f8d7..6e7371c 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -46,7 +46,7 @@
/>
<activity android:name=".NoRelaunchActivity"
android:resizeableActivity="true"
- android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+ android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|fontScale"
android:exported="true"
android:taskAffinity="nobody.but.NoRelaunchActivity"
/>
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
new file mode 100644
index 0000000..e5a121d
--- /dev/null
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2016 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.server.cts;
+
+public class ActivityManagerConfigChangeTests extends ActivityManagerTestBase {
+
+ private static final String TEST_ACTIVITY_NAME = "TestActivity";
+ private static final String NO_RELAUNCH_ACTIVITY_NAME = "NoRelaunchActivity";
+
+ public void testRotation90Relaunch() throws Exception{
+ // Should relaunch on every rotation and receive no onConfigurationChanged()
+ testRotation(TEST_ACTIVITY_NAME, 1, 1, 0);
+ }
+
+ public void testRotation90NoRelaunch() throws Exception {
+ // Should receive onConfigurationChanged() on every rotation and no relaunch
+ testRotation(NO_RELAUNCH_ACTIVITY_NAME, 1, 0, 1);
+ }
+
+ public void testRotation180Relaunch() throws Exception {
+ // Should receive nothing
+ testRotation(TEST_ACTIVITY_NAME, 2, 0, 0);
+ }
+
+ public void testRotation180NoRelaunch() throws Exception {
+ // Should receive nothing
+ testRotation(NO_RELAUNCH_ACTIVITY_NAME, 2, 0, 0);
+ }
+
+ public void testChangeFontScaleRelaunch() throws Exception {
+ // Should relaunch and receive no onConfigurationChanged()
+ testChangeFontScale(TEST_ACTIVITY_NAME, true);
+ }
+
+ public void testChangeFontScaleNoRelaunch() throws Exception {
+ // Should receive onConfigurationChanged() and no relaunch
+ testChangeFontScale(NO_RELAUNCH_ACTIVITY_NAME, false);
+ }
+
+ private void testRotation(
+ String activityName, int rotationStep, int numRelaunch, int numConfigChange)
+ throws Exception {
+ executeShellCommand(getAmStartCmd(activityName));
+
+ final String[] waitForActivitiesVisible = new String[] {activityName};
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+ mAmWmState.assertContainsStack(
+ "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+
+ setDeviceRotation(4 - rotationStep);
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+
+ for (int rotation = 0; rotation < 4; rotation += rotationStep) {
+ clearLogcat();
+ setDeviceRotation(rotation);
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+ assertRelaunchOrConfigChanged(activityName, numRelaunch, numConfigChange);
+ }
+ }
+
+ private void testChangeFontScale(
+ String activityName, boolean relaunch) throws Exception {
+ executeShellCommand(getAmStartCmd(activityName));
+ final String[] waitForActivitiesVisible = new String[] {activityName};
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+ mAmWmState.assertContainsStack(
+ "Must contain fullscreen stack.", FULLSCREEN_WORKSPACE_STACK_ID);
+
+ setFontScale(1.0f);
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+
+ for (float fontScale = 0.85f; fontScale <= 1.3f; fontScale += 0.15f) {
+ clearLogcat();
+ setFontScale(fontScale);
+ mAmWmState.computeState(mDevice, waitForActivitiesVisible);
+ assertRelaunchOrConfigChanged(activityName, relaunch ? 1 : 0, relaunch ? 0 : 1);
+ }
+ }
+}
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
index 0100102..6891510 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerTestBase.java
@@ -99,6 +99,7 @@
private int mInitialAccelerometerRotation;
private int mUserRotation;
+ private float mFontScale;
@Override
protected void setUp() throws Exception {
@@ -114,6 +115,7 @@
// Store rotation settings.
mInitialAccelerometerRotation = getAccelerometerRotation();
mUserRotation = getUserRotation();
+ mFontScale = getFontScale();
}
@Override
@@ -125,6 +127,7 @@
// Restore rotation settings to the state they were before test.
setAccelerometerRotation(mInitialAccelerometerRotation);
setUserRotation(mUserRotation);
+ setFontScale(mFontScale);
// Remove special stacks.
executeShellCommand(AM_REMOVE_STACK + PINNED_STACK_ID);
executeShellCommand(AM_REMOVE_STACK + DOCKED_STACK_ID);
@@ -319,6 +322,22 @@
}
}
+ protected void setFontScale(float fontScale) throws DeviceNotAvailableException {
+ if (fontScale == 0.0f) {
+ runCommandAndPrintOutput(
+ "settings delete system font_scale");
+ } else {
+ runCommandAndPrintOutput(
+ "settings put system font_scale " + fontScale);
+ }
+ }
+
+ protected float getFontScale() throws DeviceNotAvailableException {
+ final String fontScale =
+ runCommandAndPrintOutput("settings get system font_scale").trim();
+ return Float.parseFloat(fontScale);
+ }
+
protected String runCommandAndPrintOutput(String command) throws DeviceNotAvailableException {
final String output = executeShellCommand(command);
log(output);
@@ -359,6 +378,23 @@
}
}
+ protected void assertRelaunchOrConfigChanged(
+ String activityName, int numRelaunch, int numConfigChange)
+ throws DeviceNotAvailableException {
+ final ActivityLifecycleCounts lifecycleCounts = new ActivityLifecycleCounts(activityName);
+
+ if (lifecycleCounts.mDestroyCount != numRelaunch) {
+ fail(activityName + " has been destroyed " + lifecycleCounts.mDestroyCount
+ + " time(s), expecting " + numRelaunch);
+ } else if (lifecycleCounts.mCreateCount != numRelaunch) {
+ fail(activityName + " has been (re)created " + lifecycleCounts.mCreateCount
+ + " time(s), expecting " + numRelaunch);
+ } else if (lifecycleCounts.mConfigurationChangedCount != numConfigChange) {
+ fail(activityName + " has received " + lifecycleCounts.mConfigurationChangedCount
+ + " onConfigurationChanged() calls, expecting " + numConfigChange);
+ }
+ }
+
private String[] getDeviceLogsForActivity(String activityName)
throws DeviceNotAvailableException {
return mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", activityName + ":I", "*:S")