From b6d7695cf2e7cec5c7b24e1b09e1f7d8f1788cb7 Mon Sep 17 00:00:00 2001 From: Holly Jiuyu Sun Date: Wed, 11 Jan 2017 17:34:03 -0800 Subject: [PATCH] Change the default behavior when MCC/MNC changes. By default, we don't restart the activity when MCC/MNC changes even when they are not set in configChanges. If they want to restart, set mcc or mnc in the new attribute restartOnConfigChanges. Bug: 34258948 Test: Test in unit test(testGetActivityConfigChanges() in PackageParserTest.java) and on real device with changing the SIM card. Change-Id: Icd6899597c9b8f2e5706e74373a0280d19150092 --- api/current.txt | 1 + api/system-current.txt | 1 + api/test-current.txt | 1 + .../android/content/pm/PackageParser.java | 22 +++++++++- core/res/res/values/attrs_manifest.xml | 26 +++++++++++- core/res/res/values/public.xml | 1 + .../android/content/pm/PackageParserTest.java | 42 +++++++++++++++++++ 7 files changed, 91 insertions(+), 3 deletions(-) diff --git a/api/current.txt b/api/current.txt index b9cd7d0d35032..64a935f5f5c2b 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1052,6 +1052,7 @@ package android { field public static final int resizeable = 16843405; // 0x101028d field public static final int resizeableActivity = 16844022; // 0x10104f6 field public static final int resource = 16842789; // 0x1010025 + field public static final int restartOnConfigChanges = 16844105; // 0x1010549 field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 diff --git a/api/system-current.txt b/api/system-current.txt index 75b0a34a101c2..a1684d991313e 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1161,6 +1161,7 @@ package android { field public static final int resizeable = 16843405; // 0x101028d field public static final int resizeableActivity = 16844022; // 0x10104f6 field public static final int resource = 16842789; // 0x1010025 + field public static final int restartOnConfigChanges = 16844105; // 0x1010549 field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 diff --git a/api/test-current.txt b/api/test-current.txt index de8602216f0ea..750f064f7b98f 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1052,6 +1052,7 @@ package android { field public static final int resizeable = 16843405; // 0x101028d field public static final int resizeableActivity = 16844022; // 0x10104f6 field public static final int resource = 16842789; // 0x1010025 + field public static final int restartOnConfigChanges = 16844105; // 0x1010549 field public static final int restoreAnyVersion = 16843450; // 0x10102ba field public static final deprecated int restoreNeedsApplication = 16843421; // 0x101029d field public static final int restrictedAccountType = 16843733; // 0x10103d5 diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 083e4cc6676be..2fdc527208c03 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -179,6 +179,13 @@ public class PackageParser { private static final String TAG_PACKAGE = "package"; private static final String TAG_RESTRICT_UPDATE = "restrict-update"; + /** + * Bit mask of all the valid bits that can be set in restartOnConfigChanges. + * @hide + */ + private static final int RESTART_ON_CONFIG_CHANGES_MASK = + ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC; + // These are the tags supported by child packages private static final Set CHILD_PACKAGE_TAGS = new ArraySet<>(); static { @@ -3855,7 +3862,9 @@ public class PackageParser { a.info.maxRecents = sa.getInt( R.styleable.AndroidManifestActivity_maxRecents, ActivityManager.getDefaultAppRecentsLimitStatic()); - a.info.configChanges = sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0); + a.info.configChanges = getActivityConfigChanges( + sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0), + sa.getInt(R.styleable.AndroidManifestActivity_restartOnConfigChanges, 0)); a.info.softInputMode = sa.getInt( R.styleable.AndroidManifestActivity_windowSoftInputMode, 0); @@ -4083,6 +4092,17 @@ public class PackageParser { } } + /** + * @param configChanges The bit mask of configChanges fetched from AndroidManifest.xml. + * @param restartOnConfigChanges The bit mask restartOnConfigChanges fetched from + * AndroidManifest.xml. + * @hide Exposed for unit testing only. + */ + @TestApi + public static int getActivityConfigChanges(int configChanges, int restartOnConfigChanges) { + return configChanges | ((~restartOnConfigChanges) & RESTART_ON_CONFIG_CHANGES_MASK); + } + private void parseLayout(Resources res, AttributeSet attrs, Activity a) { TypedArray sw = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestLayout); diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index b9613949627cd..34e2f4fd59ed2 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -776,6 +776,21 @@ + + + + + + + + + updated the Mobile Country Code. By default from Android O, we + don't restart the activity even the app doesn't specify mcc in + configChanges. If the app wants to restart, specify mcc in + restartOnConfigChanges. --> + updated the Mobile Network Code. By default from Android O, we + don't restart the activity even the app doesn't specify mnc in + configChanges. If the app wants to restart, specify mnc in + restartOnConfigChanges. --> @@ -1917,6 +1938,7 @@ + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 064d31e84cca7..38c7f4d1bd703 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2785,6 +2785,7 @@ + diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java index 2a3c22c64ec2c..ca4141afae2d2 100644 --- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java +++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java @@ -215,4 +215,46 @@ public class PackageParserTest { // DEV: Released API 20 verifyComputeTargetSdkVersion(NEWER_VERSION, NEWER_PRE_RELEASE, true, -1); } + + /** + * Unit test for PackageParser.getActivityConfigChanges(). + * If the bit is 1 in the original configChanges, it is still 1 in the final configChanges. + * If the bit is 0 in the original configChanges and the bit is not set to 1 in + * restartOnConfigChanges, the bit is changed to 1 in the final configChanges by default. + */ + @Test + public void testGetActivityConfigChanges() { + // Not set in either configChanges or restartOnConfigChanges. + int configChanges = 0x0000; // 00000000. + int restartOnConfigChanges = 0x0000; // 00000000. + int finalConfigChanges = + PackageParser.getActivityConfigChanges(configChanges, restartOnConfigChanges); + assertEquals(0x0003, finalConfigChanges); // Should be 00000011. + + // Not set in configChanges, but set in restartOnConfigChanges. + configChanges = 0x0000; // 00000000. + restartOnConfigChanges = 0x0003; // 00000011. + finalConfigChanges = + PackageParser.getActivityConfigChanges(configChanges, restartOnConfigChanges); + assertEquals(0x0000, finalConfigChanges); // Should be 00000000. + + // Set in configChanges. + configChanges = 0x0003; // 00000011. + restartOnConfigChanges = 0X0000; // 00000000. + finalConfigChanges = + PackageParser.getActivityConfigChanges(configChanges, restartOnConfigChanges); + assertEquals(0x0003, finalConfigChanges); // Should be 00000011. + + restartOnConfigChanges = 0x0003; // 00000011. + finalConfigChanges = + PackageParser.getActivityConfigChanges(configChanges, restartOnConfigChanges); + assertEquals(0x0003, finalConfigChanges); // Should still be 00000011. + + // Other bit set in configChanges. + configChanges = 0x0080; // 10000000, orientation. + restartOnConfigChanges = 0x0000; // 00000000. + finalConfigChanges = + PackageParser.getActivityConfigChanges(configChanges, restartOnConfigChanges); + assertEquals(0x0083, finalConfigChanges); // Should be 10000011. + } }