summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManagerInternal.java26
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java82
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java87
-rw-r--r--services/core/java/com/android/server/am/ActivityTaskManagerService.java66
-rw-r--r--services/core/java/com/android/server/am/ProcessRecord.java54
-rw-r--r--services/core/java/com/android/server/am/WindowProcessController.java30
-rw-r--r--services/core/java/com/android/server/am/WindowProcessListener.java12
7 files changed, 249 insertions, 108 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index d00650d40d8f..50e618a577a2 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c27ec6f107f2..6a25cf13c6cf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -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) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b7eba1100bcf..2e36fc9385ba 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 @@ 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
+ 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 "
@@ -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) {
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 2d2701785d03..8ae5495cfa05 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -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);
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 0eb535b74d13..d12d6f8e8e6d 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.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();
}
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index 792b66be6dd9..1743ddeedd91 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 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);
diff --git a/services/core/java/com/android/server/am/WindowProcessListener.java b/services/core/java/com/android/server/am/WindowProcessListener.java
index 9cad6fe47563..4a7e6e8a38fe 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 @@ 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);
}