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

Commit 6805a5a5 authored by Wale Ogunwale's avatar Wale Ogunwale Committed by Android (Google) Code Review
Browse files

Merge changes Ia435aa81,If36c7d9c,I09311d30

* changes:
  Stopped starting and killing processes directly from ATMS (27/n)
  Removed direct calls to AMS.broadcastIntentLocked from ATMS (26/n)
  Removed references to ProcessRecord in ActivityStackSupervisor (25/n)
parents 5320e1fe 5c91870f
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -250,4 +250,30 @@ public abstract class ActivityManagerInternal {
    public abstract boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName,
            ApplicationInfo aInfo, String parentShortComponentName, Object parentProc,
            boolean aboveSystem, String reason);

    /**
     * Sends {@link android.content.Intent#ACTION_CONFIGURATION_CHANGED} with all the appropriate
     * flags.
     */
    public abstract void broadcastGlobalConfigurationChanged(int changes, boolean initLocale);

    /**
     * Sends {@link android.content.Intent#ACTION_CLOSE_SYSTEM_DIALOGS} with all the appropriate
     * flags.
     */
    public abstract void broadcastCloseSystemDialogs(String reason);

    /**
     * Kills all background processes, except those matching any of the specified properties.
     *
     * @param minTargetSdk the target SDK version at or above which to preserve processes,
     *                     or {@code -1} to ignore the target SDK
     * @param maxProcState the process state at or below which to preserve processes,
     *                     or {@code -1} to ignore the process state
     */
    public abstract void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState);

    /** Starts a given process. */
    public abstract void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, String hostingType, ComponentName hostingName);
}
+82 −0
Original line number Diff line number Diff line
@@ -20338,6 +20338,88 @@ public class ActivityManagerService extends IActivityManager.Stub
                    (WindowProcessController) parentProc, aboveSystem, reason);
        }
        @Override
        public void broadcastGlobalConfigurationChanged(int changes, boolean initLocale) {
            synchronized (ActivityManagerService.this) {
                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
                        | Intent.FLAG_RECEIVER_FOREGROUND
                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                        OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                        UserHandle.USER_ALL);
                if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                            | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
                    if (initLocale || !mProcessesReady) {
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    }
                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                            OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                            UserHandle.USER_ALL);
                }
                // Send a broadcast to PackageInstallers if the configuration change is interesting
                // for the purposes of installing additional splits.
                if (!initLocale && isSplitConfigurationChange(changes)) {
                    intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
                    intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
                    // Typically only app stores will have this permission.
                    String[] permissions =
                            new String[] { android.Manifest.permission.INSTALL_PACKAGES };
                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
                            permissions, OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                            UserHandle.USER_ALL);
                }
            }
        }
        /**
         * Returns true if this configuration change is interesting enough to send an
         * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
         */
        private boolean isSplitConfigurationChange(int configDiff) {
            return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
        }
        @Override
        public void broadcastCloseSystemDialogs(String reason) {
            synchronized (ActivityManagerService.this) {
                final Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
                if (reason != null) {
                    intent.putExtra("reason", reason);
                }
                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                        OP_NONE, null, false, false, -1, SYSTEM_UID, UserHandle.USER_ALL);
            }
        }
        @Override
        public void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
            synchronized (ActivityManagerService.this) {
                ActivityManagerService.this.killAllBackgroundProcessesExcept(
                        minTargetSdk, maxProcState);
            }
        }
        @Override
        public void startProcess(String processName, ApplicationInfo info,
                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
            synchronized (ActivityManagerService.this) {
                startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                        hostingType, hostingName, false /* allowWhileBooting */,
                        false /* isolated */, true /* keepIfLarge */);
            }
        }
    }
    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
