Loading core/java/android/app/ActivityThread.java +13 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import static android.content.ContentResolver.DEPRECATE_DATA_COLUMNS; import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; Loading Loading @@ -4608,7 +4610,7 @@ public final class ActivityThread extends ClientTransactionHandler { private void onCoreSettingsChange() { if (updateDebugViewAttributeState()) { // request all activities to relaunch for the changes to take place relaunchAllActivities(); relaunchAllActivities(false /* preserveWindows */); } } Loading @@ -4625,10 +4627,13 @@ public final class ActivityThread extends ClientTransactionHandler { return previousState != View.sDebugViewAttributes; } private void relaunchAllActivities() { private void relaunchAllActivities(boolean preserveWindows) { for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { final Activity activity = entry.getValue().activity; if (!activity.mFinished) { final ActivityClientRecord r = entry.getValue(); if (!r.activity.mFinished) { if (preserveWindows && r.window != null) { r.mPreserveWindow = true; } scheduleRelaunchActivity(entry.getKey()); } } Loading Loading @@ -5461,7 +5466,8 @@ public final class ActivityThread extends ClientTransactionHandler { } } void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { @VisibleForTesting(visibility = PACKAGE) public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { // Updates triggered by package installation go through a package update // receiver. Here we try to capture ApplicationInfo changes that are // caused by other sources, such as overlays. That means we want to be as conservative Loading Loading @@ -5507,7 +5513,8 @@ public final class ActivityThread extends ClientTransactionHandler { newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1; handleConfigurationChanged(newConfig, null); relaunchAllActivities(); // Preserve windows to avoid black flickers when overlays change. relaunchAllActivities(true /* preserveWindows */); } static void freeTextLayoutCachesIfNeeded(int configDiff) { Loading core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.res.Configuration; import android.os.IBinder; import android.util.MergedConfiguration; import android.view.Display; import android.view.View; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; Loading Loading @@ -152,6 +153,34 @@ public class ActivityThreadTest { }); } @Test public void testHandleActivity_assetsChanged() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); final IBinder[] token = new IBinder[1]; final View[] decorView = new View[1]; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final ActivityThread activityThread = activity.getActivityThread(); token[0] = activity.getActivityToken(); decorView[0] = activity.getWindow().getDecorView(); // Relaunches all activities activityThread.handleApplicationInfoChanged(activity.getApplicationInfo()); }); final View[] newDecorView = new View[1]; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final ActivityThread activityThread = activity.getActivityThread(); final Activity newActivity = activityThread.getActivity(token[0]); newDecorView[0] = activity.getWindow().getDecorView(); }); assertEquals("Window must be preserved", decorView[0], newDecorView[0]); } @Test public void testHandleActivityConfigurationChanged_DropStaleConfigurations() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); Loading Loading
core/java/android/app/ActivityThread.java +13 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import static android.content.ContentResolver.DEPRECATE_DATA_COLUMNS; import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX; import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UnsupportedAppUsage; Loading Loading @@ -4608,7 +4610,7 @@ public final class ActivityThread extends ClientTransactionHandler { private void onCoreSettingsChange() { if (updateDebugViewAttributeState()) { // request all activities to relaunch for the changes to take place relaunchAllActivities(); relaunchAllActivities(false /* preserveWindows */); } } Loading @@ -4625,10 +4627,13 @@ public final class ActivityThread extends ClientTransactionHandler { return previousState != View.sDebugViewAttributes; } private void relaunchAllActivities() { private void relaunchAllActivities(boolean preserveWindows) { for (Map.Entry<IBinder, ActivityClientRecord> entry : mActivities.entrySet()) { final Activity activity = entry.getValue().activity; if (!activity.mFinished) { final ActivityClientRecord r = entry.getValue(); if (!r.activity.mFinished) { if (preserveWindows && r.window != null) { r.mPreserveWindow = true; } scheduleRelaunchActivity(entry.getKey()); } } Loading Loading @@ -5461,7 +5466,8 @@ public final class ActivityThread extends ClientTransactionHandler { } } void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { @VisibleForTesting(visibility = PACKAGE) public void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { // Updates triggered by package installation go through a package update // receiver. Here we try to capture ApplicationInfo changes that are // caused by other sources, such as overlays. That means we want to be as conservative Loading Loading @@ -5507,7 +5513,8 @@ public final class ActivityThread extends ClientTransactionHandler { newConfig.assetsSeq = (mConfiguration != null ? mConfiguration.assetsSeq : 0) + 1; handleConfigurationChanged(newConfig, null); relaunchAllActivities(); // Preserve windows to avoid black flickers when overlays change. relaunchAllActivities(true /* preserveWindows */); } static void freeTextLayoutCachesIfNeeded(int configDiff) { Loading
core/tests/coretests/src/android/app/activity/ActivityThreadTest.java +29 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.res.Configuration; import android.os.IBinder; import android.util.MergedConfiguration; import android.view.Display; import android.view.View; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; Loading Loading @@ -152,6 +153,34 @@ public class ActivityThreadTest { }); } @Test public void testHandleActivity_assetsChanged() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); final IBinder[] token = new IBinder[1]; final View[] decorView = new View[1]; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final ActivityThread activityThread = activity.getActivityThread(); token[0] = activity.getActivityToken(); decorView[0] = activity.getWindow().getDecorView(); // Relaunches all activities activityThread.handleApplicationInfoChanged(activity.getApplicationInfo()); }); final View[] newDecorView = new View[1]; InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { final ActivityThread activityThread = activity.getActivityThread(); final Activity newActivity = activityThread.getActivity(token[0]); newDecorView[0] = activity.getWindow().getDecorView(); }); assertEquals("Window must be preserved", decorView[0], newDecorView[0]); } @Test public void testHandleActivityConfigurationChanged_DropStaleConfigurations() { final TestActivity activity = mActivityTestRule.launchActivity(new Intent()); Loading