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
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b7eba11..44e4323 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1013,7 +1013,7 @@
                     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 @@
         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 @@
         beginDeferResume();
 
         try {
-            final WindowProcessController proc = app.getWindowProcessController();
             r.startFreezingScreenLocked(proc, 0);
 
             // schedule launch ticks to collect information about slow apps.
@@ -1415,15 +1414,15 @@
 
             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 @@
             }
 
             try {
-                if (app.thread == null) {
+                if (!proc.hasThread()) {
                     throw new RemoteException();
                 }
                 List<ResultInfo> results = null;
@@ -1468,50 +1467,29 @@
                 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 @@
                 // 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 @@
 
             } 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 @@
         }
     }
 
-    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
+                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);
+                    // 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, app, andResume, checkConfig);
+                realStartActivityLocked(r, wpc, andResume, checkConfig);
                 return;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception when starting activity "
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 2d27017..78d6108 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -5446,7 +5446,7 @@
         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).
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0eb535b..d12d6f8 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -28,6 +28,7 @@
 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.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 @@
         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 @@
      * 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();
     }
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index 792b66b..1743dde 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -37,6 +37,7 @@
 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 @@
         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);
diff --git a/services/core/java/com/android/server/am/WindowProcessListener.java b/services/core/java/com/android/server/am/WindowProcessListener.java
index 9cad6fe4..4a7e6e8 100644
--- a/services/core/java/com/android/server/am/WindowProcessListener.java
+++ b/services/core/java/com/android/server/am/WindowProcessListener.java
@@ -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 @@
     /** 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);
 }