+32 −55
Original line number Diff line number Diff line
@@ -1013,7 +1013,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            if (realStartActivityLocked(activity, (ProcessRecord) app.mOwner,
                            if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
@@ -1360,7 +1360,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return resolveActivity(intent, rInfo, startFlags, profilerInfo);
    }

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
    private boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!allPausedActivitiesComplete()) {
@@ -1379,7 +1379,6 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        beginDeferResume();

        try {
            final WindowProcessController proc = app.getWindowProcessController();
            r.startFreezingScreenLocked(proc, 0);

            // schedule launch ticks to collect information about slow apps.
@@ -1415,15 +1414,15 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D

            final int applicationInfoUid =
                    (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
            if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
            if ((r.userId != proc.mUserId) || (r.appInfo.uid != applicationInfoUid)) {
                Slog.wtf(TAG,
                        "User ID for activity changing for " + r
                                + " appInfo.uid=" + r.appInfo.uid
                                + " info.ai.uid=" + applicationInfoUid
                                + " old=" + r.app + " new=" + app);
                                + " old=" + r.app + " new=" + proc);
            }

            app.waitingToKill = null;
            proc.clearWaitingToKill();
            r.launchCount++;
            r.lastLaunchTime = SystemClock.uptimeMillis();

@@ -1442,7 +1441,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            }

            try {
                if (app.thread == null) {
                if (!proc.hasThread()) {
                    throw new RemoteException();
                }
                List<ResultInfo> results = null;
@@ -1468,50 +1467,29 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                r.forceNewConfig = false;
                mService.getAppWarningsLocked().onStartActivity(r);
                r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
                ProfilerInfo profilerInfo = null;
                if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
                    if (mService.mAm.mProfileProc == null || mService.mAm.mProfileProc == app) {
                        mService.mAm.mProfileProc = app;
                        ProfilerInfo profilerInfoSvc = mService.mAm.mProfilerInfo;
                        if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
                            if (profilerInfoSvc.profileFd != null) {
                                try {
                                    profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
                                } catch (IOException e) {
                                    profilerInfoSvc.closeFd();
                                }
                            }

                            profilerInfo = new ProfilerInfo(profilerInfoSvc);
                        }
                    }
                }
                ProfilerInfo profilerInfo = proc.onStartActivity(mService.mTopProcessState);

                app.hasShownUi = true;
                app.setPendingUiClean(true);
                app.forceProcessStateUpTo(mService.mTopProcessState);
                // Because we could be starting an Activity in the system process this may not go
                // across a Binder interface which would create a new Configuration. Consequently
                // we have to always create a new Configuration here.

                final MergedConfiguration mergedConfiguration = new MergedConfiguration(
                        app.getWindowProcessController().getConfiguration(),
                        r.getMergedOverrideConfiguration());
                        proc.getConfiguration(), r.getMergedOverrideConfiguration());
                r.setLastReportedConfiguration(mergedConfiguration);

                logIfTransactionTooLarge(r.intent, r.icicle);


                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.getReportedProcState(),
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        mService.isNextTransitionForward(), profilerInfo));

@@ -1527,12 +1505,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

                if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
                if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
                        && mService.mHasHeavyWeightFeature) {
                    // This may be a heavy-weight process! Note that the package manager will ensure
                    // that only activity can run in the main process of the .apk, which is the only
                    // thing that will be considered heavy-weight.
                    if (app.processName.equals(app.info.packageName)) {
                    if (proc.mName.equals(proc.mInfo.packageName)) {
                        if (mService.mHeavyWeightProcess != null
                                && mService.mHeavyWeightProcess != proc) {
                            Slog.w(TAG, "Starting new heavy weight process " + proc
@@ -1545,12 +1523,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D

            } catch (RemoteException e) {
                if (r.launchFailed) {
                    // This is the second time we failed -- finish activity
                    // and give up.
                    // This is the second time we failed -- finish activity and give up.
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString()
                            + ", giving up", e);
                    mService.mAm.appDiedLocked(app);
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied();
                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "2nd-crash", false);
                    return false;
@@ -1659,24 +1635,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        }
    }

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.mAm.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        if (app != null && app.thread != null) {
        if (wpc != null && wpc.hasThread()) {
            try {
                if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mAm.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                    // Don't add this if it is a platform component that is marked to run in
                    // multiple processes, because this is actually part of the framework so doesn't
                    // make sense to track as a separate apk in the process.
                    wpc.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode);
                }
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
@@ -1687,8 +1660,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
            // restart the application.
        }

        mService.mAm.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
        // Post message to start process to avoid possible deadlock of calling into AMS with the
        // ATMS lock held.
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                r.info.applicationInfo, true, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
    }

    void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
+13 −53
Original line number Diff line number Diff line
@@ -4670,14 +4670,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return kept;
    }

    /**
     * Returns true if this configuration change is interesting enough to send an
     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
     */
    private static boolean isSplitConfigurationChange(int configDiff) {
        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
    }

    /** Update default (global) configuration and notify listeners about changes. */
    private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
            boolean persistent, int userId, boolean deferResume) {
@@ -4777,38 +4769,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            app.onConfigurationChanged(configCopy);
        }

        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
                | Intent.FLAG_RECEIVER_FOREGROUND
                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
        mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                UserHandle.USER_ALL);
        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
            if (initLocale || !mAm.mProcessesReady) {
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            }
            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
                    UserHandle.USER_ALL);
        }

        // Send a broadcast to PackageInstallers if the configuration change is interesting
        // for the purposes of installing additional splits.
        if (!initLocale && isSplitConfigurationChange(changes)) {
            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);

            // Typically only app stores will have this permission.
            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
        }
        final Message msg = PooledLambda.obtainMessage(
                ActivityManagerInternal::broadcastGlobalConfigurationChanged,
                mAmInternal, changes, initLocale);
        mH.sendMessage(msg);

        // Override configuration of the default display duplicates global config, so we need to
        // update it also. This will also notify WindowManager about changes.
