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

Commit 9c103022 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Removed references to ProcessRecord in ActivityStackSupervisor (25/n)

Once ActivityStackSupervisor is moved to WM package it will no longer have
access to ProcessRecord. This Cl fixes ActivityStackSupervisor to use
WindowProcessController before the move.

Bug: 80414790
Test: Existing tests pass
Change-Id: I09311d30d7a2615ed08cbce38d9d4419aa35e6e0
parent 03eb7e19
Loading
Loading
Loading
Loading
+26 −53
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 profilerInfo = proc.onStartActivity(mService.mTopProcessState);

                            profilerInfo = new ProfilerInfo(profilerInfoSvc);
                        }
                    }
                }

                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 "
+1 −1
Original line number Diff line number Diff line
@@ -5446,7 +5446,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).
+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();
    }
+30 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_N
import android.app.Activity;
import android.app.ActivityThread;
import android.app.IApplicationThread;
import android.app.ProfilerInfo;
import android.app.servertransaction.ConfigurationChangeItem;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -674,6 +675,35 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        mAtm.mH.sendMessage(m);
    }

    void clearWaitingToKill() {
        if (mListener == null) return;
        // Posting on handler so WM lock isn't held when we call into AM.
        final Message m = PooledLambda.obtainMessage(
                WindowProcessListener::clearWaitingToKill, mListener);
        mAtm.mH.sendMessage(m);
    }

    void addPackage(String pkg, long versionCode) {
        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
        if (mListener == null) return;
        mListener.addPackage(pkg, versionCode);
    }

    ProfilerInfo onStartActivity(int topProcessState) {
        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
        if (mListener == null) return null;
        return mListener.onStartActivity(topProcessState);
    }

    public void appDied() {
        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
        if (mListener == null) return;
        mListener.appDied();
    }

    @Override
    public void onConfigurationChanged(Configuration newGlobalConfig) {
        super.onConfigurationChanged(newGlobalConfig);
+12 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.am;

import android.app.ProfilerInfo;
import android.content.pm.ApplicationInfo;
import android.util.proto.ProtoOutputStream;

@@ -51,5 +52,16 @@ public interface WindowProcessListener {
    /** Returns the total time (in milliseconds) spent executing in both user and system code. */
    long getCpuTime();

    /** Clears the waiting to kill reason for this process. */
    void clearWaitingToKill();

    /** Adds the package to the process. */
    void addPackage(String pkg, long versionCode);

    /** Called when we are in the process on starting an activity. */
    ProfilerInfo onStartActivity(int topProcessState);

    /** App died :(...oh well */
    void appDied();
    void writeToProto(ProtoOutputStream proto, long fieldId);
}