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

Commit 37fa423c authored by Riddle Hsu's avatar Riddle Hsu Committed by Automerger Merge Worker
Browse files

Merge changes Ibd113f4f,I09c2feff into tm-qpr-dev am: 9605ca61

parents ca663321 9605ca61
Loading
Loading
Loading
Loading
+0 −30
Original line number Diff line number Diff line
@@ -3410,26 +3410,12 @@ public final class ActivityThread extends ClientTransactionHandler
        }
    }

    /**
     * Returns {@code true} if the {@link android.app.ActivityManager.ProcessState} of the current
     * process is cached.
     */
    @Override
    @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.
@@ -3446,22 +3432,6 @@ 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 =
                    mConfigurationController.getPendingConfiguration(false /* clearPending */);
            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. */
+0 −2
Original line number Diff line number Diff line
@@ -32,8 +32,6 @@ interface ActivityThreadInternal {

    boolean isInDensityCompatMode();

    boolean isCachedProcessState();

    Application getApplication();

    ArrayList<ComponentCallbacks2> collectComponentCallbacks(boolean includeUiContexts);
+0 −6
Original line number Diff line number Diff line
@@ -124,12 +124,6 @@ class ConfigurationController {
     * @param config The new configuration.
     */
    void handleConfigurationChanged(@NonNull Configuration config) {
        if (mActivityThread.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");
        handleConfigurationChanged(config, null /* compat */);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+0 −48
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ 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;
@@ -570,53 +569,6 @@ 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());
+72 −35
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.wm;

import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
@@ -195,6 +196,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    /** Whether the process configuration is waiting to be dispatched to the process. */
    private boolean mHasPendingConfigurationChange;

    /** If the process state is in (<=) the cached state, then defer delivery of the config. */
    private static final int CACHED_CONFIG_PROC_STATE = PROCESS_STATE_CACHED_ACTIVITY;
    /** Whether {@link #mLastReportedConfiguration} is deferred by the cached state. */
    private volatile boolean mHasCachedConfiguration;

    /**
     * Registered {@link DisplayArea} as a listener to override config changes. {@code null} if not
     * registered.
@@ -316,8 +322,27 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return mCurProcState;
    }

    /**
     * Sets the computed process state from the oom adjustment calculation. This is frequently
     * called in activity manager's lock, so don't use window manager lock here.
     */
    @HotPath(caller = HotPath.OOM_ADJUSTMENT)
    public void setReportedProcState(int repProcState) {
        final int prevProcState = mRepProcState;
        mRepProcState = repProcState;

        // Deliver the cached config if the app changes from cached state to non-cached state.
        final IApplicationThread thread = mThread;
        if (prevProcState >= CACHED_CONFIG_PROC_STATE && repProcState < CACHED_CONFIG_PROC_STATE
                && thread != null && mHasCachedConfiguration) {
            final Configuration config;
            synchronized (mLastReportedConfiguration) {
                config = new Configuration(mLastReportedConfiguration);
            }
            // Schedule immediately to make sure the app component (e.g. receiver, service) can get
            // the latest configuration in their lifecycle callbacks (e.g. onReceive, onCreate).
            scheduleConfigurationChange(thread, config);
        }
    }

    int getReportedProcState() {
@@ -1328,12 +1353,22 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    @Override
    public void onConfigurationChanged(Configuration newGlobalConfig) {
        super.onConfigurationChanged(newGlobalConfig);
        updateConfiguration();
        final Configuration config = getConfiguration();
        if (mLastReportedConfiguration.equals(config)) {
            // Nothing changed.
            if (Build.IS_DEBUGGABLE && mHasImeService) {
                // TODO (b/135719017): Temporary log for debugging IME service.
                Slog.w(TAG_CONFIGURATION, "Current config: " + config
                        + " unchanged for IME proc " + mName);
            }
            return;
        }

    @Override
    public void onRequestedOverrideConfigurationChanged(Configuration overrideConfiguration) {
        super.onRequestedOverrideConfigurationChanged(overrideConfiguration);
        if (mPauseConfigurationDispatchCount > 0) {
            mHasPendingConfigurationChange = true;
            return;
        }
        dispatchConfiguration(config);
    }

    @Override
@@ -1359,58 +1394,57 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        resolvedConfig.seq = newParentConfig.seq;
    }

    private void updateConfiguration() {
        final Configuration config = getConfiguration();
        if (mLastReportedConfiguration.diff(config) == 0) {
            // Nothing changed.
    void dispatchConfiguration(Configuration config) {
        mHasPendingConfigurationChange = false;
        if (mThread == null) {
            if (Build.IS_DEBUGGABLE && mHasImeService) {
                // TODO (b/135719017): Temporary log for debugging IME service.
                Slog.w(TAG_CONFIGURATION, "Current config: " + config
                        + " unchanged for IME proc " + mName);
                Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
                        + ": no app thread");
            }
            return;
        }

        if (mPauseConfigurationDispatchCount > 0) {
            mHasPendingConfigurationChange = true;
        config.seq = mAtm.increaseConfigurationSeqLocked();
        setLastReportedConfiguration(config);

        // A cached process doesn't have running application components, so it is unnecessary to
        // notify the configuration change. The last-reported-configuration is still set because
        // setReportedProcState() should not write any fields that require WM lock.
        if (mRepProcState >= CACHED_CONFIG_PROC_STATE) {
            mHasCachedConfiguration = true;
            // Because there are 2 volatile accesses in setReportedProcState(): mRepProcState and
            // mHasCachedConfiguration, check again in case mRepProcState is changed but hasn't
            // read the change of mHasCachedConfiguration.
            if (mRepProcState >= CACHED_CONFIG_PROC_STATE) {
                return;
            }
        dispatchConfiguration(config);
        }

    void dispatchConfiguration(Configuration config) {
        mHasPendingConfigurationChange = false;
        if (mThread == null) {
            if (Build.IS_DEBUGGABLE && mHasImeService) {
                // TODO (b/135719017): Temporary log for debugging IME service.
                Slog.w(TAG_CONFIGURATION, "Unable to send config for IME proc " + mName
                        + ": no app thread");
            }
            return;
        scheduleConfigurationChange(mThread, config);
    }

    private void scheduleConfigurationChange(IApplicationThread thread, Configuration config) {
        ProtoLog.v(WM_DEBUG_CONFIGURATION, "Sending to proc %s new config %s", mName,
                config);
        if (Build.IS_DEBUGGABLE && mHasImeService) {
            // TODO (b/135719017): Temporary log for debugging IME service.
            Slog.v(TAG_CONFIGURATION, "Sending to IME proc " + mName + " new config " + config);
        }

        mHasCachedConfiguration = false;
        try {
            config.seq = mAtm.increaseConfigurationSeqLocked();
            mAtm.getLifecycleManager().scheduleTransaction(mThread,
            mAtm.getLifecycleManager().scheduleTransaction(thread,
                    ConfigurationChangeItem.obtain(config));
            setLastReportedConfiguration(config);
        } catch (Exception e) {
            Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
            Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change: " + mOwner, e);
        }
    }

    void setLastReportedConfiguration(Configuration config) {
        // Synchronize for the access from setReportedProcState().
        synchronized (mLastReportedConfiguration) {
            mLastReportedConfiguration.setTo(config);
        }

    Configuration getLastReportedConfiguration() {
        return mLastReportedConfiguration;
    }

    void pauseConfigurationDispatch() {
@@ -1461,6 +1495,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
            // config seq. This increment ensures that the client won't ignore the configuration.
            config.seq = mAtm.increaseConfigurationSeqLocked();
        }
        // LaunchActivityItem includes the latest process configuration.
        mHasCachedConfiguration = false;
        return config;
    }

@@ -1688,7 +1724,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        }
        pw.println(prefix + " Configuration=" + getConfiguration());
        pw.println(prefix + " OverrideConfiguration=" + getRequestedOverrideConfiguration());
        pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
        pw.println(prefix + " mLastReportedConfiguration=" + (mHasCachedConfiguration
                ? ("(cached) " + mLastReportedConfiguration) : mLastReportedConfiguration));

        final int stateFlags = mActivityStateFlags;
        if (stateFlags != ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER) {
Loading