@@ -4877,8 +4841,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            if (isDensityChange && displayId == DEFAULT_DISPLAY) {
                mAppWarnings.onDensityChanged();

                mAm.killAllBackgroundProcessesExcept(N,
                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
                // Post message to start process to avoid possible deadlock of calling into AMS with
                // the ATMS lock held.
                final Message msg = PooledLambda.obtainMessage(
                        ActivityManagerInternal::killAllBackgroundProcessesExcept, mAmInternal,
                        N, ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
                mH.sendMessage(msg);
            }
        }

@@ -5446,7 +5414,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        return newInfo;
    }

    private WindowProcessController getProcessController(String processName, int uid) {
    WindowProcessController getProcessController(String processName, int uid) {
        if (uid == SYSTEM_UID) {
            // The system gets to run in any process. If there are multiple processes with the same
            // uid, just pick the first (this should never happen).
@@ -6247,20 +6215,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                            return;
                        }
                    }
                    Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                            | Intent.FLAG_RECEIVER_FOREGROUND);
                    if (reason != null) {
                        intent.putExtra("reason", reason);
                    }
                    mWindowManager.closeSystemDialogs(reason);

                    mStackSupervisor.closeSystemDialogsLocked();

                    mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
                            OP_NONE, null, false, false,
                            -1, SYSTEM_UID, UserHandle.USER_ALL);
                }
                // Call into AM outside the synchronized block.
                mAmInternal.broadcastCloseSystemDialogs(reason);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
+54 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.app.ActivityManager;
import android.app.ApplicationErrorReport;
import android.app.Dialog;
import android.app.IApplicationThread;
import android.app.ProfilerInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -60,6 +61,7 @@ import com.android.internal.os.ProcessCpuTracker;
import com.android.server.Watchdog;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -836,6 +838,13 @@ final class ProcessRecord implements WindowProcessListener {
        return null;
    }

    @Override
    public void addPackage(String pkg, long versionCode) {
        synchronized (mService) {
            addPackage(pkg, versionCode, mService.mProcessStats);
        }
    }

    /*
     *  Return true if package has been added false if not
     */
@@ -1176,10 +1185,55 @@ final class ProcessRecord implements WindowProcessListener {
     * Returns the total time (in milliseconds) spent executing in both user and system code.
     * Safe to call without lock held.
     */
    @Override
    public long getCpuTime() {
        return mService.mProcessCpuTracker.getCpuTimeForPid(pid);
    }

    @Override
    public void clearWaitingToKill() {
        synchronized (mService) {
            waitingToKill = null;
        }
    }

    @Override
    public ProfilerInfo onStartActivity(int topProcessState) {
        synchronized (mService) {
            ProfilerInfo profilerInfo = null;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == this) {
                    mService.mProfileProc = this;
                    final ProfilerInfo profilerInfoSvc = mService.mProfilerInfo;
                    if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
                        if (profilerInfoSvc.profileFd != null) {
                            try {
                                profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
                            } catch (IOException e) {
                                profilerInfoSvc.closeFd();
                            }
                        }

                        profilerInfo = new ProfilerInfo(profilerInfoSvc);
                    }
                }
            }

            hasShownUi = true;
            setPendingUiClean(true);
            forceProcessStateUpTo(topProcessState);

            return profilerInfo;
        }
    }

    @Override
    public void appDied() {
        synchronized (mService) {
            mService.appDiedLocked(this);
        }
    }

    public long getInputDispatchingTimeout() {
        return mWindowProcessController.getInputDispatchingTimeout();
    }
Loading