diff options
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); } |