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

Commit 2bfca138 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge changes Iefc9e02a,If30ab233,I75b71560

* changes:
  Move defer-process-config for cached process to client side
  Remove direct WM lock from WPC#onTopProcChanged
  Remove WM lock from simple conditions in oom-adj update
parents 680043ca e839c2ca
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -3144,12 +3144,25 @@ public final class ActivityThread extends ClientTransactionHandler {
        }
    }

    /**
     * Returns {@code true} if the {@link android.app.ActivityManager.ProcessState} of the current
     * process is cached.
     */
    @VisibleForTesting
    public boolean isCachedProcessState() {
        synchronized (mAppThread) {
            return mLastProcessState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
        }
    }

    @Override
    public void updateProcessState(int processState, boolean fromIpc) {
        final boolean wasCached;
        synchronized (mAppThread) {
            if (mLastProcessState == processState) {
                return;
            }
            wasCached = isCachedProcessState();
            mLastProcessState = processState;
            // Defer the top state for VM to avoid aggressive JIT compilation affecting activity
            // launch time.
@@ -3166,6 +3179,24 @@ public final class ActivityThread extends ClientTransactionHandler {
                        + (fromIpc ? " (from ipc" : ""));
            }
        }

        // Handle the pending configuration if the process state is changed from cached to
        // non-cached. Except the case where there is a launching activity because the
        // LaunchActivityItem will handle it.
        if (wasCached && !isCachedProcessState() && mNumLaunchingActivities.get() == 0) {
            final Configuration pendingConfig;
            synchronized (mResourcesManager) {
                pendingConfig = mPendingConfiguration;
            }
            if (pendingConfig == null) {
                return;
            }
            if (Looper.myLooper() == mH.getLooper()) {
                handleConfigurationChanged(pendingConfig);
            } else {
                sendMessage(H.CONFIGURATION_CHANGED, pendingConfig);
            }
        }
    }

    /** Update VM state based on ActivityManager.PROCESS_STATE_* constants. */
@@ -5687,6 +5718,12 @@ public final class ActivityThread extends ClientTransactionHandler {

    @Override
    public void handleConfigurationChanged(Configuration config) {
        if (isCachedProcessState()) {
            updatePendingConfiguration(config);
            // If the process is in a cached state, delay the handling until the process is no
            // longer cached.
            return;
        }
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
        mCurDefaultDisplayDpi = config.densityDpi;
        handleConfigurationChanged(config, null /* compat */);
+49 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.junit.Assert.assertTrue;

import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.IApplicationThread;
@@ -57,9 +58,9 @@ import android.util.MergedConfiguration;
import android.view.Display;
import android.view.View;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

@@ -541,6 +542,53 @@ public class ActivityThreadTest {
        });
    }

    @Test
    public void testHandleProcessConfigurationChanged_DependOnProcessState() {
        final ActivityThread activityThread = ActivityThread.currentActivityThread();
        final Configuration origConfig = activityThread.getConfiguration();
        final int newDpi = origConfig.densityDpi + 10;
        final Configuration newConfig = new Configuration(origConfig);
        newConfig.seq++;
        newConfig.densityDpi = newDpi;

        activityThread.updateProcessState(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY,
                false /* fromIPC */);

        applyProcessConfiguration(activityThread, newConfig);
        try {
            // In the cached state, the configuration is only set as pending and not applied.
            assertEquals(origConfig.densityDpi, activityThread.getConfiguration().densityDpi);
            assertTrue(activityThread.isCachedProcessState());
        } finally {
            // The foreground state is the default state of instrumentation.
            activityThread.updateProcessState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE,
                    false /* fromIPC */);
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        try {
            // The state becomes non-cached, the pending configuration should be applied.
            assertEquals(newConfig.densityDpi, activityThread.getConfiguration().densityDpi);
            assertFalse(activityThread.isCachedProcessState());
        } finally {
            // Restore to the original configuration.
            activityThread.getConfiguration().seq = origConfig.seq - 1;
            applyProcessConfiguration(activityThread, origConfig);
        }
    }

    private static void applyProcessConfiguration(ActivityThread thread, Configuration config) {
        final ClientTransaction clientTransaction = newTransaction(thread,
                null /* activityToken */);
        clientTransaction.addCallback(ConfigurationChangeItem.obtain(config));
        final IApplicationThread appThread = thread.getApplicationThread();
        try {
            appThread.scheduleTransaction(clientTransaction);
        } catch (Exception ignored) {
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
    }

    @Test
    public void testResumeAfterNewIntent() {
        final Activity activity = mActivityTestRule.launchActivity(new Intent());
+1 −3
Original line number Diff line number Diff line
@@ -800,9 +800,7 @@ class AppErrors {
        // with a home activity running in the process to prevent a repeatedly crashing app
        // from blocking the user to manually clear the list.
        final WindowProcessController proc = app.getWindowProcessController();
        final WindowProcessController homeProc = mService.mAtmInternal.getHomeProcess();
        if (proc == homeProc && proc.hasActivities()
                && (((ProcessRecord) homeProc.mOwner).info.flags & FLAG_SYSTEM) == 0) {
        if (proc.isHomeProcess() && proc.hasActivities() && (app.info.flags & FLAG_SYSTEM) == 0) {
            proc.clearPackagePreferredForHomeActivities();
        }

+1 −1
Original line number Diff line number Diff line
@@ -3561,7 +3561,7 @@ public final class ProcessList {
            int clientTargetSdk) {
        outInfo.pid = app.pid;
        outInfo.uid = app.info.uid;
        if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
        if (app.getWindowProcessController().isHeavyWeightProcess()) {
            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
        }
        if (app.isPersistent()) {
+4 −7
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ class ProcessRecord implements WindowProcessListener {
    long lastTopTime;           // The last time the process was in the TOP state or greater.
    boolean reportLowMemory;    // Set to true when waiting to report low mem
    boolean empty;              // Is this an empty background process?
    private volatile boolean mCached;    // Is this a cached process?
    private boolean mCached;    // Is this a cached process?
    String adjType;             // Debugging: primary thing impacting oom_adj.
    int adjTypeCode;            // Debugging: adj code to report to app.
    Object adjSource;           // Debugging: option dependent object.
@@ -794,10 +794,7 @@ class ProcessRecord implements WindowProcessListener {
    }

    void setCached(boolean cached) {
        if (mCached != cached) {
        mCached = cached;
            mWindowProcessController.onProcCachedStateChanged(cached);
        }
    }

    @Override
@@ -1850,8 +1847,8 @@ class ProcessRecord implements WindowProcessListener {

    boolean getCachedIsHeavyWeight() {
        if (mCachedIsHeavyWeight == VALUE_INVALID) {
            mCachedIsHeavyWeight = mService.mAtmInternal.isHeavyWeightProcess(
                    getWindowProcessController()) ? VALUE_TRUE : VALUE_FALSE;
            mCachedIsHeavyWeight = getWindowProcessController().isHeavyWeightProcess()
                    ? VALUE_TRUE : VALUE_FALSE;
        }
        return mCachedIsHeavyWeight == VALUE_TRUE;
    }
Loading