Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33a43368 authored by Louis Chang's avatar Louis Chang
Browse files

Do not relaunch bg activities when application info changes

Update the configurations via ActivityTaskManager to prevent the
activities being relaunched while in background. Instead, the
activities will be relaunched after brought to front and being visible.

This also prevents all activities in the system being relaunched
at the same time.

For framework resource updates, the global configuration will be
updated.

For individual package overlay changes, new asset sequence would be
set to the activity's requested configurations to ensure the activity
will be relaunch once visible. The requested asset sequence will be
reset if its parent has a newer asset sequence.

Bug: 185301309
Test: update app info via shell command while activity in background
Test: atest ResourcesLoaderValuesTest
Test: atest RoleManagerTest#requestRoleAndAllowThenIsRoleHolder
Change-Id: Ic7f13b768fb575d6301f05f7fda71b15d1ccf312
parent 8c87ff6a
Loading
Loading
Loading
Loading
+1 −15
Original line number Diff line number Diff line
@@ -5613,7 +5613,7 @@ public final class ActivityThread extends ClientTransactionHandler
    }

    /** Performs the activity relaunch locally vs. requesting from system-server. */
    private void handleRelaunchActivityLocally(IBinder token) {
    public void handleRelaunchActivityLocally(IBinder token) {
        final ActivityClientRecord r = mActivities.get(token);
        if (r == null) {
            Log.w(TAG, "Activity to relaunch no longer exists");
@@ -5977,20 +5977,6 @@ public final class ActivityThread extends ClientTransactionHandler
            // Update all affected Resources objects to use new ResourcesImpl
            mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs);
        }

        ApplicationPackageManager.configurationChanged();

        // Trigger a regular Configuration change event, only with a different assetsSeq number
        // so that we actually call through to all components.
        // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to
        // store configurations per-process.
        final Configuration config = mConfigurationController.getConfiguration();
        Configuration newConfig = new Configuration();
        newConfig.assetsSeq = (config != null ? config.assetsSeq : 0) + 1;
        mConfigurationController.handleConfigurationChanged(newConfig, null /* compat */);

        // Preserve windows to avoid black flickers when overlays change.
        relaunchAllActivities(true /* preserveWindows */, "handleApplicationInfoChanged");
    }

    /**
+0 −9
Original line number Diff line number Diff line
@@ -184,15 +184,6 @@ public class ActivityThreadTest {
        });
    }

    @Test
    public void testHandleActivity_assetsChanged() {
        relaunchActivityAndAssertPreserveWindow(activity -> {
            // Relaunches all activities.
            activity.getActivityThread().handleApplicationInfoChanged(
                    activity.getApplicationInfo());
        });
    }

    @Test
    public void testRecreateActivity() {
        relaunchActivityAndAssertPreserveWindow(Activity::recreate);
+6 −0
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.WindowManagerService;
import com.android.server.wm.WindowProcessController;

import dalvik.system.VMRuntime;

@@ -4615,6 +4616,7 @@ public final class ProcessList {
    @GuardedBy(anyOf = {"mService", "mProcLock"})
    void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId,
            boolean updateFrameworkRes) {
        final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>();
        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
            final ProcessRecord app = mLruProcesses.get(i);
            if (app.getThread() == null) {
@@ -4635,6 +4637,7 @@ public final class ProcessList {
                            if (ai.packageName.equals(app.info.packageName)) {
                                app.info = ai;
                            }
                            targetProcesses.add(app.getWindowProcessController());
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
@@ -4643,6 +4646,9 @@ public final class ProcessList {
                }
            });
        }

        mService.mActivityTaskManager.updateAssetConfiguration(
                updateFrameworkRes ? null : targetProcesses);
    }

    @GuardedBy("mService")
+6 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -6838,6 +6839,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

    @Override
    void resolveOverrideConfiguration(Configuration newParentConfiguration) {
        final Configuration requestedOverrideConfig = getRequestedOverrideConfiguration();
        if (requestedOverrideConfig.assetsSeq != ASSETS_SEQ_UNDEFINED
                && newParentConfiguration.assetsSeq > requestedOverrideConfig.assetsSeq) {
            requestedOverrideConfig.assetsSeq = ASSETS_SEQ_UNDEFINED;
        }
        super.resolveOverrideConfiguration(newParentConfiguration);
        final Configuration resolvedConfig = getResolvedOverrideConfiguration();
        if (isFixedRotationTransforming()) {
+33 −0
Original line number Diff line number Diff line
@@ -472,6 +472,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

    /** Current sequencing integer of the configuration, for skipping old configurations. */
    private int mConfigurationSeq;

    /** Current sequencing integer of the asset changes, for skipping old resources overlays. */
    private int mGlobalAssetsSeq;

    // To cache the list of supported system locales
    private String[] mSupportedSystemLocales = null;

@@ -4079,6 +4083,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return changes;
    }

    private int increaseAssetConfigurationSeq() {
        mGlobalAssetsSeq = Math.max(++mGlobalAssetsSeq, 1);
        return mGlobalAssetsSeq;
    }

    /**
     * Update the asset configuration and increase the assets sequence number.
     * @param processes the processes that needs to update the asset configuration, if none
     *                  updates the global configuration for all processes.
     */
    public void updateAssetConfiguration(List<WindowProcessController> processes) {
        synchronized (mGlobalLock) {
            final int assetSeq = increaseAssetConfigurationSeq();

            // Update the global configuration if the no target processes
            if (processes == null) {
                Configuration newConfig = new Configuration();
                newConfig.assetsSeq = assetSeq;
                updateConfiguration(newConfig);
                return;
            }

            for (int i = processes.size() - 1; i >= 0; i--) {
                final WindowProcessController wpc = processes.get(i);
                wpc.updateAssetConfiguration(assetSeq);
            }
        }
    }

    void startLaunchPowerMode(@PowerModeReason int reason) {
        if (mPowerManagerInternal == null) return;
        mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
Loading