diff options
62 files changed, 1729 insertions, 1063 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 2fdb715087de..e5cfe847e2e2 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -32,6 +32,7 @@ import android.view.RemoteAnimationAdapter; import com.android.internal.app.IVoiceInteractor; +import java.util.ArrayList; import java.util.List; /** @@ -204,4 +205,12 @@ public abstract class ActivityManagerInternal { /** Closes all system dialogs. */ public abstract void closeSystemDialogs(String reason); + + /** Kill the processes in the list due to their tasks been removed. */ + public abstract void killProcessesForRemovedTask(ArrayList<Object> procsToKill); + + /** + * Returns {@code true} if {@code uid} is running an activity from {@code packageName}. + */ + public abstract boolean hasRunningActivity(int uid, @Nullable String packageName); } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 43657602cd11..376d16bf1476 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -20,7 +20,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS; - import static com.android.internal.util.FunctionalUtils.ignoreRemoteException; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; @@ -30,8 +29,6 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AlertDialog; import android.app.AppOpsManager; import android.app.PendingIntent; @@ -112,10 +109,9 @@ import com.android.internal.util.DumpUtils; import com.android.internal.util.IntPair; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.LocalServices; +import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.WindowManagerInternal; -import libcore.util.EmptyArray; - import org.xmlpull.v1.XmlPullParserException; import java.io.FileDescriptor; @@ -134,6 +130,8 @@ import java.util.Set; import java.util.function.Consumer; import java.util.function.IntSupplier; +import libcore.util.EmptyArray; + /** * This class is instantiated by the system as a system level service and can be * accessed only by the system. The task of this service is to be a centralized diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index a2dc986424dd..4206d9a43ae2 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -28,7 +28,6 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.IActivityManager; import android.app.IActivityTaskManager; @@ -83,6 +82,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.server.LocalServices; import com.android.server.autofill.AutofillManagerService.AutofillCompatState; import com.android.server.autofill.ui.AutoFillUI; +import com.android.server.wm.ActivityTaskManagerInternal; import java.io.PrintWriter; import java.util.ArrayList; @@ -534,7 +534,7 @@ final class AutofillManagerServiceImpl { } catch (NameNotFoundException e) { throw new SecurityException("Could not verify UID for " + componentName); } - if (callingUid != packageUid && !LocalServices.getService(ActivityTaskManagerInternal.class) + if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class) .hasRunningActivity(callingUid, packageName)) { final String[] packages = pm.getPackagesForUid(callingUid); final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid; diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 48f27d8aa7bc..18255c5c39d4 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -16,8 +16,6 @@ package com.android.server.autofill; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES; import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST; import static android.service.autofill.FillRequest.INVALID_REQUEST_ID; @@ -33,6 +31,8 @@ import static com.android.server.autofill.Helper.sPartitionMaxCount; import static com.android.server.autofill.Helper.sVerbose; import static com.android.server.autofill.Helper.toArray; import static com.android.server.autofill.ViewState.STATE_RESTARTED_SESSION; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import android.annotation.NonNull; import android.annotation.Nullable; diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 4e700d7c985d..a34c2b93e3bf 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -19,7 +19,6 @@ package com.android.server; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AlarmManager; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -31,15 +30,15 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.database.ContentObserver; import android.hardware.Sensor; -import android.hardware.SensorManager; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.hardware.TriggerEvent; import android.hardware.TriggerEventListener; -import android.location.LocationRequest; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; +import android.location.LocationRequest; import android.net.ConnectivityManager; import android.net.INetworkPolicyManager; import android.net.NetworkInfo; @@ -86,6 +85,7 @@ import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; import com.android.server.am.BatteryStatsService; import com.android.server.net.NetworkPolicyManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index d025a87fa817..92005d249268 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -24,23 +24,18 @@ import static android.os.storage.OnObbStateChangeListener.ERROR_NOT_MOUNTED; import static android.os.storage.OnObbStateChangeListener.ERROR_PERMISSION_DENIED; import static android.os.storage.OnObbStateChangeListener.MOUNTED; import static android.os.storage.OnObbStateChangeListener.UNMOUNTED; - import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; import static com.android.internal.util.XmlUtils.readStringAttribute; import static com.android.internal.util.XmlUtils.writeIntAttribute; import static com.android.internal.util.XmlUtils.writeLongAttribute; import static com.android.internal.util.XmlUtils.writeStringAttribute; - import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; -import android.app.ActivityTaskManagerInternal.ScreenObserver; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.KeyguardManager; @@ -126,9 +121,8 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; import com.android.server.pm.PackageManagerService; import com.android.server.storage.AppFuseBridge; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; +import com.android.server.wm.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -164,6 +158,9 @@ import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; +import libcore.io.IoUtils; +import libcore.util.EmptyArray; + /** * Service responsible for various storage media. Connects to {@code vold} to * watch for and manage dynamically added storage, such as SD cards and USB mass diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 652bc6a7b0fe..f7cd5adc7925 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -1389,7 +1389,7 @@ public final class ActiveServices { private boolean updateServiceClientActivitiesLocked(ProcessRecord proc, ConnectionRecord modCr, boolean updateLru) { if (modCr != null && modCr.binding.client != null) { - if (modCr.binding.client.activities.size() <= 0) { + if (!modCr.binding.client.hasActivities()) { // This connection is from a client without activities, so adding // and removing is not interesting. return false; @@ -1407,7 +1407,7 @@ public final class ActiveServices { // Binding to ourself is not interesting. continue; } - if (cr.binding.client.activities.size() > 0) { + if (cr.binding.client.hasActivities()) { anyClientActivities = true; break; } @@ -2081,7 +2081,7 @@ public final class ActiveServices { bumpServiceExecutingLocked(r, execInFg, "bind"); r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, - r.app.repProcState); + r.app.getReportedProcState()); if (!rebind) { i.requested = true; } @@ -2463,7 +2463,7 @@ public final class ActiveServices { app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), - app.repProcState); + app.getReportedProcState()); r.postNotification(); created = true; } catch (DeadObjectException e) { @@ -3050,7 +3050,7 @@ public final class ActiveServices { } } if (finishing) { - if (r.app != null && !r.app.persistent) { + if (r.app != null && !r.app.isPersistent()) { r.app.services.remove(r); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); @@ -3140,7 +3140,7 @@ public final class ActiveServices { && (filterByClasses == null || filterByClasses.contains(service.name.getClassName()))); if (sameComponent - && (service.app == null || evenPersistent || !service.app.persistent)) { + && (service.app == null || evenPersistent || !service.app.isPersistent())) { if (!doit) { return true; } @@ -3148,7 +3148,7 @@ public final class ActiveServices { Slog.i(TAG, " Force stopping service " + service); if (service.app != null) { service.app.removed = killProcess; - if (!service.app.persistent) { + if (!service.app.isPersistent()) { service.app.services.remove(service); if (service.whitelistManager) { updateWhitelistManagerLocked(service.app); @@ -3302,7 +3302,7 @@ public final class ActiveServices { synchronized (sr.stats.getBatteryStats()) { sr.stats.stopLaunchedLocked(); } - if (sr.app != app && sr.app != null && !sr.app.persistent) { + if (sr.app != app && sr.app != null && !sr.app.isPersistent()) { sr.app.services.remove(sr); } sr.app = null; @@ -3347,7 +3347,7 @@ public final class ActiveServices { continue; } // XXX turned off for now until we have more time to get a better policy. - if (false && proc != null && !proc.persistent && proc.thread != null + if (false && proc != null && !proc.isPersistent() && proc.thread != null && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { proc.kill("bound to service " + sr.name.flattenToShortString() @@ -3365,7 +3365,7 @@ public final class ActiveServices { // Unless the process is persistent, this process record is going away, // so make sure the service is cleaned out of it. - if (!app.persistent) { + if (!app.isPersistent()) { app.services.removeAt(i); } @@ -3475,7 +3475,7 @@ public final class ActiveServices { if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) { info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; } - if (r.app != null && r.app.persistent) { + if (r.app != null && r.app.isPersistent()) { info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; } diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index 5608f97aa3e5..9f9fe4c9d13a 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -30,28 +30,29 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.FLAG_PRIVATE; import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT; +import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER; +import static com.android.server.am.ActivityDisplayProto.ID; +import static com.android.server.am.ActivityDisplayProto.STACKS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER; -import static com.android.server.am.ActivityDisplayProto.STACKS; -import static com.android.server.am.ActivityDisplayProto.ID; import android.annotation.Nullable; import android.app.ActivityOptions; -import android.app.ActivityTaskManagerInternal; import android.app.WindowConfiguration; import android.graphics.Point; import android.util.IntArray; import android.util.Slog; import android.util.proto.ProtoOutputStream; import android.view.Display; + import com.android.internal.annotations.VisibleForTesting; +import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ConfigurationContainer; import com.android.server.wm.DisplayWindowController; - import com.android.server.wm.WindowContainerListener; + import java.io.PrintWriter; import java.util.ArrayList; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1c61f300e2eb..70901d0e1d12 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -22,6 +22,8 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.REMOVE_TASKS; +import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; +import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityThread.PROC_START_SEQ_IDENT; @@ -30,10 +32,6 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; -import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; -import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; -import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; -import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.GET_PROVIDERS; import static android.content.pm.PackageManager.MATCH_ANY_USER; import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING; @@ -42,10 +40,8 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode; import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground; -import static android.os.Build.VERSION_CODES.N; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; @@ -67,7 +63,6 @@ import static android.os.Process.SCHED_OTHER; import static android.os.Process.SCHED_RESET_ON_FORK; import static android.os.Process.SE_UID; import static android.os.Process.SHELL_UID; -import static android.os.Process.SIGNAL_QUIT; import static android.os.Process.SIGNAL_USR1; import static android.os.Process.SYSTEM_UID; import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE; @@ -94,16 +89,12 @@ import static android.os.Process.zygoteProcess; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; import static android.provider.Settings.Global.DEBUG_APP; -import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; -import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; -import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS; import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER; import static android.provider.Settings.System.FONT_SCALE; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.Display.INVALID_DISPLAY; import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; @@ -141,8 +132,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; @@ -153,18 +142,15 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION; -import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; -import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.hasMemcg; +import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -177,14 +163,9 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; -import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; -import android.app.ActivityTaskManagerInternal.ScreenObserver; -import android.app.ActivityTaskManagerInternal.SleepToken; import android.app.ActivityManagerProto; import android.app.ActivityOptions; -import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.AlertDialog; import android.app.AppGlobals; @@ -217,7 +198,6 @@ import android.app.ProfilerInfo; import android.app.WindowConfiguration.ActivityType; import android.app.WindowConfiguration.WindowingMode; import android.app.backup.IBackupManager; -import android.app.servertransaction.ConfigurationChangeItem; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; @@ -272,7 +252,6 @@ import android.os.Debug; import android.os.DropBoxManager; import android.os.Environment; import android.os.FactoryTest; -import android.os.FileObserver; import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; @@ -280,7 +259,6 @@ import android.os.IDeviceIdentifiersPolicyService; import android.os.IPermissionController; import android.os.IProcessInfoService; import android.os.IProgressListener; -import android.os.LocaleList; import android.os.Looper; import android.os.Message; import android.os.Parcel; @@ -311,7 +289,6 @@ import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.text.format.DateUtils; -import android.text.format.Time; import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; @@ -338,6 +315,9 @@ import android.view.View; import android.view.WindowManager; import android.view.autofill.AutofillManagerInternal; +import com.google.android.collect.Lists; +import com.google.android.collect.Maps; + import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -382,17 +362,17 @@ import com.android.server.SystemService; import com.android.server.SystemServiceManager; import com.android.server.ThreadPriorityBooster; import com.android.server.Watchdog; -import com.android.server.am.ActivityStack.ActivityState; -import com.android.server.am.MemoryStatUtil.MemoryStat; -import com.android.server.am.ActivityManagerServiceProto; import com.android.server.am.ActivityManagerServiceDumpActivitiesProto; import com.android.server.am.ActivityManagerServiceDumpBroadcastsProto; import com.android.server.am.ActivityManagerServiceDumpProcessesProto; import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto; import com.android.server.am.ActivityManagerServiceDumpServicesProto; +import com.android.server.am.ActivityManagerServiceProto; +import com.android.server.am.ActivityStack.ActivityState; import com.android.server.am.GrantUriProto; import com.android.server.am.ImportanceTokenProto; import com.android.server.am.MemInfoDumpProto; +import com.android.server.am.MemoryStatUtil.MemoryStat; import com.android.server.am.NeededUriGrantsProto; import com.android.server.am.ProcessOomProto; import com.android.server.am.ProcessToGcProto; @@ -404,16 +384,10 @@ import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.dex.DexManager; import com.android.server.utils.PriorityDump; import com.android.server.vr.VrManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import com.android.server.wm.WindowManagerService; -import dalvik.system.VMRuntime; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; - -import com.google.android.collect.Lists; -import com.google.android.collect.Maps; - import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; @@ -450,6 +424,10 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; +import dalvik.system.VMRuntime; +import libcore.io.IoUtils; +import libcore.util.EmptyArray; + public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @@ -728,7 +706,22 @@ public class ActivityManagerService extends IActivityManager.Stub * returned by the package manager), and the keys are ApplicationRecord * objects. */ - final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); + final MyProcessMap mProcessNames = new MyProcessMap(); + final class MyProcessMap extends ProcessMap<ProcessRecord> { + @Override + public ProcessRecord put(String name, int uid, ProcessRecord value) { + final ProcessRecord r = super.put(name, uid, value); + mAtmInternal.onProcessAdded(r.getWindowProcessController()); + return r; + } + + @Override + public ProcessRecord remove(String name, int uid) { + final ProcessRecord r = super.remove(name, uid); + mAtmInternal.onProcessRemoved(name, uid); + return r; + } + } /** * Tracking long-term execution of processes to look for abuse and other @@ -739,7 +732,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * The currently running isolated processes. */ - final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); + final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>(); /** * Counter for assigning isolated process uids, to avoid frequently reusing the @@ -866,23 +859,6 @@ public class ActivityManagerService extends IActivityManager.Stub boolean mFullPssPending = false; /** - * This is the process holding what we currently consider to be - * the "home" activity. - */ - ProcessRecord mHomeProcess; - - /** - * This is the process holding the activity the user last visited that - * is in a different process from the one they are currently in. - */ - ProcessRecord mPreviousProcess; - - /** - * The time at which the previous process was last visible. - */ - long mPreviousProcessVisibleTime; - - /** * Track all uids that have actively running processes. */ final SparseArray<UidRecord> mActiveUids = new SparseArray<>(); @@ -2048,13 +2024,13 @@ public class ActivityManagerService extends IActivityManager.Stub } ActivityRecord root = (ActivityRecord)msg.obj; - ProcessRecord process = root.app; + final WindowProcessController process = root.app; if (process == null) { return; } try { - Context context = mContext.createPackageContext(process.info.packageName, 0); + Context context = mContext.createPackageContext(process.mInfo.packageName, 0); String text = mContext.getString(R.string.heavy_weight_notification, context.getApplicationInfo().loadLabel(context.getPackageManager())); Notification notification = @@ -2438,8 +2414,9 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); - app.persistent = true; + app.setPersistent(true); app.pid = MY_PID; + app.getWindowProcessController().setPid(MY_PID); app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); synchronized (mPidsSelfLocked) { @@ -2475,15 +2452,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - public void setActivityTaskManager(ActivityTaskManagerService atm) { - synchronized (this) { - mActivityTaskManager = atm; - mActivityTaskManager.setActivityManagerService(this); - mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); - mStackSupervisor = mActivityTaskManager.mStackSupervisor; - } - } - public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { mUsageStatsService = usageStatsManager; } @@ -2584,10 +2552,17 @@ public class ActivityManagerService extends IActivityManager.Stub public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; + private static ActivityTaskManagerService sAtm; public Lifecycle(Context context) { super(context); - mService = new ActivityManagerService(context); + mService = new ActivityManagerService(context, sAtm); + } + + public static ActivityManagerService startService( + SystemServiceManager ssm, ActivityTaskManagerService atm) { + sAtm = atm; + return ssm.startService(ActivityManagerService.Lifecycle.class).getService(); } @Override @@ -2744,7 +2719,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Note: This method is invoked on the main thread but may need to attach various // handlers to other threads. So take care to be explicit about the looper. - public ActivityManagerService(Context systemContext) { + public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) { LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY); mInjector = new Injector(); mContext = systemContext; @@ -2823,6 +2798,11 @@ public class ActivityManagerService extends IActivityManager.Stub mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); + mActivityTaskManager = atm; + mActivityTaskManager.setActivityManagerService(this); + mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); + mStackSupervisor = mActivityTaskManager.mStackSupervisor; + mProcessCpuThread = new Thread("CpuTracker") { @Override public void run() { @@ -2891,6 +2871,7 @@ public class ActivityManagerService extends IActivityManager.Stub mAppOpsService.publish(mContext); Slog.d("AppOps", "AppOpsService published"); LocalServices.addService(ActivityManagerInternal.class, new LocalService()); + mActivityTaskManager.onActivityManagerInternalAdded(); // Wait for the synchronized block started in mProcessCpuThread, // so that any other access to mProcessCpuTracker from main thread // will be blocked during mProcessCpuTracker initialization. @@ -3295,7 +3276,7 @@ public class ActivityManagerService extends IActivityManager.Stub String what, Object obj, ProcessRecord srcApp) { app.lastActivityTime = now; - if (app.activities.size() > 0 || app.recentTasks.size() > 0) { + if (app.hasActivitiesOrRecentTasks()) { // Don't want to touch dependent processes that are hosting activities. return index; } @@ -3342,7 +3323,7 @@ public class ActivityManagerService extends IActivityManager.Stub int lrui = mLruProcesses.lastIndexOf(app); if (lrui >= 0) { if (!app.killed) { - if (app.persistent) { + if (app.isPersistent()) { Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app); } else { Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); @@ -3366,8 +3347,8 @@ public class ActivityManagerService extends IActivityManager.Stub final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client) { - final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities - || app.treatLikeActivity || app.recentTasks.size() > 0; + final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities + || app.treatLikeActivity; final boolean hasService = false; // not impl yet. app.services.size() > 0; if (!activityChange && hasActivity) { // The process has activities, so we are only allowing activity-based adjustments @@ -3399,7 +3380,7 @@ public class ActivityManagerService extends IActivityManager.Stub int lrui = mLruProcesses.lastIndexOf(app); - if (app.persistent && lrui >= 0) { + if (app.isPersistent() && lrui >= 0) { // We don't care about the position of persistent processes, as long as // they are in the list. if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); @@ -3471,7 +3452,7 @@ public class ActivityManagerService extends IActivityManager.Stub int nextIndex; if (hasActivity) { final int N = mLruProcesses.size(); - if ((app.activities.size() == 0 || app.recentTasks.size() > 0) + if ((!app.hasActivities() || app.hasRecentTasks()) && mLruProcessActivityStart < (N - 1)) { // Process doesn't have activities, but has clients with // activities... move it up, but one below the top (the top @@ -3546,14 +3527,14 @@ public class ActivityManagerService extends IActivityManager.Stub if (cr.binding != null && !cr.serviceDead && cr.binding.service != null && cr.binding.service.app != null && cr.binding.service.app.lruSeq != mLruSeq - && !cr.binding.service.app.persistent) { + && !cr.binding.service.app.isPersistent()) { nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, "service connection", cr, app); } } for (int j=app.conProviders.size()-1; j>=0; j--) { ContentProviderRecord cpr = app.conProviders.get(j).provider; - if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { + if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) { nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, "provider reference", cpr, app); } @@ -3583,7 +3564,7 @@ public class ActivityManagerService extends IActivityManager.Stub && proc.lastCachedPss >= 4000) { // Turn this condition on to cause killing to happen regularly, for testing. if (proc.baseProcessTracker != null) { - proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); + proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss); } proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); } else if (proc != null && !keepIfLarge @@ -3592,7 +3573,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss); if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { if (proc.baseProcessTracker != null) { - proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); + proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss); } proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); } @@ -3898,7 +3879,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (app.info.isPrivilegedApp() && - DexManager.isPackageSelectedToRunOob(app.pkgList.keySet())) { + DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) { runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; } @@ -3940,7 +3921,7 @@ public class ActivityManagerService extends IActivityManager.Stub } app.gids = gids; - app.requiredAbi = requiredAbi; + app.setRequiredAbi(requiredAbi); app.instructionSet = instructionSet; // the per-user SELinux context must be set @@ -4131,7 +4112,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Ignore } - if (app.persistent) { + if (app.isPersistent()) { Watchdog.getInstance().processStarted(app.processName, pid); } @@ -4190,7 +4171,7 @@ public class ActivityManagerService extends IActivityManager.Stub "updateUsageStats: comp=" + component + "res=" + resumed); final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); StatsLog.write(StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED, - component.app.uid, component.realActivity.getPackageName(), + component.app.mUid, component.realActivity.getPackageName(), component.realActivity.getShortClassName(), resumed ? StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__FOREGROUND : StatsLog.ACTIVITY_FOREGROUND_STATE_CHANGED__STATE__BACKGROUND); @@ -4201,7 +4182,7 @@ public class ActivityManagerService extends IActivityManager.Stub } synchronized (stats) { - stats.noteActivityResumedLocked(component.app.uid); + stats.noteActivityResumedLocked(component.app.mUid); } } else { if (mUsageStatsService != null) { @@ -4209,7 +4190,7 @@ public class ActivityManagerService extends IActivityManager.Stub UsageEvents.Event.MOVE_TO_BACKGROUND); } synchronized (stats) { - stats.noteActivityPausedLocked(component.app.uid); + stats.noteActivityPausedLocked(component.app.mUid); } } } @@ -4678,7 +4659,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Inform the activity try { - activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity, + activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity, voiceInteractor); long token = Binder.clearCallingIdentity(); try { @@ -4746,14 +4727,7 @@ public class ActivityManagerService extends IActivityManager.Stub return; } - ArrayList<ActivityRecord> activities = new ArrayList<>(proc.activities); - for (int i = 0; i < activities.size(); i++) { - ActivityRecord r = activities.get(i); - if (!r.finishing && r.isInStackLocked()) { - r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED, - null, "finish-heavy", true); - } - } + proc.getWindowProcessController().finishActivities(); mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, proc.userId, 0)); @@ -4802,11 +4776,10 @@ public class ActivityManagerService extends IActivityManager.Stub } // Remove this application's activities from active lists. - boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); + boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app.getWindowProcessController()); app.clearRecentTasks(); - - app.activities.clear(); + app.clearActivities(); if (app.instr != null) { Slog.w(TAG, "Crash of app " + app.processName @@ -4879,7 +4852,7 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i=mLruProcesses.size()-1; i>=0; i--) { ProcessRecord rec = mLruProcesses.get(i); if (rec.thread != null - && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { + && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) { haveBg = true; break; } @@ -5131,7 +5104,7 @@ public class ActivityManagerService extends IActivityManager.Stub return SystemClock.elapsedRealtime() - timeStart; } - private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids, + public static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids, ArrayList<Integer> nativePids, ArrayList<Integer> extraPids) { // We don't need any sort of inotify based monitoring when we're dumping traces via @@ -5207,90 +5180,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { - if (true || Build.IS_USER) { - return; - } - - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - StrictMode.allowThreadDiskWrites(); - try { - File tracesDir = new File("/data/anr"); - File tracesFile = null; - try { - tracesFile = File.createTempFile("app_slow", null, tracesDir); - - StringBuilder sb = new StringBuilder(); - Time tobj = new Time(); - tobj.set(System.currentTimeMillis()); - sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); - sb.append(": "); - TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); - sb.append(" since "); - sb.append(msg); - FileOutputStream fos = new FileOutputStream(tracesFile); - fos.write(sb.toString().getBytes()); - if (app == null) { - fos.write("\n*** No application process!".getBytes()); - } - fos.close(); - FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- - } catch (IOException e) { - Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e); - return; - } - - if (app != null && app.pid > 0) { - ArrayList<Integer> firstPids = new ArrayList<Integer>(); - firstPids.add(app.pid); - dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null); - } - - File lastTracesFile = null; - File curTracesFile = null; - for (int i=9; i>=0; i--) { - String name = String.format(Locale.US, "slow%02d.txt", i); - curTracesFile = new File(tracesDir, name); - if (curTracesFile.exists()) { - if (lastTracesFile != null) { - curTracesFile.renameTo(lastTracesFile); - } else { - curTracesFile.delete(); - } - } - lastTracesFile = curTracesFile; - } - tracesFile.renameTo(curTracesFile); - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } - } - - @GuardedBy("this") - final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { - if (!mLaunchWarningShown) { - mLaunchWarningShown = true; - mUiHandler.post(new Runnable() { - @Override - public void run() { - synchronized (ActivityManagerService.this) { - final Dialog d = new LaunchWarningWindow(mContext, cur, next); - d.show(); - mUiHandler.postDelayed(new Runnable() { - @Override - public void run() { - synchronized (ActivityManagerService.this) { - d.dismiss(); - mLaunchWarningShown = false; - } - } - }, 4000); - } - } - }); - } - } - @Override public boolean clearApplicationUserData(final String packageName, boolean keepState, final IPackageDataObserver observer, int userId) { @@ -5491,7 +5380,7 @@ public class ActivityManagerService extends IActivityManager.Stub final int NA = apps.size(); for (int ia = 0; ia < NA; ia++) { final ProcessRecord app = apps.valueAt(ia); - if (app.persistent) { + if (app.isPersistent()) { // We don't kill persistent processes. continue; } @@ -5746,7 +5635,7 @@ public class ActivityManagerService extends IActivityManager.Stub proc.baseProcessTracker.addPss(infos[i].getTotalPss(), infos[i].getTotalUss(), infos[i].getTotalRss(), false, ProcessStats.ADD_PSS_EXTERNAL_SLOW, endTime-startTime, - proc.pkgList); + proc.pkgList.mPkgList); } } } @@ -5776,7 +5665,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (proc.thread != null && proc.setAdj == oomAdj) { // Record this for posterity if the process has been stable. proc.baseProcessTracker.addPss(pss[i], tmpUss[0], tmpUss[2], false, - ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList); + ProcessStats.ADD_PSS_EXTERNAL, endTime-startTime, proc.pkgList.mPkgList); } } } @@ -5849,7 +5738,7 @@ public class ActivityManagerService extends IActivityManager.Stub final int NA = apps.size(); for (int ia=0; ia<NA; ia++) { ProcessRecord app = apps.valueAt(ia); - if (app.persistent && !evenPersistent) { + if (app.isPersistent() && !evenPersistent) { // we don't kill persistent processes continue; } @@ -6186,7 +6075,7 @@ public class ActivityManagerService extends IActivityManager.Stub // We shouldn't already have a process under this name, but just in case we // need to clean up whatever may be there now. ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); - if (old == proc && proc.persistent) { + if (old == proc && proc.isPersistent()) { // We are re-adding a persistent process. Whatevs! Just leave it there. Slog.w(TAG, "Re-adding persistent process " + proc); } else if (old != null) { @@ -6253,7 +6142,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } boolean willRestart = false; - if (app.persistent && !app.isolated) { + if (app.isPersistent() && !app.isolated) { if (!callerWillRestart) { willRestart = true; } else { @@ -6406,7 +6295,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.makeActive(thread, mProcessStats); app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ; - app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; + app.setCurrentSchedulingGroup(app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT); app.forcingToImportant = null; updateProcessForegroundLocked(app, false, false); app.hasShownUi = false; @@ -6585,7 +6474,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, - isRestrictedBackupMode || !normalMode, app.persistent, + isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), @@ -6594,7 +6483,7 @@ public class ActivityManagerService extends IActivityManager.Stub thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, - isRestrictedBackupMode || !normalMode, app.persistent, + isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), @@ -9457,7 +9346,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (conn.stableCount == 0 && conn.unstableCount == 0) { cpr.connections.remove(conn); conn.client.conProviders.remove(conn); - if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { + if (conn.client.setProcState < PROCESS_STATE_LAST_ACTIVITY) { // The client is more important than last activity -- note the time this // is happening, so we keep the old provider process around a bit as last // activity to avoid thrashing it. @@ -10457,9 +10346,9 @@ public class ActivityManagerService extends IActivityManager.Stub && userId == UserHandle.USER_SYSTEM && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc. - r.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; + r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; - r.persistent = true; + r.setPersistent(true); r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } if (isolated && isolatedUid != 0) { @@ -10558,7 +10447,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { - app.persistent = true; + app.setPersistent(true); app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; } if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { @@ -11109,7 +10998,10 @@ public class ActivityManagerService extends IActivityManager.Stub public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { - return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; + if (r == null || !r.hasProcess()) { + return KEY_DISPATCHING_TIMEOUT; + } + return getInputDispatchingTimeoutLocked((ProcessRecord) r.app.mOwner); } public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { @@ -11326,7 +11218,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid); } // promote to FIFO now - if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { + if (proc.getCurrentSchedulingGroup() == ProcessList.SCHED_GROUP_TOP_APP) { if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band"); if (mUseFifoUiScheduling) { setThreadScheduler(proc.renderThreadTid, @@ -12294,7 +12186,7 @@ public class ActivityManagerService extends IActivityManager.Stub final boolean isFatal = Build.IS_ENG || Settings.Global .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0; - final boolean isSystem = (r == null) || r.persistent; + final boolean isSystem = (r == null) || r.isPersistent(); if (isFatal && !isSystem) { mAppErrors.crashApplication(r, crashInfo); @@ -12457,8 +12349,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (activity != null) { sb.append("Activity: ").append(activity.shortComponentName).append("\n"); } - if (parent != null && parent.app != null && parent.app.pid != process.pid) { - sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); + if (parent != null && parent.app != null && parent.app.getPid() != process.pid) { + sb.append("Parent-Process: ").append(parent.app.mName).append("\n"); } if (parent != null && parent != activity) { sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); @@ -12560,25 +12452,27 @@ public class ActivityManagerService extends IActivityManager.Stub if (!allUsers && app.userId != userId) { continue; } - if ((app.thread != null) && (app.crashing || app.notResponding)) { + final boolean crashing = app.isCrashing(); + final boolean notResponding = app.isNotResponding(); + if ((app.thread != null) && (crashing || notResponding)) { // This one's in trouble, so we'll generate a report for it // crashes are higher priority (in case there's a crash *and* an anr) ActivityManager.ProcessErrorStateInfo report = null; - if (app.crashing) { + if (crashing) { report = app.crashingReport; - } else if (app.notResponding) { + } else if (notResponding) { report = app.notRespondingReport; } if (report != null) { if (errList == null) { - errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); + errList = new ArrayList<>(1); } errList.add(report); } else { Slog.w(TAG, "Missing app error report, app = " + app.processName + - " crashing = " + app.crashing + - " notResponding = " + app.notResponding); + " crashing = " + crashing + + " notResponding = " + notResponding); } } } @@ -12608,10 +12502,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (mHeavyWeightProcess == app) { outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; } - if (app.persistent) { + if (app.isPersistent()) { outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; } - if (app.activities.size() > 0) { + if (app.hasActivities()) { outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; } outInfo.lastTrimLevel = app.trimMemoryLevel; @@ -12645,7 +12539,7 @@ public class ActivityManagerService extends IActivityManager.Stub || (!allUids && app.uid != callingUid)) { continue; } - if ((app.thread != null) && (!app.crashing && !app.notResponding)) { + if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) { // Generate process state info for running application ActivityManager.RunningAppProcessInfo currApp = new ActivityManager.RunningAppProcessInfo(app.processName, @@ -12658,7 +12552,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.adjSourceProcState); } else if (app.adjSource instanceof ActivityRecord) { ActivityRecord r = (ActivityRecord)app.adjSource; - if (r.app != null) currApp.importanceReasonPid = r.app.pid; + if (r.app != null) currApp.importanceReasonPid = r.app.getPid(); } if (app.adjTarget instanceof ComponentName) { currApp.importanceReasonComponent = (ComponentName)app.adjTarget; @@ -13461,11 +13355,11 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" All known processes:"); needSep = true; } - pw.print(r.persistent ? " *PERS*" : " *APP*"); + pw.print(r.isPersistent() ? " *PERS*" : " *APP*"); pw.print(" UID "); pw.print(procs.keyAt(ia)); pw.print(" "); pw.println(r); r.dump(pw, " "); - if (r.persistent) { + if (r.isPersistent()) { numPers++; } } @@ -13617,27 +13511,27 @@ public class ActivityManagerService extends IActivityManager.Stub needSep = false; mUserController.dump(pw, dumpAll); } - if (mHomeProcess != null && (dumpPackage == null - || mHomeProcess.pkgList.containsKey(dumpPackage))) { + if (mActivityTaskManager.mHomeProcess != null && (dumpPackage == null + || mActivityTaskManager.mHomeProcess.mPkgList.contains(dumpPackage))) { if (needSep) { pw.println(); needSep = false; } - pw.println(" mHomeProcess: " + mHomeProcess); + pw.println(" mHomeProcess: " + mActivityTaskManager.mHomeProcess); } - if (mPreviousProcess != null && (dumpPackage == null - || mPreviousProcess.pkgList.containsKey(dumpPackage))) { + if (mActivityTaskManager.mPreviousProcess != null && (dumpPackage == null + || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) { if (needSep) { pw.println(); needSep = false; } - pw.println(" mPreviousProcess: " + mPreviousProcess); + pw.println(" mPreviousProcess: " + mActivityTaskManager.mPreviousProcess); } - if (dumpAll && (mPreviousProcess == null || dumpPackage == null - || mPreviousProcess.pkgList.containsKey(dumpPackage))) { + if (dumpAll && (mActivityTaskManager.mPreviousProcess == null || dumpPackage == null + || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) { StringBuilder sb = new StringBuilder(128); sb.append(" mPreviousProcessVisibleTime: "); - TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); + TimeUtils.formatDuration(mActivityTaskManager.mPreviousProcessVisibleTime, sb); pw.println(sb); } if (mHeavyWeightProcess != null && (dumpPackage == null @@ -13933,7 +13827,7 @@ public class ActivityManagerService extends IActivityManager.Stub continue; } r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PROCS); - if (r.persistent) { + if (r.isPersistent()) { numPers++; } } @@ -14043,15 +13937,15 @@ public class ActivityManagerService extends IActivityManager.Stub proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, mActivityTaskManager.getFocusedStack().mConfigWillChange); } - if (mHomeProcess != null && (dumpPackage == null - || mHomeProcess.pkgList.containsKey(dumpPackage))) { - mHomeProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC); + if (mActivityTaskManager.mHomeProcess != null && (dumpPackage == null + || mActivityTaskManager.mHomeProcess.mPkgList.contains(dumpPackage))) { + ((ProcessRecord) mActivityTaskManager.mHomeProcess.mOwner).writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC); } - if (mPreviousProcess != null && (dumpPackage == null - || mPreviousProcess.pkgList.containsKey(dumpPackage))) { - mPreviousProcess.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC); - proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime); + if (mActivityTaskManager.mPreviousProcess != null && (dumpPackage == null + || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) { + ((ProcessRecord) mActivityTaskManager.mPreviousProcess.mOwner).writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC); + proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mActivityTaskManager.mPreviousProcessVisibleTime); } if (mHeavyWeightProcess != null && (dumpPackage == null @@ -14322,8 +14216,8 @@ public class ActivityManagerService extends IActivityManager.Stub dumpProcessesToGc(pw, needSep, null); pw.println(); - pw.println(" mHomeProcess: " + mHomeProcess); - pw.println(" mPreviousProcess: " + mPreviousProcess); + pw.println(" mHomeProcess: " + mActivityTaskManager.mHomeProcess); + pw.println(" mPreviousProcess: " + mActivityTaskManager.mPreviousProcess); if (mHeavyWeightProcess != null) { pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); } @@ -14495,20 +14389,20 @@ public class ActivityManagerService extends IActivityManager.Stub pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); pw.print(" pid="); - if (r.app != null) pw.println(r.app.pid); + if (r.hasProcess()) pw.println(r.app.getPid()); else pw.println("(not running)"); if (dumpAll) { r.dump(pw, innerPrefix); } } - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { // flush anything that is already in the PrintWriter since the thread is going // to write to the file descriptor directly pw.flush(); try { TransferPipe tp = new TransferPipe(); try { - r.app.thread.dumpActivity(tp.getWriteFd(), + r.app.getThread().dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args); tp.go(fd); } finally { @@ -14863,9 +14757,9 @@ public class ActivityManagerService extends IActivityManager.Stub continue; } pw.println(String.format("%s%s #%2d: %s", - prefix, (r.persistent ? persistentLabel : normalLabel), + prefix, (r.isPersistent() ? persistentLabel : normalLabel), i, r.toString())); - if (r.persistent) { + if (r.isPersistent()) { numPers++; } } @@ -14918,7 +14812,7 @@ public class ActivityManagerService extends IActivityManager.Stub ProcessRecord r = list.get(i).first; long token = proto.start(fieldId); String oomAdj = ProcessList.makeOomAdjString(r.setAdj); - proto.write(ProcessOomProto.PERSISTENT, r.persistent); + proto.write(ProcessOomProto.PERSISTENT, r.isPersistent()); proto.write(ProcessOomProto.NUM, (origList.size()-1)-list.get(i).second); proto.write(ProcessOomProto.OOM_ADJ, oomAdj); int schedGroup = ProcessOomProto.SCHED_GROUP_UNKNOWN; @@ -14941,7 +14835,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (r.foregroundActivities) { proto.write(ProcessOomProto.ACTIVITIES, true); - } else if (r.foregroundServices) { + } else if (r.hasForegroundServices()) { proto.write(ProcessOomProto.SERVICES, true); } proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState)); @@ -15038,14 +14932,14 @@ public class ActivityManagerService extends IActivityManager.Stub char foreground; if (r.foregroundActivities) { foreground = 'A'; - } else if (r.foregroundServices) { + } else if (r.hasForegroundServices()) { foreground = 'S'; } else { foreground = ' '; } String procState = ProcessList.makeProcStateString(r.curProcState); pw.print(prefix); - pw.print(r.persistent ? persistentLabel : normalLabel); + pw.print(r.isPersistent() ? persistentLabel : normalLabel); pw.print(" #"); int num = (origList.size()-1)-list.get(i).second; if (num < 10) pw.print(' '); @@ -15660,7 +15554,7 @@ public class ActivityManagerService extends IActivityManager.Stub thread = r.thread; pid = r.pid; oomAdj = r.getSetAdjWithServices(); - hasActivities = r.activities.size() > 0; + hasActivities = r.hasActivities(); } if (thread != null) { if (!opts.isCheckinRequest && opts.dumpDetails) { @@ -15727,7 +15621,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true, - reportType, endTime-startTime, r.pkgList); + reportType, endTime-startTime, r.pkgList.mPkgList); } } @@ -16163,7 +16057,7 @@ public class ActivityManagerService extends IActivityManager.Stub thread = r.thread; pid = r.pid; oomAdj = r.getSetAdjWithServices(); - hasActivities = r.activities.size() > 0; + hasActivities = r.hasActivities(); } if (thread == null) { continue; @@ -16225,7 +16119,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { // Record this for posterity if the process has been stable. r.baseProcessTracker.addPss(myTotalPss, myTotalUss, myTotalRss, true, - reportType, endTime-startTime, r.pkgList); + reportType, endTime-startTime, r.pkgList.mPkgList); } } @@ -16791,7 +16685,7 @@ public class ActivityManagerService extends IActivityManager.Stub ProcessRecord capp = conn.client; conn.dead = true; if (conn.stableCount > 0) { - if (!capp.persistent && capp.thread != null + if (!capp.isPersistent() && capp.thread != null && capp.pid != 0 && capp.pid != MY_PID) { capp.kill("depends on provider " @@ -16853,8 +16747,8 @@ public class ActivityManagerService extends IActivityManager.Stub app.waitDialog = null; } - app.crashing = false; - app.notResponding = false; + app.setCrashing(false); + app.setNotResponding(false); app.resetPackageList(mProcessStats); app.unlinkDeathRecipient(); @@ -16963,7 +16857,7 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } - if (!app.persistent || app.isolated) { + if (!app.isPersistent() || app.isolated) { if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Removing non-persistent process during cleanup: " + app); if (!replacingPid) { @@ -16987,12 +16881,7 @@ public class ActivityManagerService extends IActivityManager.Stub TAG_CLEANUP, "Clean-up removing on hold: " + app); mProcessesOnHold.remove(app); - if (app == mHomeProcess) { - mHomeProcess = null; - } - if (app == mPreviousProcess) { - mPreviousProcess = null; - } + mAtmInternal.onCleanUpApplicationRecord(app.getWindowProcessController()); if (restart && !app.isolated) { // We have components that still need to be running in the @@ -18037,7 +17926,7 @@ public class ActivityManagerService extends IActivityManager.Stub isCallerSystem = true; break; default: - isCallerSystem = (callerApp != null) && callerApp.persistent; + isCallerSystem = (callerApp != null) && callerApp.isPersistent(); break; } @@ -19279,7 +19168,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (app.thread == null) { app.adjSeq = mAdjSeq; - app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND; + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND); app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ; app.completedAdjSeq = app.adjSeq; @@ -19292,7 +19181,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.empty = false; app.cached = false; - final int activitiesSize = app.activities.size(); + final WindowProcessController wpc = app.getWindowProcessController(); final int appUid = app.info.uid; final int logUid = mCurOomAdjUid; @@ -19308,7 +19197,7 @@ public class ActivityManagerService extends IActivityManager.Stub app.adjSeq = mAdjSeq; app.curRawAdj = app.maxAdj; app.foregroundActivities = false; - app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; // System processes can do UI, and when they do we want to have // them trim their memory after the user leaves the UI. To @@ -19317,29 +19206,24 @@ public class ActivityManagerService extends IActivityManager.Stub app.systemNoUi = true; if (app == TOP_APP) { app.systemNoUi = false; - app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); app.adjType = "pers-top-activity"; } else if (app.hasTopUi) { // sched group/proc state adjustment is below app.systemNoUi = false; app.adjType = "pers-top-ui"; - } else if (activitiesSize > 0) { - for (int j = 0; j < activitiesSize; j++) { - final ActivityRecord r = app.activities.get(j); - if (r.visible) { - app.systemNoUi = false; - } - } + } else if (wpc.hasVisibleActivities()) { + app.systemNoUi = false; } if (!app.systemNoUi) { if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) { // screen on, promote UI app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; - app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP; + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); } else { // screen off, restrict UI scheduling app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; - app.curSchedGroup = ProcessList.SCHED_GROUP_RESTRICTED; + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED); } } app.curAdj = app.maxAdj; @@ -19438,120 +19322,127 @@ public class ActivityManagerService extends IActivityManager.Stub } // Examine all activities if not already foreground. - if (!foregroundActivities && activitiesSize > 0) { - int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX; - for (int j = 0; j < activitiesSize; j++) { - final ActivityRecord r = app.activities.get(j); - if (r.app != app) { - Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app - + " instead of expected " + app); - if (r.app == null || (r.app.uid == app.uid)) { - // Only fix things up when they look sane - r.setProcess(app); - } else { - continue; - } - } - if (r.visible) { - // App has a visible activity; only upgrade adjustment. - if (adj > ProcessList.VISIBLE_APP_ADJ) { - adj = ProcessList.VISIBLE_APP_ADJ; - app.adjType = "vis-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise adj to vis-activity: " + app); - } - } - if (procState > PROCESS_STATE_CUR_TOP) { - procState = PROCESS_STATE_CUR_TOP; - app.adjType = "vis-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise procstate to vis-activity (top): " + app); - } - } - if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) { - schedGroup = ProcessList.SCHED_GROUP_DEFAULT; - } - app.cached = false; - app.empty = false; - foregroundActivities = true; - final TaskRecord task = r.getTask(); - if (task != null && minLayer > 0) { - final int layer = task.mLayerRank; - if (layer >= 0 && minLayer > layer) { - minLayer = layer; - } - } - break; - } else if (r.isState(ActivityState.PAUSING, ActivityState.PAUSED)) { - if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { - adj = ProcessList.PERCEPTIBLE_APP_ADJ; - app.adjType = "pause-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise adj to pause-activity: " + app); - } - } - if (procState > PROCESS_STATE_CUR_TOP) { - procState = PROCESS_STATE_CUR_TOP; - app.adjType = "pause-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise procstate to pause-activity (top): " + app); + if (!foregroundActivities && wpc.hasActivities()) { + final int[] adjHolder = new int[1]; + adjHolder[0] = adj; + final boolean[] foregroundActivitiesHolder = new boolean[1]; + foregroundActivitiesHolder[0] = foregroundActivities; + int[] procStateHolder = new int[1]; + procStateHolder[0] = procState; + int[] schedGroupHolder = new int[1]; + schedGroupHolder[0] = schedGroup; + + int minLayer = wpc.computeOomAdjFromActivities(ProcessList.VISIBLE_APP_LAYER_MAX, + new WindowProcessController.ComputeOomAdjCallback() { + @Override + public void onVisibleActivity() { + // App has a visible activity; only upgrade adjustment. + if (adjHolder[0] > ProcessList.VISIBLE_APP_ADJ) { + adjHolder[0] = ProcessList.VISIBLE_APP_ADJ; + app.adjType = "vis-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise adj to vis-activity: " + app); + } + } + if (procStateHolder[0] > PROCESS_STATE_CUR_TOP) { + procStateHolder[0] = PROCESS_STATE_CUR_TOP; + app.adjType = "vis-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise procstate to vis-activity (top): " + app); + } + } + if (schedGroupHolder[0] < ProcessList.SCHED_GROUP_DEFAULT) { + schedGroupHolder[0] = ProcessList.SCHED_GROUP_DEFAULT; + } + app.cached = false; + app.empty = false; + foregroundActivitiesHolder[0] = true; } - } - if (schedGroup < ProcessList.SCHED_GROUP_DEFAULT) { - schedGroup = ProcessList.SCHED_GROUP_DEFAULT; - } - app.cached = false; - app.empty = false; - foregroundActivities = true; - } else if (r.isState(ActivityState.STOPPING)) { - if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { - adj = ProcessList.PERCEPTIBLE_APP_ADJ; - app.adjType = "stop-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise adj to stop-activity: " + app); + + @Override + public void onPausedActivity() { + if (adjHolder[0] > ProcessList.PERCEPTIBLE_APP_ADJ) { + adjHolder[0] = ProcessList.PERCEPTIBLE_APP_ADJ; + app.adjType = "pause-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise adj to pause-activity: " + app); + } + } + if (procStateHolder[0] > PROCESS_STATE_CUR_TOP) { + procStateHolder[0] = PROCESS_STATE_CUR_TOP; + app.adjType = "pause-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise procstate to pause-activity (top): " + app); + } + } + if (schedGroupHolder[0] < ProcessList.SCHED_GROUP_DEFAULT) { + schedGroupHolder[0] = ProcessList.SCHED_GROUP_DEFAULT; + } + app.cached = false; + app.empty = false; + foregroundActivitiesHolder[0] = true; } - } - // For the process state, we will at this point consider the - // process to be cached. It will be cached either as an activity - // or empty depending on whether the activity is finishing. We do - // this so that we can treat the process as cached for purposes of - // memory trimming (determing current memory level, trim command to - // send to process) since there can be an arbitrary number of stopping - // processes and they should soon all go into the cached state. - if (!r.finishing) { - if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { - procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; - app.adjType = "stop-activity"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise procstate to stop-activity: " + app); + + @Override + public void onStoppingActivity(boolean finishing) { + if (adjHolder[0] > ProcessList.PERCEPTIBLE_APP_ADJ) { + adjHolder[0] = ProcessList.PERCEPTIBLE_APP_ADJ; + app.adjType = "stop-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise adj to stop-activity: " + app); + } } + // For the process state, we will at this point consider the process to + // be cached. It will be cached either as an activity or empty depending + // on whether the activity is finishing. We do this so that we can treat + // the process as cached for purposes of memory trimming (determining + // current memory level, trim command to send to process) since there + // can be an arbitrary number of stopping processes and they should soon + // all go into the cached state. + if (!finishing) { + if (procStateHolder[0] > PROCESS_STATE_LAST_ACTIVITY) { + procStateHolder[0] = PROCESS_STATE_LAST_ACTIVITY; + app.adjType = "stop-activity"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise procstate to stop-activity: " + app); + } + } + } + app.cached = false; + app.empty = false; + foregroundActivitiesHolder[0] = true; } - } - app.cached = false; - app.empty = false; - foregroundActivities = true; - } else { - if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { - procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; - app.adjType = "cch-act"; - if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { - reportOomAdjMessageLocked(TAG_OOM_ADJ, - "Raise procstate to cached activity: " + app); + + @Override + public void onOtherActivity() { + if (procStateHolder[0] > PROCESS_STATE_CACHED_ACTIVITY) { + procStateHolder[0] = PROCESS_STATE_CACHED_ACTIVITY; + app.adjType = "cch-act"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, + "Raise procstate to cached activity: " + app); + } + } } - } - } - } + }); + + adj = adjHolder[0]; + foregroundActivities = foregroundActivitiesHolder[0]; + procState = procStateHolder[0]; + schedGroup = schedGroupHolder[0]; + if (adj == ProcessList.VISIBLE_APP_ADJ) { adj += minLayer; } } - if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.recentTasks.size() > 0) { + + if (procState > ActivityManager.PROCESS_STATE_CACHED_RECENT && app.hasRecentTasks()) { procState = ActivityManager.PROCESS_STATE_CACHED_RECENT; app.adjType = "cch-rec"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { @@ -19561,7 +19452,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - if (app.foregroundServices) { + if (app.hasForegroundServices()) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; @@ -19622,7 +19513,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - if (app == mHomeProcess) { + if (wpc == mActivityTaskManager.mHomeProcess) { if (adj > ProcessList.HOME_APP_ADJ) { // This process is hosting what we currently consider to be the // home app, so we don't want to let it go into the background. @@ -19643,7 +19534,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - if (app == mPreviousProcess && app.activities.size() > 0) { + if (wpc == mActivityTaskManager.mPreviousProcess && app.hasActivities()) { if (adj > ProcessList.PREVIOUS_APP_ADJ) { // This was the previous process that showed UI to the user. // We want to try to keep it around more aggressively, to give @@ -19656,8 +19547,8 @@ public class ActivityManagerService extends IActivityManager.Stub reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app); } } - if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { - procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; + if (procState > PROCESS_STATE_LAST_ACTIVITY) { + procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "previous"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app); @@ -19720,7 +19611,7 @@ public class ActivityManagerService extends IActivityManager.Stub "Raise procstate to started service: " + app); } } - if (app.hasShownUi && app != mHomeProcess) { + if (app.hasShownUi && wpc != mActivityTaskManager.mHomeProcess) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help @@ -19783,7 +19674,7 @@ public class ActivityManagerService extends IActivityManager.Stub } int clientAdj = client.curRawAdj; int clientProcState = client.curProcState; - if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { + if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. The specific cached state // doesn't propagate except under certain conditions. @@ -19793,7 +19684,7 @@ public class ActivityManagerService extends IActivityManager.Stub if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { // Not doing bind OOM management, so treat // this guy more like a started service. - if (app.hasShownUi && app != mHomeProcess) { + if (app.hasShownUi && wpc != mActivityTaskManager.mHomeProcess) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help @@ -19826,7 +19717,7 @@ public class ActivityManagerService extends IActivityManager.Stub // about letting this process get into the LRU // list to be killed and restarted if needed for // memory. - if (app.hasShownUi && app != mHomeProcess + if (app.hasShownUi && wpc != mActivityTaskManager.mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { adjType = "cch-bound-ui-services"; @@ -19870,9 +19761,10 @@ public class ActivityManagerService extends IActivityManager.Stub // This will treat important bound services identically to // the top app, which may behave differently than generic // foreground work. - if (client.curSchedGroup > schedGroup) { + final int curSchedGroup = client.getCurrentSchedulingGroup(); + if (curSchedGroup > schedGroup) { if ((cr.flags&Context.BIND_IMPORTANT) != 0) { - schedGroup = client.curSchedGroup; + schedGroup = curSchedGroup; } else { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } @@ -20010,14 +19902,14 @@ public class ActivityManagerService extends IActivityManager.Stub } int clientAdj = client.curRawAdj; int clientProcState = client.curProcState; - if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { + if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { // If the other app is cached for any reason, for purposes here // we are going to consider it empty. clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; } String adjType = null; if (adj > clientAdj) { - if (app.hasShownUi && app != mHomeProcess + if (app.hasShownUi && wpc != mActivityTaskManager.mHomeProcess && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { adjType = "cch-ui-provider"; } else { @@ -20058,7 +19950,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (procState > clientProcState) { procState = clientProcState; } - if (client.curSchedGroup > schedGroup) { + if (client.getCurrentSchedulingGroup() > schedGroup) { schedGroup = ProcessList.SCHED_GROUP_DEFAULT; } if (adjType != null) { @@ -20111,8 +20003,8 @@ public class ActivityManagerService extends IActivityManager.Stub "Raise adj to recent provider: " + app); } } - if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { - procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; + if (procState > PROCESS_STATE_LAST_ACTIVITY) { + procState = PROCESS_STATE_LAST_ACTIVITY; app.adjType = "recent-provider"; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, @@ -20174,7 +20066,7 @@ public class ActivityManagerService extends IActivityManager.Stub } else if (app.treatLikeActivity) { // This is a cached process, but somebody wants us to treat it like it has // an activity, okay! - procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; + procState = PROCESS_STATE_CACHED_ACTIVITY; app.adjType = "cch-as-act"; } } @@ -20233,7 +20125,7 @@ public class ActivityManagerService extends IActivityManager.Stub // worry about this for max adj above, since max adj will always be used to // keep it out of the cached vaues. app.curAdj = app.modifyRawOomAdj(adj); - app.curSchedGroup = schedGroup; + app.setCurrentSchedulingGroup(schedGroup); app.curProcState = procState; app.foregroundActivities = foregroundActivities; app.completedAdjSeq = mAdjSeq; @@ -20250,7 +20142,8 @@ public class ActivityManagerService extends IActivityManager.Stub EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024, swapPss * 1024, rss * 1024, statType, procState, pssDuration); proc.lastPssTime = now; - proc.baseProcessTracker.addPss(pss, uss, rss, true, statType, pssDuration, proc.pkgList); + proc.baseProcessTracker.addPss( + pss, uss, rss, true, statType, pssDuration, proc.pkgList.mPkgList); if (DEBUG_PSS) Slog.d(TAG_PSS, "pss of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss + " state=" + ProcessList.makeProcStateString(procState)); @@ -20601,7 +20494,7 @@ public class ActivityManagerService extends IActivityManager.Stub } app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince + " dur=" + checkDur + " limit=" + cpuLimit, true); - app.baseProcessTracker.reportExcessiveCpu(app.pkgList); + app.baseProcessTracker.reportExcessiveCpu(app.pkgList.mPkgList); } } app.lastCpuTime = app.curCpuTime; @@ -20630,12 +20523,13 @@ public class ActivityManagerService extends IActivityManager.Stub app.verifiedAdj = ProcessList.INVALID_ADJ; } - if (app.setSchedGroup != app.curSchedGroup) { + final int curSchedGroup = app.getCurrentSchedulingGroup(); + if (app.setSchedGroup != curSchedGroup) { int oldSchedGroup = app.setSchedGroup; - app.setSchedGroup = app.curSchedGroup; + app.setSchedGroup = curSchedGroup; if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) { String msg = "Setting sched group of " + app.processName - + " to " + app.curSchedGroup + ": " + app.adjType; + + " to " + curSchedGroup + ": " + app.adjType; reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); } if (app.waitingToKill != null && app.curReceivers.isEmpty() @@ -20644,7 +20538,7 @@ public class ActivityManagerService extends IActivityManager.Stub success = false; } else { int processGroup; - switch (app.curSchedGroup) { + switch (curSchedGroup) { case ProcessList.SCHED_GROUP_BACKGROUND: processGroup = THREAD_GROUP_BG_NONINTERACTIVE; break; @@ -20662,10 +20556,11 @@ public class ActivityManagerService extends IActivityManager.Stub long oldId = Binder.clearCallingIdentity(); try { setProcessGroup(app.pid, processGroup); - if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { + if (curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { // do nothing if we already switched to RT if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { - mActivityTaskManager.onTopProcChangedLocked(app); + mActivityTaskManager.onTopProcChangedLocked( + app.getWindowProcessController()); if (mUseFifoUiScheduling) { // Switch UI pipeline for app to SCHED_FIFO app.savedPriority = Process.getThreadPriority(app.pid); @@ -20696,8 +20591,9 @@ public class ActivityManagerService extends IActivityManager.Stub } } } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && - app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { - mActivityTaskManager.onTopProcChangedLocked(app); + curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) { + mActivityTaskManager.onTopProcChangedLocked( + app.getWindowProcessController()); if (mUseFifoUiScheduling) { try { // Reset UI pipeline to SCHED_OTHER @@ -20726,7 +20622,7 @@ public class ActivityManagerService extends IActivityManager.Stub } catch (Exception e) { if (false) { Slog.w(TAG, "Failed setting process group of " + app.pid - + " to " + app.curSchedGroup); + + " to " + app.getCurrentSchedulingGroup()); Slog.w(TAG, "at location", e); } } finally { @@ -20738,16 +20634,16 @@ public class ActivityManagerService extends IActivityManager.Stub app.repForegroundActivities = app.foregroundActivities; changes |= ProcessChangeItem.CHANGE_ACTIVITIES; } - if (app.repProcState != app.curProcState) { - app.repProcState = app.curProcState; + if (app.getReportedProcState() != app.curProcState) { + app.setReportedProcState(app.curProcState); if (app.thread != null) { try { if (false) { //RuntimeException h = new RuntimeException("here"); - Slog.i(TAG, "Sending new process state " + app.repProcState + Slog.i(TAG, "Sending new process state " + app.getReportedProcState() + " to " + app /*, h*/); } - app.thread.setProcessState(app.repProcState); + app.thread.setProcessState(app.getReportedProcState()); } catch (RemoteException e) { } } @@ -21034,10 +20930,9 @@ public class ActivityManagerService extends IActivityManager.Stub } private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { - if (proc.thread != null) { - if (proc.baseProcessTracker != null) { - proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); - } + if (proc.thread != null && proc.baseProcessTracker != null) { + proc.baseProcessTracker.setState( + proc.getReportedProcState(), memFactor, now, proc.pkgList.mPkgList); } } @@ -21055,8 +20950,8 @@ public class ActivityManagerService extends IActivityManager.Stub @GuardedBy("this") final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, boolean oomAdj) { - if (isForeground != proc.foregroundServices) { - proc.foregroundServices = isForeground; + if (isForeground != proc.hasForegroundServices()) { + proc.setHasForegroundServices(isForeground); ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, proc.info.uid); if (isForeground) { @@ -21126,7 +21021,8 @@ public class ActivityManagerService extends IActivityManager.Stub @GuardedBy("this") final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) { final ActivityRecord TOP_ACT = resumedAppLocked(); - final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; + final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() + ? (ProcessRecord) TOP_ACT.app.mOwner : null; final boolean wasCached = app.cached; mAdjSeq++; @@ -21151,7 +21047,8 @@ public class ActivityManagerService extends IActivityManager.Stub @GuardedBy("this") final void updateOomAdjLocked() { final ActivityRecord TOP_ACT = resumedAppLocked(); - final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; + final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess() + ? (ProcessRecord) TOP_ACT.app.mOwner : null; final long now = SystemClock.uptimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final long oldTime = now - ProcessList.MAX_EMPTY_TIME; @@ -21238,7 +21135,7 @@ public class ActivityManagerService extends IActivityManager.Stub // to the process, do that now. if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { switch (app.curProcState) { - case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: + case PROCESS_STATE_CACHED_ACTIVITY: case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: case ActivityManager.PROCESS_STATE_CACHED_RECENT: // This process is a cached process holding activities... @@ -21324,7 +21221,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Count the number of process types. switch (app.curProcState) { - case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: + case PROCESS_STATE_CACHED_ACTIVITY: case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: mNumCachedHiddenProcs++; numCached++; @@ -21367,7 +21264,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (uidRec.curProcState > app.curProcState) { uidRec.curProcState = app.curProcState; } - if (app.foregroundServices) { + if (app.hasForegroundServices()) { uidRec.foregroundServices = true; } } @@ -21442,8 +21339,8 @@ public class ActivityManagerService extends IActivityManager.Stub } int factor = numTrimming/3; int minFactor = 2; - if (mHomeProcess != null) minFactor++; - if (mPreviousProcess != null) minFactor++; + if (mActivityTaskManager.mHomeProcess != null) minFactor++; + if (mActivityTaskManager.mPreviousProcess != null) minFactor++; if (factor < minFactor) factor = minFactor; int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; for (int i=N-1; i>=0; i--) { @@ -21461,19 +21358,6 @@ public class ActivityManagerService extends IActivityManager.Stub app.thread.scheduleTrimMemory(curLevel); } catch (RemoteException e) { } - if (false) { - // For now we won't do this; our memory trimming seems - // to be good enough at this point that destroying - // activities causes more harm than good. - if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE - && app != mHomeProcess && app != mPreviousProcess) { - // Need to do this on its own message because the stack may not - // be in a consistent state at this point. - // For these apps we will also finish their activities - // to help them free memory. - mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); - } - } } app.trimMemoryLevel = curLevel; step++; @@ -22024,7 +21908,7 @@ public class ActivityManagerService extends IActivityManager.Stub // has been removed. for (int i=mRemovedProcesses.size()-1; i>=0; i--) { final ProcessRecord app = mRemovedProcesses.get(i); - if (app.activities.size() == 0 && app.recentTasks.size() == 0 + if (!app.hasActivitiesOrRecentTasks() && app.curReceivers.isEmpty() && app.services.size() == 0) { Slog.i( TAG, "Exiting empty application process " @@ -22043,7 +21927,7 @@ public class ActivityManagerService extends IActivityManager.Stub cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/); mRemovedProcesses.remove(i); - if (app.persistent) { + if (app.isPersistent()) { addAppLocked(app.info, null, false, null /* ABI override */); } } @@ -22069,7 +21953,7 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = mLruProcesses.get(i); - if (r.thread != null && r.persistent) { + if (r.thread != null && r.isPersistent()) { sendSignal(r.pid, sig); } } @@ -22574,7 +22458,7 @@ public class ActivityManagerService extends IActivityManager.Stub final int NA = apps.size(); for (int ia = 0; ia < NA; ia++) { final ProcessRecord app = apps.valueAt(ia); - if (app.persistent) { + if (app.isPersistent()) { // We don't kill persistent processes. continue; } @@ -22847,6 +22731,42 @@ public class ActivityManagerService extends IActivityManager.Stub public void closeSystemDialogs(String reason) { ActivityManagerService.this.closeSystemDialogs(reason); } + + public void killProcessesForRemovedTask(ArrayList<Object> procsToKill) { + synchronized (ActivityManagerService.this) { + for (int i = 0; i < procsToKill.size(); i++) { + final WindowProcessController wpc = + (WindowProcessController) procsToKill.get(i); + final ProcessRecord pr = (ProcessRecord) wpc.mOwner; + if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND + && pr.curReceivers.isEmpty()) { + pr.kill("remove task", true); + } else { + // We delay killing processes that are not in the background or running a + // receiver. + pr.waitingToKill = "remove task"; + } + } + } + } + + @Override + public boolean hasRunningActivity(int uid, @Nullable String packageName) { + if (packageName == null) return false; + + synchronized (ActivityManagerService.this) { + for (int i = 0; i < mLruProcesses.size(); i++) { + final ProcessRecord pr = mLruProcesses.get(i); + if (pr.uid != uid) { + continue; + } + if (pr.getWindowProcessController().hasRunningActivity(packageName)) { + return true; + } + } + } + return false; + } } /** diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 1611a384f4e3..9b088231345e 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -2,7 +2,7 @@ package com.android.server.am; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; -import static android.app.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT; +import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; @@ -154,7 +154,7 @@ class ActivityMetricsLogger { launchedActivityLaunchToken = info.launchedActivity.info.launchToken; launchedActivityAppRecordRequiredAbi = info.launchedActivity.app == null ? null - : info.launchedActivity.app.requiredAbi; + : info.launchedActivity.app.getRequiredAbi(); reason = info.reason; startingWindowDelayMs = info.startingWindowDelayMs; bindApplicationDelayMs = info.bindApplicationDelayMs; @@ -246,25 +246,11 @@ class ActivityMetricsLogger { // of caches might be purged so the time until it produces the first frame is very // interesting. final boolean processSwitch = processRecord == null - || !hasStartedActivity(processRecord, launchedActivity); + || !processRecord.getWindowProcessController().hasStartedActivity(launchedActivity); notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch); } - private boolean hasStartedActivity(ProcessRecord record, ActivityRecord launchedActivity) { - final ArrayList<ActivityRecord> activities = record.activities; - for (int i = activities.size() - 1; i >= 0; i--) { - final ActivityRecord activity = activities.get(i); - if (launchedActivity == activity) { - continue; - } - if (!activity.stopped) { - return true; - } - } - return false; - } - /** * Notifies the tracker the the activity is actually launching. * diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 7f3f8f34ce71..d40b9b4cb082 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -288,7 +288,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. - ProcessRecord app; // if non-null, hosting application + WindowProcessController app; // if non-null, hosting application private ActivityState mState; // current state we are in Bundle icicle; // last saved activity state PersistableBundle persistentState; // last persistently saved activity state @@ -622,7 +622,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } private void scheduleActivityMovedToDisplay(int displayId, Configuration config) { - if (app == null || app.thread == null) { + if (!attachedToProcess()) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.w(TAG, "Can't report activity moved to display - client not running, activityRecord=" + this + ", displayId=" + displayId); @@ -633,7 +633,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo "Reporting activity moved to display" + ", activityRecord=" + this + ", displayId=" + displayId + ", config=" + config); - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, MoveToDisplayItem.obtain(displayId, config)); } catch (RemoteException e) { // If process died, whatever. @@ -641,7 +641,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } private void scheduleConfigurationChanged(Configuration config) { - if (app == null || app.thread == null) { + if (attachedToProcess()) { if (DEBUG_CONFIGURATION) Slog.w(TAG, "Can't report activity configuration update - client not running" + ", activityRecord=" + this); @@ -651,7 +651,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + this + ", config: " + config); - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, ActivityConfigurationChangeItem.obtain(config)); } catch (RemoteException e) { // If process died, whatever. @@ -659,7 +659,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } void updateMultiWindowMode() { - if (task == null || task.getStack() == null || app == null || app.thread == null) { + if (task == null || task.getStack() == null || !attachedToProcess()) { return; } @@ -678,7 +678,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private void scheduleMultiWindowModeChanged(Configuration overrideConfig) { try { - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, MultiWindowModeChangeItem.obtain(mLastReportedMultiWindowMode, overrideConfig)); } catch (Exception e) { // If process died, I don't care. @@ -686,7 +686,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } void updatePictureInPictureMode(Rect targetStackBounds, boolean forceUpdate) { - if (task == null || task.getStack() == null || app == null || app.thread == null) { + if (task == null || task.getStack() == null || !attachedToProcess()) { return; } @@ -705,7 +705,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo private void schedulePictureInPictureModeChanged(Configuration overrideConfig) { try { - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, PipModeChangeItem.obtain(mLastReportedPictureInPictureMode, overrideConfig)); } catch (Exception e) { @@ -984,7 +984,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } } - void setProcess(ProcessRecord proc) { + void setProcess(WindowProcessController proc) { app = proc; final ActivityRecord root = task != null ? task.getRootActivity() : null; if (root == this) { @@ -992,6 +992,14 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } } + boolean hasProcess() { + return app != null; + } + + boolean attachedToProcess() { + return hasProcess() && app.hasThread(); + } + AppWindowContainerController getWindowContainerController() { return mWindowContainerController; } @@ -1366,7 +1374,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo clearOptionsLocked(); } - if (service.mAm != null) { + if (service != null) { service.getTaskChangeNotificationController().notifyTaskStackChanged(); } } @@ -1435,13 +1443,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // - It is currently resumed or paused. i.e. it is currently visible to the user and we want // the user to see the visual effects caused by the intent delivery now. // - The device is sleeping and it is the top activity behind the lock screen (b/6700897). - if ((mState == RESUMED || mState == PAUSED - || isTopActivityWhileSleeping) && app != null && app.thread != null) { + if ((mState == RESUMED || mState == PAUSED || isTopActivityWhileSleeping) + && attachedToProcess()) { try { ArrayList<ReferrerIntent> ar = new ArrayList<>(1); ar.add(rintent); service.getLifecycleManager().scheduleTransaction( - app.thread, appToken, NewIntentItem.obtain(ar, mState == PAUSED)); + app.getThread(), appToken, NewIntentItem.obtain(ar, mState == PAUSED)); unsent = false; } catch (RemoteException e) { Slog.w(TAG, "Exception thrown sending new intent to " + this, e); @@ -1744,7 +1752,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } setVisible(true); sleeping = false; - app.pendingUiClean = true; + app.setPendingUiClean(true); if (reportToClient) { makeClientVisible(); } else { @@ -1764,13 +1772,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo void makeClientVisible() { mClientVisibilityDeferred = false; try { - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, WindowVisibilityItem.obtain(true /* showWindow */)); if (shouldPauseWhenBecomingVisible()) { // An activity must be in the {@link PAUSING} state for the system to validate // the move to {@link PAUSED}. setState(PAUSING, "makeVisibleIfNeeded"); - service.getLifecycleManager().scheduleTransaction(app.thread, appToken, + service.getLifecycleManager().scheduleTransaction(app.getThread(), appToken, PauseActivityItem.obtain(finishing, false /* userLeaving */, configChangeFlags, false /* dontReport */)); } @@ -1816,7 +1824,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo stopFreezingScreenLocked(false); try { if (returningOptions != null) { - app.thread.scheduleOnNewActivityOptions(appToken, returningOptions.toBundle()); + app.getThread().scheduleOnNewActivityOptions(appToken, returningOptions.toBundle()); } } catch(RemoteException e) { } @@ -1850,9 +1858,9 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo stopped = false; if (isActivityTypeHome()) { - ProcessRecord app = task.mActivities.get(0).app; - if (app != null && app != service.mAm.mHomeProcess) { - service.mAm.mHomeProcess = app; + WindowProcessController app = task.mActivities.get(0).app; + if (hasProcess() && app != service.mHomeProcess) { + service.mHomeProcess = app; } } @@ -1873,8 +1881,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // Mark the point when the activity is resuming // TODO: To be more accurate, the mark should be before the onCreate, // not after the onResume. But for subsequent starts, onResume is fine. - if (app != null) { - cpuTimeAtResume = service.mAm.mProcessCpuTracker.getCpuTimeForPid(app.pid); + if (hasProcess()) { + cpuTimeAtResume = service.mAm.mProcessCpuTracker.getCpuTimeForPid(app.getPid()); } else { cpuTimeAtResume = 0; // Couldn't get the cpu time of process } @@ -1970,15 +1978,15 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // IApplicationToken - public boolean mayFreezeScreenLocked(ProcessRecord app) { + public boolean mayFreezeScreenLocked(WindowProcessController app) { // Only freeze the screen if this activity is currently attached to // an application, and that application is not blocked or unresponding. // In any other case, we can't count on getting the screen unfrozen, // so it is best to leave as-is. - return app != null && !app.crashing && !app.notResponding; + return hasProcess() && !app.isCrashing() && !app.isNotResponding(); } - public void startFreezingScreenLocked(ProcessRecord app, int configChanges) { + public void startFreezingScreenLocked(WindowProcessController app, int configChanges) { if (mayFreezeScreenLocked(app)) { mWindowContainerController.startFreezingScreen(configChanges); } @@ -2135,17 +2143,17 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo @Override public boolean keyDispatchingTimedOut(String reason, int windowPid) { ActivityRecord anrActivity; - ProcessRecord anrApp; + WindowProcessController anrApp; boolean windowFromSameProcessAsActivity; synchronized (service.mGlobalLock) { anrActivity = getWaitingHistoryRecordLocked(); anrApp = app; windowFromSameProcessAsActivity = - app == null || app.pid == windowPid || windowPid == -1; + !hasProcess() || app.getPid() == windowPid || windowPid == -1; } if (windowFromSameProcessAsActivity) { return service.mAm.inputDispatchingTimedOut( - anrApp, anrActivity, this, false, reason); + (ProcessRecord) anrApp.mOwner, anrActivity, this, false, reason); } else { // In this case another process added windows using this activity token. So, we call the // generic service input dispatch timed out method so that the right process is blamed. @@ -2202,9 +2210,9 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo if (!force && sleeping == _sleeping) { return; } - if (app != null && app.thread != null) { + if (attachedToProcess()) { try { - app.thread.scheduleSleeping(appToken, _sleeping); + app.getThread().scheduleSleeping(appToken, _sleeping); if (_sleeping && !mStackSupervisor.mGoingToSleepActivities.contains(this)) { mStackSupervisor.mGoingToSleepActivities.add(this); } @@ -2253,7 +2261,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } final boolean isDestroyable() { - if (finishing || app == null) { + if (finishing || !hasProcess()) { // This would be redundant. return false; } @@ -2593,7 +2601,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // If the activity isn't currently running, just leave the new configuration and it will // pick that up next time it starts. - if (app == null || app.thread == null) { + if (!attachedToProcess()) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Configuration doesn't matter not running " + this); stopFreezingScreenLocked(false); @@ -2614,7 +2622,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo startFreezingScreenLocked(app, globalChanges); forceNewConfig = false; preserveWindow &= isResizeOnlyChange(changes); - if (app == null || app.thread == null) { + if (!attachedToProcess()) { if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Config is destroying non-running " + this); stack.destroyActivityLocked(this, true, "config"); @@ -2774,7 +2782,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } else { lifecycleItem = PauseActivityItem.obtain(); } - final ClientTransaction transaction = ClientTransaction.obtain(app.thread, appToken); + final ClientTransaction transaction = ClientTransaction.obtain(app.getThread(), appToken); transaction.addCallback(callbackItem); transaction.setLifecycleStateRequest(lifecycleItem); service.getLifecycleManager().scheduleTransaction(transaction); @@ -2804,11 +2812,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo } private boolean isProcessRunning() { - ProcessRecord proc = app; + WindowProcessController proc = app; if (proc == null) { - proc = service.mAm.mProcessNames.get(processName, info.applicationInfo.uid); + proc = service.mProcessNames.get(processName, info.applicationInfo.uid); } - return proc != null && proc.thread != null; + return proc != null && proc.hasThread(); } /** @@ -3037,8 +3045,8 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo proto.write(STATE, mState.toString()); proto.write(VISIBLE, visible); proto.write(FRONT_OF_TASK, frontOfTask); - if (app != null) { - proto.write(PROC_ID, app.pid); + if (hasProcess()) { + proto.write(PROC_ID, app.getPid()); } proto.write(TRANSLUCENT, !fullscreen); proto.end(token); diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index d177702c49d3..9b01919c0aa4 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -367,9 +367,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; private static class ScheduleDestroyArgs { - final ProcessRecord mOwner; + final WindowProcessController mOwner; final String mReason; - ScheduleDestroyArgs(ProcessRecord owner, String reason) { + ScheduleDestroyArgs(WindowProcessController owner, String reason) { mOwner = owner; mReason = reason; } @@ -392,8 +392,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // so we need to be conservative and assume it isn't. Slog.w(TAG, "Activity pause timeout for " + r); synchronized (mService.mGlobalLock) { - if (r.app != null) { - mService.mAm.logAppTooSlow(r.app, r.pauseTime, "pausing " + r); + if (r.hasProcess()) { + mService.logAppTooSlow(r.app, r.pauseTime, "pausing " + r); } activityPausedLocked(r.appToken, true); } @@ -402,7 +402,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai ActivityRecord r = (ActivityRecord)msg.obj; synchronized (mService.mGlobalLock) { if (r.continueLaunchTickingLocked()) { - mService.mAm.logAppTooSlow(r.app, r.launchTickTime, "launching " + r); + mService.logAppTooSlow(r.app, r.launchTickTime, "launching " + r); } } } break; @@ -1453,15 +1453,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mService.mAm.updateCpuStats(); - if (prev.app != null && prev.app.thread != null) { + if (prev.attachedToProcess()) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev); try { EventLogTags.writeAmPauseActivity(prev.userId, System.identityHashCode(prev), prev.shortComponentName, "userLeaving=" + userLeaving); mService.mAm.updateUsageStats(prev, false); - mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken, - PauseActivityItem.obtain(prev.finishing, userLeaving, + mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(), + prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving, prev.configChangeFlags, pauseImmediately)); } catch (Exception e) { // Ignore exception, if process died other code will cleanup. @@ -1563,7 +1563,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev); prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false, "completedPausedLocked"); - } else if (prev.app != null) { + } else if (prev.hasProcess()) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev + " wasStopping=" + wasStopping + " visible=" + prev.visible); if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) { @@ -1620,9 +1620,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (prev != null) { prev.resumeKeyDispatchingLocked(); - if (prev.app != null && prev.cpuTimeAtResume > 0 + if (prev.hasProcess() && prev.cpuTimeAtResume > 0 && mService.mAm.mBatteryStatsService.isOnBattery()) { - long diff = mService.mAm.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid) + long diff = mService.mAm.mProcessCpuTracker.getCpuTimeForPid(prev.app.getPid()) - prev.cpuTimeAtResume; if (diff > 0) { BatteryStatsImpl bsi = mService.mAm.mBatteryStatsService.getActiveStatistics(); @@ -1904,7 +1904,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai true /* ignoreStopState */); } - if (r.app == null || r.app.thread == null) { + if (!r.attachedToProcess()) { if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop, resumeNextActivity, r)) { if (activityNdx >= activities.size()) { @@ -2136,11 +2136,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai switch (r.getState()) { case STOPPING: case STOPPED: - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Scheduling invisibility: " + r); - mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, - WindowVisibilityItem.obtain(false /* showWindow */)); + mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), + r.appToken, WindowVisibilityItem.obtain(false /* showWindow */)); } // Reset the flag indicating that an app can enter picture-in-picture once the @@ -2217,9 +2217,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (waitingActivity != null) { mWindowManager.setWindowOpaque(waitingActivity.appToken, false); - if (waitingActivity.app != null && waitingActivity.app.thread != null) { + if (waitingActivity.attachedToProcess()) { try { - waitingActivity.app.thread.scheduleTranslucentConversionComplete( + waitingActivity.app.getThread().scheduleTranslucentConversionComplete( waitingActivity.appToken, r != null); } catch (RemoteException e) { } @@ -2451,8 +2451,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // at the top of the LRU list, since we know we will be needing it // very soon and it would be a waste to let it get killed if it // happens to be sitting towards the end. - if (next.app != null && next.app.thread != null) { - mService.mAm.updateLruProcessLocked(next.app, true, null); + if (next.attachedToProcess()) { + next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, + true /* updateLru */, true /* activityChange */, false /* updateOomAdj */); } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); if (lastResumed != null) { @@ -2577,7 +2578,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai mStackSupervisor.mNoAnimActivities.clear(); ActivityStack lastStack = mStackSupervisor.getLastStack(); - if (next.app != null && next.app.thread != null) { + if (next.attachedToProcess()) { if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next + " stopped=" + next.stopped + " visible=" + next.visible); @@ -2618,9 +2619,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai next.setState(RESUMED, "resumeTopActivityInnerLocked"); - mService.mAm.updateLruProcessLocked(next.app, true, null); + next.app.updateProcessInfo(false /* updateServiceConnectionActivities */, + true /* updateLru */, true /* activityChange */, true /* updateOomAdj */); updateLRUListLocked(next); - mService.mAm.updateOomAdjLocked(); // Have the window manager re-evaluate the orientation of // the screen based on the new activity order. @@ -2662,8 +2663,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } try { - final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread, - next.appToken); + final ClientTransaction transaction = + ClientTransaction.obtain(next.app.getThread(), next.appToken); // Deliver all pending results. ArrayList<ResultInfo> a = next.results; if (a != null) { @@ -2691,11 +2692,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai next.sleeping = false; mService.mAm.getAppWarningsLocked().onResumeActivity(next); mService.mAm.showAskCompatModeDialogLocked(next); - next.app.pendingUiClean = true; - next.app.forceProcessStateUpTo(mService.mAm.mTopProcessState); + next.app.setPendingUiCleanAndForceProcessStateUpTo( + mService.mAm.mTopProcessState); next.clearOptionsLocked(); transaction.setLifecycleStateRequest( - ResumeActivityItem.obtain(next.app.repProcState, + ResumeActivityItem.obtain(next.app.getReportedProcState(), mService.isNextTransitionForward())); mService.getLifecycleManager().scheduleTransaction(transaction); @@ -3345,12 +3346,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r + " : who=" + resultWho + " req=" + requestCode + " res=" + resultCode + " data=" + data); - if (mResumedActivity == r && r.app != null && r.app.thread != null) { + if (mResumedActivity == r && r.attachedToProcess()) { try { ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); list.add(new ResultInfo(resultWho, requestCode, resultCode, data)); - mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, + mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken, ActivityResultItem.obtain(list)); return; } catch (Exception e) { @@ -3464,7 +3465,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { adjustFocusedActivityStack(r, "stopActivity"); r.resumeKeyDispatchingLocked(); try { @@ -3479,7 +3480,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } EventLogTags.writeAmStopActivity( r.userId, System.identityHashCode(r), r.shortComponentName); - mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, + mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken, StopActivityItem.obtain(r.visible, r.configChangeFlags)); if (shouldSleepOrShutDownActivities()) { r.setSleeping(true); @@ -3546,7 +3547,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * @return The task that was finished in this stack, {@code null} if top running activity does * not belong to the crashed app. */ - final TaskRecord finishTopCrashedActivityLocked(ProcessRecord app, String reason) { + final TaskRecord finishTopCrashedActivityLocked(WindowProcessController app, String reason) { ActivityRecord r = topRunningActivityLocked(); TaskRecord finishedTask = null; if (r == null || r.app != app) { @@ -3578,7 +3579,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai if (activityNdx >= 0) { r = mTaskHistory.get(taskNdx).mActivities.get(activityNdx); if (r.isState(RESUMED, PAUSING, PAUSED)) { - if (!r.isActivityTypeHome() || mService.mAm.mHomeProcess != r.app) { + if (!r.isActivityTypeHome() || mService.mHomeProcess != r.app) { Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); finishActivityLocked(r, Activity.RESULT_CANCELED, null, reason, false); @@ -3606,13 +3607,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // Check if any of the activities are using voice for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) { ActivityRecord r = tr.mActivities.get(activityNdx); - if (r.voiceSession != null - && r.voiceSession.asBinder() == sessionBinder) { + if (r.voiceSession != null && r.voiceSession.asBinder() == sessionBinder) { // Inform of cancellation r.clearVoiceSessionLocked(); try { - r.app.thread.scheduleLocalVoiceInteractionStarted((IBinder) r.appToken, - null); + r.app.getThread().scheduleLocalVoiceInteractionStarted( + r.appToken, null); } catch (RemoteException re) { // Ok } @@ -4002,7 +4002,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // TODO(b/64750076): Check if calling pid should really be -1. final int res = mService.getActivityStartController() .obtainStarter(destIntent, "navigateUpTo") - .setCaller(srec.app.thread) + .setCaller(srec.app.getThread()) .setActivityInfo(aInfo) .setResultTo(parent.appToken) .setCallingPid(-1) @@ -4169,13 +4169,13 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } - final void scheduleDestroyActivities(ProcessRecord owner, String reason) { + final void scheduleDestroyActivities(WindowProcessController owner, String reason) { Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG); msg.obj = new ScheduleDestroyArgs(owner, reason); mHandler.sendMessage(msg); } - private void destroyActivitiesLocked(ProcessRecord owner, String reason) { + private void destroyActivitiesLocked(WindowProcessController owner, String reason) { boolean lastIsOpaque = false; boolean activityRemoved = false; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { @@ -4220,7 +4220,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return false; } - final int releaseSomeActivitiesLocked(ProcessRecord app, ArraySet<TaskRecord> tasks, + final int releaseSomeActivitiesLocked(WindowProcessController app, ArraySet<TaskRecord> tasks, String reason) { // Iterate over tasks starting at the back (oldest) first. if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); @@ -4274,7 +4274,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, String reason) { if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(TAG_SWITCH, "Removing activity from " + reason + ": token=" + r - + ", app=" + (r.app != null ? r.app.processName : "(null)")); + + ", app=" + (r.hasProcess() ? r.app.mName : "(null)")); if (r.isState(DESTROYING, DESTROYED)) { if (DEBUG_STATES) Slog.v(TAG_STATES, "activity " + r + " already destroying." @@ -4290,23 +4290,23 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai cleanUpActivityLocked(r, false, false); - final boolean hadApp = r.app != null; + final boolean hadApp = r.hasProcess(); if (hadApp) { if (removeFromApp) { - r.app.activities.remove(r); - if (mService.mAm.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) { + r.app.removeActivity(r); + if (mService.mAm.mHeavyWeightProcess != null + && mService.mAm.mHeavyWeightProcess.getWindowProcessController() == r.app + && !r.app.hasActivities()) { mService.mAm.mHeavyWeightProcess = null; mService.mAm.mHandler.sendEmptyMessage( ActivityManagerService.CANCEL_HEAVY_NOTIFICATION_MSG); } - if (r.app.activities.isEmpty()) { + if (!r.app.hasActivities()) { // Update any services we are bound to that might care about whether // their client may have activities. - mService.mAm.mServices.updateServiceConnectionActivitiesLocked(r.app); // No longer have activities, so update LRU list and oom adj. - mService.mAm.updateLruProcessLocked(r.app, false, null); - mService.mAm.updateOomAdjLocked(); + r.app.updateProcessInfo(true, true, false, true); } } @@ -4314,7 +4314,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai try { if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "Destroying: " + r); - mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken, + mService.getLifecycleManager().scheduleTransaction(r.app.getThread(), r.appToken, DestroyActivityItem.obtain(r.finishing, r.configChangeFlags)); } catch (Exception e) { // We can just ignore exceptions here... if the process @@ -4405,7 +4405,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list, - ProcessRecord app, String listName) { + WindowProcessController app, String listName) { int i = list.size(); if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP, "Removing app " + app + " from list " + listName + " with " + i + " entries"); @@ -4421,7 +4421,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } - private boolean removeHistoryRecordsForAppLocked(ProcessRecord app) { + private boolean removeHistoryRecordsForAppLocked(WindowProcessController app) { removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities"); removeHistoryRecordsForAppLocked(mStackSupervisor.mStoppingActivities, app, "mStoppingActivities"); @@ -4895,7 +4895,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai || (packageName == null && r.userId == userId); if ((userId == UserHandle.USER_ALL || r.userId == userId) && (sameComponent || r.getTask() == lastTask) - && (r.app == null || evenPersistent || !r.app.persistent)) { + && (r.app == null || evenPersistent || !r.app.isPersistent())) { if (!doit) { if (r.finishing) { // If this activity is just finishing, then it is not @@ -4915,8 +4915,8 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai didSomething = true; Slog.i(TAG, " Force finishing activity " + r); if (sameComponent) { - if (r.app != null) { - r.app.removed = true; + if (r.hasProcess()) { + r.app.setRemoved(true); } r.app = null; } @@ -4987,7 +4987,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai * @param app The app of the activity that died. * @return result from removeHistoryRecordsForAppLocked. */ - boolean handleAppDiedLocked(ProcessRecord app) { + boolean handleAppDiedLocked(WindowProcessController app) { if (mPausingActivity != null && mPausingActivity.app == app) { if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG_PAUSE, "App died while pausing: " + mPausingActivity); @@ -5001,7 +5001,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai return removeHistoryRecordsForAppLocked(app); } - void handleAppCrashLocked(ProcessRecord app) { + void handleAppCrashLocked(WindowProcessController app) { for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 7503ec2e86ef..f49943e2f0c8 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -109,7 +109,9 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; -import android.app.ActivityTaskManagerInternal.SleepToken; +import android.app.ActivityManagerInternal; +import com.android.internal.util.function.pooled.PooledLambda; +import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import android.app.ActivityOptions; import android.app.AppOpsManager; import android.app.ProfilerInfo; @@ -580,21 +582,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D final ActivityRecord sourceRecord; final int startFlags; final ActivityStack stack; - final ProcessRecord callerApp; + final WindowProcessController callerApp; PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, - int _startFlags, ActivityStack _stack, ProcessRecord _callerApp) { + int _startFlags, ActivityStack _stack, WindowProcessController app) { r = _r; sourceRecord = _sourceRecord; startFlags = _startFlags; stack = _stack; - callerApp = _callerApp; + callerApp = app; } void sendErrorResult(String message) { try { - if (callerApp.thread != null) { - callerApp.thread.scheduleCrash(message); + if (callerApp.hasThread()) { + callerApp.getThread().scheduleCrash(message); } } catch (RemoteException e) { Slog.e(TAG, "Exception scheduling crash of failed " @@ -1399,12 +1401,13 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D beginDeferResume(); try { - r.startFreezingScreenLocked(app, 0); + final WindowProcessController proc = app.getWindowProcessController(); + r.startFreezingScreenLocked(proc, 0); // schedule launch ticks to collect information about slow apps. r.startLaunchTickingLocked(); - r.setProcess(app); + r.setProcess(proc); if (getKeyguardController().isKeyguardLocked()) { r.notifyUnknownVisibilityLaunched(); @@ -1448,12 +1451,8 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r); - int idx = app.activities.indexOf(r); - if (idx < 0) { - app.activities.add(r); - } - mService.mAm.updateLruProcessLocked(app, true, null); - mService.mAm.updateOomAdjLocked(); + proc.addActivityIfNeeded(r); + proc.updateProcessInfo(false, true, true, true); final LockTaskController lockTaskController = mService.getLockTaskController(); if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE @@ -1483,7 +1482,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D System.identityHashCode(r), task.taskId, r.shortComponentName); if (r.isActivityTypeHome()) { // Home process is the root process of the task. - mService.mAm.mHomeProcess = task.mActivities.get(0).app; + mService.mHomeProcess = task.mActivities.get(0).app; } mService.mAm.notifyPackageUse(r.intent.getComponent().getPackageName(), PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY); @@ -1534,9 +1533,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // and override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, - r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, - r.persistentState, results, newIntents, mService.isNextTransitionForward(), - profilerInfo)); + r.launchedFromPackage, task.voiceInteractor, app.getReportedProcState(), + r.icicle, r.persistentState, results, newIntents, + mService.isNextTransitionForward(), profilerInfo)); // Set desired final state. final ActivityLifecycleItem lifecycleItem; @@ -1587,7 +1586,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // This is the first time we failed -- restart process and // retry. r.launchFailed = true; - app.activities.remove(r); + proc.removeActivity(r); throw e; } } finally { @@ -1625,7 +1624,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Update any services we are bound to that might care about whether // their client may have activities. if (r.app != null) { - mService.mAm.mServices.updateServiceConnectionActivitiesLocked(r.app); + r.app.updateServiceConnectionActivities(); } return true; @@ -2129,7 +2128,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return r; } - boolean handleAppDiedLocked(ProcessRecord app) { + boolean handleAppDiedLocked(WindowProcessController app) { boolean hasVisibleActivities = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); @@ -2192,7 +2191,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // First, found out what is currently the foreground app, so that // we don't blow away the previous app if this activity is being // hosted by the process that is actually still the foreground. - ProcessRecord fgApp = null; + WindowProcessController fgApp = null; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { @@ -2211,11 +2210,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Now set this one as the previous process, only if that really // makes sense to. - if (r.app != null && fgApp != null && r.app != fgApp - && r.lastVisibleTime > mService.mAm.mPreviousProcessVisibleTime - && r.app != mService.mAm.mHomeProcess) { - mService.mAm.mPreviousProcess = r.app; - mService.mAm.mPreviousProcessVisibleTime = r.lastVisibleTime; + if (r.hasProcess() && fgApp != null && r.app != fgApp + && r.lastVisibleTime > mService.mPreviousProcessVisibleTime + && r.app != mService.mHomeProcess) { + mService.mPreviousProcess = r.app; + mService.mPreviousProcessVisibleTime = r.lastVisibleTime; } } @@ -2261,7 +2260,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D * @param reason Reason to perform this action. * @return The task that was finished in this stack, {@code null} if haven't found any. */ - TaskRecord finishTopCrashedActivitiesLocked(ProcessRecord app, String reason) { + TaskRecord finishTopCrashedActivitiesLocked(WindowProcessController app, String reason) { TaskRecord finishedTask = null; ActivityStack focusedStack = getFocusedStack(); for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { @@ -3111,36 +3110,34 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Determine if the process(es) for this task should be killed. final String pkg = component.getPackageName(); - ArrayList<ProcessRecord> procsToKill = new ArrayList<>(); - ArrayMap<String, SparseArray<ProcessRecord>> pmap = mService.mAm.mProcessNames.getMap(); + ArrayList<Object> procsToKill = new ArrayList<>(); + ArrayMap<String, SparseArray<WindowProcessController>> pmap = + mService.mProcessNames.getMap(); for (int i = 0; i < pmap.size(); i++) { - SparseArray<ProcessRecord> uids = pmap.valueAt(i); + SparseArray<WindowProcessController> uids = pmap.valueAt(i); for (int j = 0; j < uids.size(); j++) { - ProcessRecord proc = uids.valueAt(j); - if (proc.userId != tr.userId) { + WindowProcessController proc = uids.valueAt(j); + if (proc.mUserId != tr.userId) { // Don't kill process for a different user. continue; } - if (proc == mService.mAm.mHomeProcess) { + if (proc == mService.mHomeProcess) { // Don't kill the home process along with tasks from the same package. continue; } - if (!proc.pkgList.containsKey(pkg)) { + if (!proc.mPkgList.contains(pkg)) { // Don't kill process that is not associated with this task. continue; } - for (int k = 0; k < proc.activities.size(); k++) { - TaskRecord otherTask = proc.activities.get(k).getTask(); - if (tr.taskId != otherTask.taskId && otherTask.inRecents) { - // Don't kill process(es) that has an activity in a different task that is - // also in recents. - return; - } + if (!proc.shouldKillProcessForRemovedTask(tr)) { + // Don't kill process(es) that has an activity in a different task that is also + // in recents. + return; } - if (proc.foregroundServices) { + if (proc.hasForegroundServices()) { // Don't kill process(es) with foreground service. return; } @@ -3150,17 +3147,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } - // Kill the running processes. - for (int i = 0; i < procsToKill.size(); i++) { - ProcessRecord pr = procsToKill.get(i); - if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND - && pr.curReceivers.isEmpty()) { - pr.kill("remove task", true); - } else { - // We delay killing processes that are not in the background or running a receiver. - pr.waitingToKill = "remove task"; - } - } + // Kill the running processes. Post on handle since we don't want to hold the service lock + // while calling into AM. + final Runnable r = PooledLambda.obtainRunnable( + ActivityManagerInternal::killProcessesForRemovedTask, mService.mAmInternal, + procsToKill); + mService.mH.post(r); } /** @@ -3663,7 +3655,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return false; } - void handleAppCrashLocked(ProcessRecord app) { + void handleAppCrashLocked(WindowProcessController app) { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { @@ -3765,7 +3757,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } - void scheduleDestroyAllActivities(ProcessRecord app, String reason) { + void scheduleDestroyAllActivities(WindowProcessController app, String reason) { for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { @@ -3775,44 +3767,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } } - void releaseSomeActivitiesLocked(ProcessRecord app, String reason) { - // Examine all activities currently running in the process. - TaskRecord firstTask = null; + void releaseSomeActivitiesLocked(WindowProcessController app, String reason) { // Tasks is non-null only if two or more tasks are found. - ArraySet<TaskRecord> tasks = null; - if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + app); - for (int i = 0; i < app.activities.size(); i++) { - ActivityRecord r = app.activities.get(i); - // First, if we find an activity that is in the process of being destroyed, - // then we just aren't going to do anything for now; we want things to settle - // down before we try to prune more activities. - if (r.finishing || r.isState(DESTROYING, DESTROYED)) { - if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); - return; - } - // Don't consider any activies that are currently not in a state where they - // can be destroyed. - if (r.visible || !r.stopped || !r.haveState - || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) { - if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); - continue; - } - - final TaskRecord task = r.getTask(); - if (task != null) { - if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task - + " from " + r); - if (firstTask == null) { - firstTask = task; - } else if (firstTask != task) { - if (tasks == null) { - tasks = new ArraySet<>(); - tasks.add(firstTask); - } - tasks.add(task); - } - } - } + ArraySet<TaskRecord> tasks = app.getReleaseSomeActivitiesTasks(); if (tasks == null) { if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Didn't find two or more tasks to release"); return; @@ -4205,16 +4162,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D pw.print(innerPrefix); pw.println(r.app); } } - if (client && r.app != null && r.app.thread != null) { + if (client && r.attachedToProcess()) { // flush anything that is already in the PrintWriter since the thread is going // to write to the file descriptor directly pw.flush(); try { TransferPipe tp = new TransferPipe(); try { - r.app.thread.dumpActivity(tp.getWriteFd(), r.appToken, innerPrefix, args); - // Short timeout, since blocking here can - // deadlock with the application. + r.app.getThread().dumpActivity( + tp.getWriteFd(), r.appToken, innerPrefix, args); + // Short timeout, since blocking here can deadlock with the application. tp.go(fd, 2000); } finally { tp.kill(); @@ -4574,7 +4531,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D for (int i = task.mActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = task.mActivities.get(i); - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { mMultiWindowModeChangedActivities.add(r); } } @@ -4597,7 +4554,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds) { for (int i = task.mActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = task.mActivities.get(i); - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { mPipModeChangedActivities.add(r); // If we are scheduling pip change, then remove this activity from multi-window // change list as the processing of pip change will make sure multi-window changed @@ -4616,7 +4573,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mHandler.removeMessages(REPORT_PIP_MODE_CHANGED_MSG); for (int i = task.mActivities.size() - 1; i >= 0; i--) { final ActivityRecord r = task.mActivities.get(i); - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { r.updatePictureInPictureMode(targetStackBounds, forceUpdate); } } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 6f58aeab0cab..dac77150b314 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -720,10 +720,11 @@ class ActivityStarter { abort |= !mService.mAm.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); + final WindowProcessController callerWpc = + callerApp != null ? callerApp.getWindowProcessController() : null; // Merge the two options bundles, while realCallerOptions takes precedence. ActivityOptions checkedOptions = options != null - ? options.getOptions(intent, aInfo, callerApp, mSupervisor) - : null; + ? options.getOptions(intent, aInfo, callerWpc, mSupervisor) : null; if (allowPendingRemoteAnimationRegistryLookup) { checkedOptions = mService.getActivityStartController() .getPendingRemoteAnimationRegistry() @@ -847,7 +848,7 @@ class ActivityStarter { if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start")) { mController.addPendingActivityLaunch(new PendingActivityLaunch(r, - sourceRecord, startFlags, stack, callerApp)); + sourceRecord, startFlags, stack, callerWpc)); ActivityOptions.abort(checkedOptions); return ActivityManager.START_SWITCHES_CANCELED; } @@ -1057,13 +1058,8 @@ class ActivityStarter { } newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target)); - if (heavy.activities.size() > 0) { - ActivityRecord hist = heavy.activities.get(0); - newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, - hist.packageName); - newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, - hist.getTask().taskId); - } + heavy.getWindowProcessController().updateIntentForHeavyWeightActivity( + newIntent); newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, aInfo.packageName); newIntent.setFlags(intent.getFlags()); @@ -1364,7 +1360,7 @@ class ActivityStarter { final boolean dontStart = top != null && mStartActivity.resultTo == null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId - && top.app != null && top.app.thread != null + && top.attachedToProcess() && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)); if (dontStart) { diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java index d554e0f3c713..d47fb4401e5b 100644 --- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java @@ -26,10 +26,11 @@ import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STOP_APP_SWITCHES; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; +import static com.android.server.am.ActivityManagerService.dumpStackTraces; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW; import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; @@ -46,7 +47,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; -import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; @@ -56,7 +56,6 @@ import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; -import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; @@ -114,7 +113,7 @@ import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; -import android.app.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.IActivityController; import android.app.IActivityTaskManager; @@ -150,7 +149,9 @@ import android.graphics.Rect; import android.metrics.LogMaker; import android.net.Uri; import android.os.Binder; +import android.os.Build; import android.os.Bundle; +import android.os.FileUtils; import android.os.Handler; import android.os.IBinder; import android.os.LocaleList; @@ -159,6 +160,7 @@ import android.os.Message; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; +import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UpdateLock; @@ -168,6 +170,7 @@ import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; import android.telecom.TelecomManager; import android.text.TextUtils; +import android.text.format.Time; import android.util.ArrayMap; import android.util.EventLog; import android.util.Log; @@ -176,6 +179,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.StatsLog; +import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationAdapter; @@ -184,6 +188,7 @@ import android.view.RemoteAnimationDefinition; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.app.IVoiceInteractor; +import com.android.internal.app.ProcessMap; import com.android.internal.logging.MetricsLogger; import com.android.internal.os.logging.MetricsLoggerWrapper; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -199,10 +204,13 @@ import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.WindowManagerService; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; +import java.util.Locale; /** * System service for managing activities and their containers (task, stacks, displays,... ). @@ -228,6 +236,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Object mGlobalLock; ActivityStackSupervisor mStackSupervisor; WindowManagerService mWindowManager; + /** All processes currently running that might have a window organized by name. */ + final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>(); + /** This is the process holding what we currently consider to be the "home" activity. */ + WindowProcessController mHomeProcess; + /** + * This is the process holding the activity the user last visited that is in a different process + * from the one they are currently in. + */ + WindowProcessController mPreviousProcess; + /** The time at which the previous process was last visible. */ + long mPreviousProcessVisibleTime; + /** List of intents that were used to start the most recent tasks. */ private RecentTasks mRecentTasks; /** State of external calls telling us if the device is awake or asleep. */ @@ -443,7 +463,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // TODO: Will be converted to WM lock once transition is complete. void setActivityManagerService(ActivityManagerService am) { mAm = am; - mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mGlobalLock = mAm; mH = new H(mAm.mHandlerThread.getLooper()); mUiHandler = new UiHandler(); @@ -464,6 +483,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mKeyguardController = mStackSupervisor.getKeyguardController(); } + void onActivityManagerInternalAdded() { + mAmInternal = LocalServices.getService(ActivityManagerInternal.class); + } + protected ActivityStackSupervisor createStackSupervisor() { final ActivityStackSupervisor supervisor = new ActivityStackSupervisor(this, mH.getLooper()); supervisor.initialize(); @@ -621,7 +644,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { SafeActivityOptions.abort(options); return false; } - if (r.app == null || r.app.thread == null) { + if (!r.attachedToProcess()) { // The caller is not running... d'oh! SafeActivityOptions.abort(options); return false; @@ -701,7 +724,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // TODO(b/64750076): Check if calling pid should really be -1. final int res = getActivityStartController() .obtainStarter(intent, "startNextMatchingActivity") - .setCaller(r.app.thread) + .setCaller(r.app.getThread()) .setResolvedType(r.resolvedType) .setActivityInfo(aInfo) .setResultTo(resultTo != null ? resultTo.appToken : null) @@ -804,12 +827,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (sourceRecord.app == null) { throw new SecurityException("Called without a process attached to activity"); } - if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) { + if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) { // This is still okay, as long as this activity is running under the // uid of the original calling activity. - if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { + if (sourceRecord.app.mUid != sourceRecord.launchedFromUid) { throw new SecurityException( - "Calling activity in uid " + sourceRecord.app.uid + "Calling activity in uid " + sourceRecord.app.mUid + " must be system uid or original calling uid " + sourceRecord.launchedFromUid); } @@ -830,7 +853,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } if (userId == UserHandle.USER_NULL) { - userId = UserHandle.getUserId(sourceRecord.app.uid); + userId = UserHandle.getUserId(sourceRecord.app.mUid); } // TODO: Switch to user app stacks here. @@ -1062,20 +1085,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { final long origId = Binder.clearCallingIdentity(); - synchronized (mGlobalLock) { - ActivityStack stack = ActivityRecord.getStackLocked(token); - if (stack != null) { - ActivityRecord r = - mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */, - false /* processPausingActivities */, config); - if (stopProfiling) { - if ((mAm.mProfileProc == r.app) && mAm.mProfilerInfo != null) { - mAm.clearProfilerLocked(); - } + try { + WindowProcessController proc = null; + synchronized (mGlobalLock) { + ActivityStack stack = ActivityRecord.getStackLocked(token); + if (stack == null) { + return; + } + final ActivityRecord r = mStackSupervisor.activityIdleInternalLocked(token, + false /* fromTimeout */, false /* processPausingActivities */, config); + if (r != null) { + proc = r.app; + } + if (stopProfiling && proc != null) { + proc.clearProfilerIfNeeded(); } } + } finally { + Binder.restoreCallingIdentity(origId); } - Binder.restoreCallingIdentity(origId); } @Override @@ -2237,9 +2265,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mH.post(() -> { synchronized (mGlobalLock) { ActivityRecord r = ActivityRecord.forTokenLocked(token); - if (r != null && r.app != null && r.app.thread != null) { + if (r != null && r.attachedToProcess()) { try { - r.app.thread.scheduleEnterAnimationComplete(r.appToken); + r.app.getThread().scheduleEnterAnimationComplete(r.appToken); } catch (RemoteException e) { } } @@ -2477,7 +2505,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); try { - ProcessRecord app = mAm.getRecordForAppLocked(appInt); + WindowProcessController app = + mAm.getRecordForAppLocked(appInt).getWindowProcessController(); mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); } finally { Binder.restoreCallingIdentity(origId); @@ -2777,7 +2806,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Slog.w(TAG, "getAssistContextExtras failed: no top activity"); return null; } - if (activity.app == null || activity.app.thread == null) { + if (!activity.attachedToProcess()) { Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); return null; } @@ -2797,7 +2826,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + " couldn't be found"); return null; } - if (activity.app == null || activity.app.thread == null) { + if (!activity.attachedToProcess()) { Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity); return null; } @@ -2809,7 +2838,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { extras.putAll(args); } extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); - extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid); + extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.mUid); pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras, userHandle); @@ -2820,8 +2849,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mViSessionId++; } try { - activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType, - mViSessionId, flags); + activity.app.getThread().requestAssistContextExtras(activity.appToken, pae, + requestType, mViSessionId, flags); mPendingAssistExtras.add(pae); mUiHandler.postDelayed(pae, timeout); } catch (RemoteException e) { @@ -3800,7 +3829,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mAm.mPidsSelfLocked) { final int pid = Binder.getCallingPid(); final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid); - mVrController.setVrThreadLocked(tid, pid, proc); + mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController()); } } } @@ -3905,7 +3934,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRecentTasks.notifyTaskPersisterLocked(task, flush); } - void onTopProcChangedLocked(ProcessRecord proc) { + void onTopProcChangedLocked(WindowProcessController proc) { mVrController.onTopProcChangedLocked(proc); } @@ -4307,6 +4336,65 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return kept; } + void logAppTooSlow(WindowProcessController app, long startTime, String msg) { + if (true || Build.IS_USER) { + return; + } + + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + StrictMode.allowThreadDiskWrites(); + try { + File tracesDir = new File("/data/anr"); + File tracesFile = null; + try { + tracesFile = File.createTempFile("app_slow", null, tracesDir); + + StringBuilder sb = new StringBuilder(); + Time tobj = new Time(); + tobj.set(System.currentTimeMillis()); + sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); + sb.append(": "); + TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); + sb.append(" since "); + sb.append(msg); + FileOutputStream fos = new FileOutputStream(tracesFile); + fos.write(sb.toString().getBytes()); + if (app == null) { + fos.write("\n*** No application process!".getBytes()); + } + fos.close(); + FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- + } catch (IOException e) { + Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesFile, e); + return; + } + + if (app != null && app.getPid() > 0) { + ArrayList<Integer> firstPids = new ArrayList<Integer>(); + firstPids.add(app.getPid()); + dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, null, null); + } + + File lastTracesFile = null; + File curTracesFile = null; + for (int i=9; i>=0; i--) { + String name = String.format(Locale.US, "slow%02d.txt", i); + curTracesFile = new File(tracesDir, name); + if (curTracesFile.exists()) { + if (lastTracesFile != null) { + curTracesFile.renameTo(lastTracesFile); + } else { + curTracesFile.delete(); + } + } + lastTracesFile = curTracesFile; + } + tracesFile.renameTo(curTracesFile); + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } + } + final class H extends Handler { public H(Looper looper) { super(looper, null, true); @@ -4487,26 +4575,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public boolean hasRunningActivity(int uid, @Nullable String packageName) { - if (packageName == null) return false; - - synchronized (mGlobalLock) { - for (int i = 0; i < mAm.mLruProcesses.size(); i++) { - final ProcessRecord processRecord = mAm.mLruProcesses.get(i); - if (processRecord.uid == uid) { - for (int j = 0; j < processRecord.activities.size(); j++) { - final ActivityRecord activityRecord = processRecord.activities.get(j); - if (packageName.equals(activityRecord.packageName)) { - return true; - } - } - } - } - } - return false; - } - - @Override public void registerScreenObserver(ScreenObserver observer) { mScreenObservers.add(observer); } @@ -4575,5 +4643,31 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { caller, callingPid, callingUid); } } + + @Override + public void onProcessAdded(WindowProcessController proc) { + synchronized (mGlobalLock) { + mProcessNames.put(proc.mName, proc.mUid, proc); + } + } + + @Override + public void onProcessRemoved(String name, int uid) { + synchronized (mGlobalLock) { + mProcessNames.remove(name, uid); + } + } + + @Override + public void onCleanUpApplicationRecord(WindowProcessController proc) { + synchronized (mGlobalLock) { + if (proc == mHomeProcess) { + mHomeProcess = null; + } + if (proc == mPreviousProcess) { + mPreviousProcess = null; + } + } + } } } diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java index 68c63a2d595b..cde633dddb3b 100644 --- a/services/core/java/com/android/server/am/AppErrorDialog.java +++ b/services/core/java/com/android/server/am/AppErrorDialog.java @@ -92,7 +92,7 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR | WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; getWindow().setAttributes(attrs); - if (mProc.persistent) { + if (mProc.isPersistent()) { getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 5719490ad1ba..7db98b35dfc1 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -25,7 +25,6 @@ import com.android.server.Watchdog; import android.app.ActivityManager; import android.app.ActivityOptions; -import android.app.ActivityThread; import android.app.AppOpsManager; import android.app.ApplicationErrorReport; import android.app.Dialog; @@ -45,7 +44,6 @@ import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; import android.util.EventLog; -import android.util.Log; import android.util.Slog; import android.util.StatsLog; import android.util.SparseArray; @@ -57,7 +55,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.Set; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; @@ -314,9 +311,9 @@ class AppErrors { } void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { - app.crashing = false; + app.setCrashing(false); app.crashingReport = null; - app.notResponding = false; + app.setNotResponding(false); app.notRespondingReport = null; if (app.anrDialog == fromDialog) { app.anrDialog = null; @@ -409,7 +406,7 @@ class AppErrors { // If a persistent app is stuck in a crash loop, the device isn't very // usable, so we want to consider sending out a rescue party. - if (r != null && r.persistent) { + if (r != null && r.isPersistent()) { RescueParty.notePersistentAppCrash(mContext, r.uid); } @@ -493,8 +490,8 @@ class AppErrors { long orig = Binder.clearCallingIdentity(); try { // Kill it with fire! - mService.mStackSupervisor.handleAppCrashLocked(r); - if (!r.persistent) { + mService.mStackSupervisor.handleAppCrashLocked(r.getWindowProcessController()); + if (!r.isPersistent()) { mService.removeProcessLocked(r, false, false, "crash"); mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); } @@ -571,11 +568,11 @@ class AppErrors { private boolean makeAppCrashingLocked(ProcessRecord app, String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { - app.crashing = true; + app.setCrashing(true); app.crashingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); startAppProblemLocked(app); - app.stopFreezingAllLocked(); + app.getWindowProcessController().stopFreezingActivities(); return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace, data); } @@ -643,7 +640,7 @@ class AppErrors { return null; } - if (!r.crashing && !r.notResponding && !r.forceCrashReport) { + if (!r.isCrashing() && !r.isNotResponding() && !r.forceCrashReport) { return null; } @@ -654,10 +651,10 @@ class AppErrors { report.time = timeMillis; report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; - if (r.crashing || r.forceCrashReport) { + if (r.isCrashing() || r.forceCrashReport) { report.type = ApplicationErrorReport.TYPE_CRASH; report.crashInfo = crashInfo; - } else if (r.notResponding) { + } else if (r.isNotResponding()) { report.type = ApplicationErrorReport.TYPE_ANR; report.anrInfo = new ApplicationErrorReport.AnrInfo(); @@ -715,8 +712,8 @@ class AppErrors { + " has crashed too many times: killing!"); EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, app.userId, app.info.processName, app.uid); - mService.mStackSupervisor.handleAppCrashLocked(app); - if (!app.persistent) { + mService.mStackSupervisor.handleAppCrashLocked(app.getWindowProcessController()); + if (!app.isPersistent()) { // We don't want to start this process again until the user // explicitly does so... but for persistent process, we really // need to keep it running. If a persistent process is actually @@ -744,7 +741,7 @@ class AppErrors { mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); } else { final TaskRecord affectedTask = - mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app, reason); + mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app.getWindowProcessController(), reason); if (data != null) { data.task = affectedTask; } @@ -762,21 +759,11 @@ class AppErrors { // replaced by a third-party app, clear the package preferred activities from packages // with a home activity running in the process to prevent a repeatedly crashing app // from blocking the user to manually clear the list. - final ArrayList<ActivityRecord> activities = app.activities; - if (app == mService.mHomeProcess && activities.size() > 0 - && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { - for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - if (r.isActivityTypeHome()) { - Log.i(TAG, "Clearing package preferred activities from " + r.packageName); - try { - ActivityThread.getPackageManager() - .clearPackagePreferredActivities(r.packageName); - } catch (RemoteException c) { - // pm is in same process, this will never happen. - } - } - } + final WindowProcessController proc = app.getWindowProcessController(); + final WindowProcessController homeProc = mService.mActivityTaskManager.mHomeProcess; + if (proc == homeProc && proc.hasActivities() + && (homeProc.mInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + proc.clearPackagePreferredForHomeActivities(); } if (!app.isolated) { @@ -917,10 +904,10 @@ class AppErrors { if (mService.mShuttingDown) { Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); return; - } else if (app.notResponding) { + } else if (app.isNotResponding()) { Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); return; - } else if (app.crashing) { + } else if (app.isCrashing()) { Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); return; } else if (app.killedByAm) { @@ -933,7 +920,7 @@ class AppErrors { // In case we come through here for the same app before completing // this one, mark as anring now so we will bail out. - app.notResponding = true; + app.setNotResponding(true); // Log the ANR to the event log. EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, @@ -946,8 +933,8 @@ class AppErrors { isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app); if (!isSilentANR) { int parentPid = app.pid; - if (parent != null && parent.app != null && parent.app.pid > 0) { - parentPid = parent.app.pid; + if (parent != null && parent.app != null && parent.app.getPid() > 0) { + parentPid = parent.app.getPid(); } if (parentPid != app.pid) firstPids.add(parentPid); @@ -958,7 +945,7 @@ class AppErrors { if (r != null && r.thread != null) { int pid = r.pid; if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { - if (r.persistent) { + if (r.isPersistent()) { firstPids.add(pid); if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); } else if (r.treatLikeActivity) { @@ -1100,12 +1087,12 @@ class AppErrors { private void makeAppNotRespondingLocked(ProcessRecord app, String activity, String shortMsg, String longMsg) { - app.notResponding = true; + app.setNotResponding(true); app.notRespondingReport = generateProcessError(app, ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, activity, shortMsg, longMsg, null); startAppProblemLocked(app); - app.stopFreezingAllLocked(); + app.getWindowProcessController().stopFreezingActivities(); } void handleShowAnrUi(Message msg) { diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java index 8a88a69a7d82..7c983ff427ad 100644 --- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java +++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java @@ -157,7 +157,7 @@ final class AppNotRespondingDialog extends BaseErrorDialog implements View.OnCli System.currentTimeMillis(), null); } - app.notResponding = false; + app.setNotResponding(false); app.notRespondingReport = null; if (app.anrDialog == AppNotRespondingDialog.this) { app.anrDialog = null; diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java index 037f245dfc1f..395b0da15f45 100644 --- a/services/core/java/com/android/server/am/AssistDataRequester.java +++ b/services/core/java/com/android/server/am/AssistDataRequester.java @@ -17,13 +17,12 @@ package com.android.server.am; import static android.app.ActivityManager.ASSIST_CONTEXT_FULL; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_NONE; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; import android.app.ActivityTaskManager; import android.app.AppOpsManager; -import android.app.IActivityManager; import android.app.IAssistDataReceiver; import android.content.Context; import android.graphics.Bitmap; diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index c9a26cbb3287..a9fd51d93fe4 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -304,7 +304,7 @@ public final class BroadcastQueue { app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId, - app.repProcState); + app.getReportedProcState()); if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Process cur broadcast " + r + " DELIVERED for app " + app); started = true; @@ -492,7 +492,7 @@ public final class BroadcastQueue { // correctly ordered with other one-way calls. try { app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, - data, extras, ordered, sticky, sendingUser, app.repProcState); + data, extras, ordered, sticky, sendingUser, app.getReportedProcState()); // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting // DeadObjectException when the process isn't actually dead. //} catch (DeadObjectException ex) { @@ -618,7 +618,7 @@ public final class BroadcastQueue { } if (!skip && (filter.receiverList.app == null || filter.receiverList.app.killed - || filter.receiverList.app.crashing)) { + || filter.receiverList.app.isCrashing())) { Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r + " to " + filter.receiverList + ": process gone or crashing"); skip = true; @@ -885,7 +885,7 @@ public final class BroadcastQueue { synchronized (mService.mPidsSelfLocked) { ProcessRecord proc = mService.mPidsSelfLocked.get( mPendingBroadcast.curApp.pid); - isDead = proc == null || proc.crashing; + isDead = proc == null || proc.isCrashing(); } } else { final ProcessRecord proc = mService.mProcessNames.get( @@ -1210,7 +1210,7 @@ public final class BroadcastQueue { + " (uid " + r.callingUid + ")"); skip = true; } - if (r.curApp != null && r.curApp.crashing) { + if (r.curApp != null && r.curApp.isCrashing()) { // If the target process is crashing, just skip it. Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r + " to " + r.curApp + ": process crashing"); diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java index fb55a4719ae2..657e0ebbdc5f 100644 --- a/services/core/java/com/android/server/am/KeyguardController.java +++ b/services/core/java/com/android/server/am/KeyguardController.java @@ -19,6 +19,13 @@ package com.android.server.am; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; +import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; +import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; +import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; +import static android.view.WindowManager.TRANSIT_UNSET; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE; import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER; @@ -27,15 +34,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED; import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING; -import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; -import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; -import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; -import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; -import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; -import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; -import static android.view.WindowManager.TRANSIT_UNSET; -import android.app.ActivityTaskManagerInternal.SleepToken; import android.os.IBinder; import android.os.RemoteException; import android.os.Trace; @@ -44,6 +43,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.server.policy.WindowManagerPolicy; +import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import com.android.server.wm.WindowManagerService; import java.io.PrintWriter; diff --git a/services/core/java/com/android/server/am/NativeCrashListener.java b/services/core/java/com/android/server/am/NativeCrashListener.java index 9348023fb1f1..6e42aee3ba2a 100644 --- a/services/core/java/com/android/server/am/NativeCrashListener.java +++ b/services/core/java/com/android/server/am/NativeCrashListener.java @@ -29,7 +29,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileDescriptor; import java.io.InterruptedIOException; -import java.net.InetSocketAddress; /** * Set up a Unix domain socket that debuggerd will connect() to in @@ -226,7 +225,7 @@ final class NativeCrashListener extends Thread { } if (pr != null) { // Don't attempt crash reporting for persistent apps - if (pr.persistent) { + if (pr.isPersistent()) { if (DEBUG) { Slog.v(TAG, "Skipping report for persistent app " + pr); } @@ -260,7 +259,7 @@ final class NativeCrashListener extends Thread { // even though the process will vanish as soon as we let // debuggerd proceed. synchronized (mAm) { - pr.crashing = true; + pr.setCrashing(true); pr.forceCrashReport = true; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index caf52e359548..5a44ab6a37fb 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -54,7 +54,7 @@ import java.util.Arrays; * Full information about a particular process that * is currently running. */ -final class ProcessRecord { +final class ProcessRecord implements WindowProcessListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessRecord" : TAG_AM; private final ActivityManagerService mService; // where we came from @@ -65,7 +65,37 @@ final class ProcessRecord { final int userId; // user of process. final String processName; // name of the process // List of packages running in the process - final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<>(); + final PackageList pkgList = new PackageList(); + final class PackageList { + final ArrayMap<String, ProcessStats.ProcessStateHolder> mPkgList = new ArrayMap<>(); + + ProcessStats.ProcessStateHolder put(String key, ProcessStats.ProcessStateHolder value) { + mWindowProcessController.addPackage(key); + return mPkgList.put(key, value); + } + + void clear() { + mPkgList.clear(); + mWindowProcessController.clearPackageList(); + } + + int size() { + return mPkgList.size(); + } + + String keyAt(int index) { + return mPkgList.keyAt(index); + } + + public ProcessStats.ProcessStateHolder valueAt(int index) { + return mPkgList.valueAt(index); + } + + boolean containsKey(Object key) { + return mPkgList.containsKey(key); + } + } + final ProcessList.ProcStateMemTracker procStateMemTracker = new ProcessList.ProcStateMemTracker(); UidRecord uidRecord; // overall state of process's uid. @@ -78,7 +108,7 @@ final class ProcessRecord { int pid; // The process of this application; 0 if none String procStatFile; // path to /proc/<pid>/stat int[] gids; // The gids this process was launched with - String requiredAbi; // The ABI this process was launched with + private String mRequiredAbi;// The ABI this process was launched with String instructionSet; // The instruction set this process was launched with boolean starting; // True if the process is being started long lastActivityTime; // For managing the LRU list @@ -96,12 +126,11 @@ final class ProcessRecord { int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int verifiedAdj; // The last adjustment that was verified as actually being set - int curSchedGroup; // Currently desired scheduling class + private int mCurSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class - int vrThreadTid; // Thread currently set for VR scheduling int trimMemoryLevel; // Last selected memory trimming level int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state - int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state + private int mRepProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for int pssStatType; // The type of stat collection that we are currently requesting @@ -112,7 +141,7 @@ final class ProcessRecord { boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle? boolean hasClientActivities; // Are there any client services with activities? boolean hasStartedServices; // Are there any started services running in this process? - boolean foregroundServices; // Running any services that are foreground? + private boolean mHasForegroundServices; // Running any services that are foreground? boolean foregroundActivities; // Running any activities that are foreground? boolean repForegroundActivities; // Last reported foreground activities. boolean systemNoUi; // This is a system process, but not currently showing UI. @@ -173,10 +202,8 @@ final class ProcessRecord { Object adjTarget; // Debugging: target component impacting oom_adj. Runnable crashHandler; // Optional local handler to be invoked in the process crash. - // all activities running in the process - final ArrayList<ActivityRecord> activities = new ArrayList<>(); - // any tasks this process had run root activities in - final ArrayList<TaskRecord> recentTasks = new ArrayList<>(); + // Controller for driving the process state on the window manager side. + final private WindowProcessController mWindowProcessController; // all ServiceRecord running in this process final ArraySet<ServiceRecord> services = new ArraySet<>(); // services that are currently executing code (need to remain foreground). @@ -194,11 +221,11 @@ final class ProcessRecord { String[] isolatedEntryPointArgs; // Arguments to pass to isolatedEntryPoint's main(). boolean execServicesFg; // do we need to be executing services in the foreground? - boolean persistent; // always keep this application running? - boolean crashing; // are we in the process of crashing? + private boolean mPersistent;// always keep this application running? + private boolean mCrashing; // are we in the process of crashing? Dialog crashDialog; // dialog being displayed due to crash. boolean forceCrashReport; // suppress normal auto-dismiss of crash dialog & report UI? - boolean notResponding; // does the app have a not responding dialog? + private boolean mNotResponding; // does the app have a not responding dialog? Dialog anrDialog; // dialog being displayed due to app not resp. boolean removed; // has app package been removed from device? boolean debugging; // was app launched for debugging? @@ -259,7 +286,7 @@ final class ProcessRecord { } } pw.println("}"); - pw.print(prefix); pw.print("requiredAbi="); pw.print(requiredAbi); + pw.print(prefix); pw.print("mRequiredAbi="); pw.print(mRequiredAbi); pw.print(" instructionSet="); pw.println(instructionSet); if (info.className != null) { pw.print(prefix); pw.print("class="); pw.println(info.className); @@ -324,15 +351,12 @@ final class ProcessRecord { pw.print(" setRaw="); pw.print(setRawAdj); pw.print(" cur="); pw.print(curAdj); pw.print(" set="); pw.println(setAdj); - pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup); + pw.print(prefix); pw.print("mCurSchedGroup="); pw.print(mCurSchedGroup); pw.print(" setSchedGroup="); pw.print(setSchedGroup); pw.print(" systemNoUi="); pw.print(systemNoUi); pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel); - if (vrThreadTid != 0) { - pw.print(prefix); pw.print("vrThreadTid="); pw.println(vrThreadTid); - } pw.print(prefix); pw.print("curProcState="); pw.print(curProcState); - pw.print(" repProcState="); pw.print(repProcState); + pw.print(" mRepProcState="); pw.print(mRepProcState); pw.print(" pssProcState="); pw.print(pssProcState); pw.print(" setProcState="); pw.print(setProcState); pw.print(" lastStateTime="); @@ -349,8 +373,8 @@ final class ProcessRecord { pw.print(" hasOverlayUi="); pw.print(hasOverlayUi); pw.print(" runningRemoteAnimation="); pw.println(runningRemoteAnimation); } - if (foregroundServices || forcingToImportant != null) { - pw.print(prefix); pw.print("foregroundServices="); pw.print(foregroundServices); + if (mHasForegroundServices || forcingToImportant != null) { + pw.print(prefix); pw.print("mHasForegroundServices="); pw.print(mHasForegroundServices); pw.print(" forcingToImportant="); pw.println(forcingToImportant); } if (reportedInteraction || fgInteractionTime != 0) { @@ -366,8 +390,8 @@ final class ProcessRecord { } pw.println(); } - if (persistent || removed) { - pw.print(prefix); pw.print("persistent="); pw.print(persistent); + if (mPersistent || removed) { + pw.print(prefix); pw.print("persistent="); pw.print(mPersistent); pw.print(" removed="); pw.println(removed); } if (hasClientActivities || foregroundActivities || repForegroundActivities) { @@ -407,16 +431,16 @@ final class ProcessRecord { pw.print(" killedByAm="); pw.print(killedByAm); pw.print(" waitingToKill="); pw.println(waitingToKill); } - if (debugging || crashing || crashDialog != null || notResponding + if (debugging || mCrashing || crashDialog != null || mNotResponding || anrDialog != null || bad) { pw.print(prefix); pw.print("debugging="); pw.print(debugging); - pw.print(" crashing="); pw.print(crashing); + pw.print(" mCrashing="); pw.print(mCrashing); pw.print(" "); pw.print(crashDialog); - pw.print(" notResponding="); pw.print(notResponding); + pw.print(" mNotResponding="); pw.print(mNotResponding); pw.print(" " ); pw.print(anrDialog); pw.print(" bad="); pw.print(bad); - // crashing or notResponding is always set before errorReportReceiver + // mCrashing or mNotResponding is always set before errorReportReceiver if (errorReportReceiver != null) { pw.print(" errorReportReceiver="); pw.print(errorReportReceiver.flattenToShortString()); @@ -431,18 +455,7 @@ final class ProcessRecord { pw.print(prefix); pw.print("isolatedEntryPointArgs="); pw.println(Arrays.toString(isolatedEntryPointArgs)); } - if (activities.size() > 0) { - pw.print(prefix); pw.println("Activities:"); - for (int i=0; i<activities.size(); i++) { - pw.print(prefix); pw.print(" - "); pw.println(activities.get(i)); - } - } - if (recentTasks.size() > 0) { - pw.print(prefix); pw.println("Recent Tasks:"); - for (int i=0; i<recentTasks.size(); i++) { - pw.print(prefix); pw.print(" - "); pw.println(recentTasks.get(i)); - } - } + mWindowProcessController.dump(pw, prefix); if (services.size() > 0) { pw.print(prefix); pw.println("Services:"); for (int i=0; i<services.size(); i++) { @@ -498,17 +511,20 @@ final class ProcessRecord { uid = _uid; userId = UserHandle.getUserId(_uid); processName = _processName; - pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode)); maxAdj = ProcessList.UNKNOWN_ADJ; curRawAdj = setRawAdj = ProcessList.INVALID_ADJ; curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ; - persistent = false; + mPersistent = false; removed = false; lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis(); + mWindowProcessController = new WindowProcessController( + mService.mActivityTaskManager, info, processName, uid, userId, this, this); + pkgList.put(_info.packageName, new ProcessStats.ProcessStateHolder(_info.longVersionCode)); } public void setPid(int _pid) { pid = _pid; + mWindowProcessController.setPid(pid); procStatFile = null; shortStringName = null; stringName = null; @@ -519,7 +535,7 @@ final class ProcessRecord { final ProcessState origBase = baseProcessTracker; if (origBase != null) { origBase.setState(ProcessStats.STATE_NOTHING, - tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList); + tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList); origBase.makeInactive(); } baseProcessTracker = tracker.getProcessStateLocked(info.packageName, uid, @@ -538,15 +554,17 @@ final class ProcessRecord { } } thread = _thread; + mWindowProcessController.setThread(thread); } public void makeInactive(ProcessStatsService tracker) { thread = null; + mWindowProcessController.setThread(null); final ProcessState origBase = baseProcessTracker; if (origBase != null) { if (origBase != null) { origBase.setState(ProcessStats.STATE_NOTHING, - tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList); + tracker.getMemFactorLocked(), SystemClock.uptimeMillis(), pkgList.mPkgList); origBase.makeInactive(); } baseProcessTracker = null; @@ -560,11 +578,24 @@ final class ProcessRecord { } } - public void clearRecentTasks() { - for (int i = recentTasks.size() - 1; i >= 0; i--) { - recentTasks.get(i).clearRootProcess(); - } - recentTasks.clear(); + boolean hasActivities() { + return mWindowProcessController.hasActivities(); + } + + void clearActivities() { + mWindowProcessController.clearActivities(); + } + + boolean hasActivitiesOrRecentTasks() { + return mWindowProcessController.hasActivitiesOrRecentTasks(); + } + + boolean hasRecentTasks() { + return mWindowProcessController.hasRecentTasks(); + } + + void clearRecentTasks() { + mWindowProcessController.clearRecentTasks(); } /** @@ -572,12 +603,8 @@ final class ProcessRecord { * to the user. See HistoryRecord.isInterestingToUserLocked() */ public boolean isInterestingToUserLocked() { - final int size = activities.size(); - for (int i = 0 ; i < size ; i++) { - ActivityRecord r = activities.get(i); - if (r.isInterestingToUserLocked()) { - return true; - } + if (mWindowProcessController.isInterestingToUser()) { + return true; } final int servicesSize = services.size(); @@ -590,14 +617,6 @@ final class ProcessRecord { return false; } - public void stopFreezingAllLocked() { - int i = activities.size(); - while (i > 0) { - i--; - activities.get(i).stopFreezingScreenLocked(true); - } - } - public void unlinkDeathRecipient() { if (deathRecipient != null && thread != null) { thread.asBinder().unlinkToDeath(deathRecipient, 0); @@ -676,7 +695,7 @@ final class ProcessRecord { } else { pendingStart = false; } - if (!persistent) { + if (!mPersistent) { killed = true; killedByAm = true; } @@ -697,7 +716,7 @@ final class ProcessRecord { proto.write(ProcessRecordProto.ISOLATED_APP_ID, UserHandle.getAppId(uid)); } } - proto.write(ProcessRecordProto.PERSISTENT, persistent); + proto.write(ProcessRecordProto.PERSISTENT, mPersistent); proto.end(token); } @@ -806,8 +825,8 @@ final class ProcessRecord { } public void forceProcessStateUpTo(int newState) { - if (repProcState > newState) { - curProcState = repProcState = newState; + if (mRepProcState > newState) { + curProcState = mRepProcState = newState; } } @@ -819,7 +838,7 @@ final class ProcessRecord { if (baseProcessTracker != null) { long now = SystemClock.uptimeMillis(); baseProcessTracker.setState(ProcessStats.STATE_NOTHING, - tracker.getMemFactorLocked(), now, pkgList); + tracker.getMemFactorLocked(), now, pkgList.mPkgList); if (N != 1) { for (int i=0; i<N; i++) { ProcessStats.ProcessStateHolder holder = pkgList.valueAt(i); @@ -856,4 +875,128 @@ final class ProcessRecord { } return list; } + + WindowProcessController getWindowProcessController() { + return mWindowProcessController; + } + + void setCurrentSchedulingGroup(int curSchedGroup) { + mCurSchedGroup = curSchedGroup; + mWindowProcessController.setCurrentSchedulingGroup(curSchedGroup); + } + + int getCurrentSchedulingGroup() { + return mCurSchedGroup; + } + + void setReportedProcState(int repProcState) { + mRepProcState = repProcState; + mWindowProcessController.setReportedProcState(repProcState); + } + + int getReportedProcState() { + return mRepProcState; + } + + void setCrashing(boolean crashing) { + mCrashing = crashing; + mWindowProcessController.setCrashing(crashing); + } + + boolean isCrashing() { + return mCrashing; + } + + void setNotResponding(boolean notResponding) { + mNotResponding = notResponding; + mWindowProcessController.setNotResponding(notResponding); + } + + boolean isNotResponding() { + return mNotResponding; + } + + void setPersistent(boolean persistent) { + mPersistent = persistent; + mWindowProcessController.setPersistent(persistent); + } + + boolean isPersistent() { + return mPersistent; + } + + public void setRequiredAbi(String requiredAbi) { + mRequiredAbi = requiredAbi; + mWindowProcessController.setRequiredAbi(requiredAbi); + } + + String getRequiredAbi() { + return mRequiredAbi; + } + + void setHasForegroundServices(boolean hasForegroundServices) { + mHasForegroundServices = hasForegroundServices; + mWindowProcessController.setHasForegroundServices(hasForegroundServices); + } + + boolean hasForegroundServices() { + return mHasForegroundServices; + } + + @Override + public void clearProfilerIfNeeded() { + synchronized (mService) { + if (mService.mProfileProc == null || mService.mProfilerInfo == null + || mService.mProfileProc != this) { + return; + } + mService.clearProfilerLocked(); + } + } + + @Override + public void updateServiceConnectionActivities() { + synchronized (mService) { + mService.mServices.updateServiceConnectionActivitiesLocked(this); + } + } + + @Override + public void setPendingUiClean(boolean pendingUiClean) { + synchronized (mService) { + this.pendingUiClean = true; + } + } + + @Override + public void setPendingUiCleanAndForceProcessStateUpTo(int newState) { + synchronized (mService) { + pendingUiClean = true; + forceProcessStateUpTo(newState); + } + } + + @Override + public void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru, + boolean activityChange, boolean updateOomAdj) { + synchronized (mService) { + if (updateServiceConnectionActivities) { + mService.mServices.updateServiceConnectionActivitiesLocked(this); + } + if (updateLru) { + mService.updateLruProcessLocked(this, activityChange, null); + } + if (updateOomAdj) { + mService.updateOomAdjLocked(); + } + } + } + + @Override + public void setRemoved(boolean removed) { + synchronized (mService) { + this.removed = removed; + } + } + } diff --git a/services/core/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java index 2f520027c1ca..29c165733808 100644 --- a/services/core/java/com/android/server/am/ProviderMap.java +++ b/services/core/java/com/android/server/am/ProviderMap.java @@ -32,7 +32,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -203,7 +202,7 @@ public final class ProviderMap { && (filterByClasses == null || filterByClasses.contains(provider.name.getClassName()))); if (sameComponent - && (provider.proc == null || evenPersistent || !provider.proc.persistent)) { + && (provider.proc == null || evenPersistent || !provider.proc.isPersistent())) { if (!doit) { return true; } diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java index b87b948f672f..fef3b867a2e8 100644 --- a/services/core/java/com/android/server/am/SafeActivityOptions.java +++ b/services/core/java/com/android/server/am/SafeActivityOptions.java @@ -117,7 +117,7 @@ class SafeActivityOptions { * @param callerApp The record of the caller. */ ActivityOptions getOptions(@Nullable Intent intent, @Nullable ActivityInfo aInfo, - @Nullable ProcessRecord callerApp, + @Nullable WindowProcessController callerApp, ActivityStackSupervisor supervisor) throws SecurityException { if (mOriginalOptions != null) { checkPermissions(intent, aInfo, callerApp, supervisor, mOriginalOptions, @@ -186,7 +186,7 @@ class SafeActivityOptions { } private void checkPermissions(@Nullable Intent intent, @Nullable ActivityInfo aInfo, - @Nullable ProcessRecord callerApp, ActivityStackSupervisor supervisor, + @Nullable WindowProcessController callerApp, ActivityStackSupervisor supervisor, ActivityOptions options, int callingPid, int callingUid) { // If a launch task id is specified, then ensure that the caller is the recents // component or has the START_TASKS_FROM_RECENTS permission diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index ba012abfd432..c8ffdb16ed6d 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -264,7 +264,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi /** The process that had previously hosted the root activity of this task. * Used to know that we should try harder to keep this process around, in case the * user wants to return to it. */ - private ProcessRecord mRootProcess; + private WindowProcessController mRootProcess; /** Takes on same value as first root activity */ boolean isPersistable = false; @@ -1131,7 +1131,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // activity reportOut.numRunning = 0; } - if (r.app != null && r.app.thread != null) { + if (r.attachedToProcess()) { // Increment the number of actually running activities reportOut.numRunning++; } @@ -1909,18 +1909,18 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } } - void setRootProcess(ProcessRecord proc) { + void setRootProcess(WindowProcessController proc) { clearRootProcess(); if (intent != null && (intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0) { mRootProcess = proc; - proc.recentTasks.add(this); + mRootProcess.addRecentTask(this); } } void clearRootProcess() { if (mRootProcess != null) { - mRootProcess.recentTasks.remove(this); + mRootProcess.removeRecentTask(this); mRootProcess = null; } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 3b478443215b..992179a2637b 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -41,7 +41,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; -import android.app.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java index 45410d79afe7..366f95a170ff 100644 --- a/services/core/java/com/android/server/am/VrController.java +++ b/services/core/java/com/android/server/am/VrController.java @@ -147,14 +147,15 @@ final class VrController { * * <p>Note: This must be called with the global ActivityManagerService lock held. * - * @param proc is the ProcessRecord of the process that entered or left the TOP_APP scheduling - * group. + * @param proc is the WindowProcessController of the process that entered or left the TOP_APP + * scheduling group. */ - public void onTopProcChangedLocked(ProcessRecord proc) { - if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { - setVrRenderThreadLocked(proc.vrThreadTid, proc.curSchedGroup, true); + public void onTopProcChangedLocked(WindowProcessController proc) { + final int curSchedGroup = proc.getCurrentSchedulingGroup(); + if (curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { + setVrRenderThreadLocked(proc.mVrThreadTid, curSchedGroup, true); } else { - if (proc.vrThreadTid == mVrRenderThreadTid) { + if (proc.mVrThreadTid == mVrRenderThreadTid) { clearVrRenderThreadLocked(true); } } @@ -190,7 +191,7 @@ final class VrController { changed = changeVrModeLocked(vrMode, record.app); if (record.app != null) { - processId = record.app.pid; + processId = record.app.getPid(); } } @@ -213,9 +214,9 @@ final class VrController { * * @param tid the tid of the thread to set, or 0 to unset the current thread. * @param pid the pid of the process owning the thread to set. - * @param proc the ProcessRecord of the process owning the thread to set. + * @param proc the WindowProcessController of the process owning the thread to set. */ - public void setVrThreadLocked(int tid, int pid, ProcessRecord proc) { + public void setVrThreadLocked(int tid, int pid, WindowProcessController proc) { if (hasPersistentVrFlagSet()) { Slog.w(TAG, "VR thread cannot be set in persistent VR mode!"); return; @@ -230,9 +231,9 @@ final class VrController { if (!inVrMode()) { Slog.w(TAG, "VR thread cannot be set when not in VR mode!"); } else { - setVrRenderThreadLocked(tid, proc.curSchedGroup, false); + setVrRenderThreadLocked(tid, proc.getCurrentSchedulingGroup(), false); } - proc.vrThreadTid = (tid > 0) ? tid : 0; + proc.mVrThreadTid = (tid > 0) ? tid : 0; } /** @@ -280,11 +281,11 @@ final class VrController { * <p>Note: This must be called with the global ActivityManagerService lock held. * * @param vrMode {@code true} if the system VR mode is being enabled. - * @param proc the ProcessRecord of the process enabling the system VR mode. + * @param proc the WindowProcessController of the process enabling the system VR mode. * * @return {@code true} if our state changed. */ - private boolean changeVrModeLocked(boolean vrMode, ProcessRecord proc) { + private boolean changeVrModeLocked(boolean vrMode, WindowProcessController proc) { final int oldVrState = mVrState; // This is the only place where mVrState should have its FLAG_VR_MODE setting @@ -299,8 +300,9 @@ final class VrController { if (changed) { if (proc != null) { - if (proc.vrThreadTid > 0) { - setVrRenderThreadLocked(proc.vrThreadTid, proc.curSchedGroup, false); + if (proc.mVrThreadTid > 0) { + setVrRenderThreadLocked( + proc.mVrThreadTid, proc.getCurrentSchedulingGroup(), false); } } else { clearVrRenderThreadLocked(false); diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java new file mode 100644 index 000000000000..64a273efc4ee --- /dev/null +++ b/services/core/java/com/android/server/am/WindowProcessController.java @@ -0,0 +1,526 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.am; + +import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.am.ActivityStack.ActivityState.DESTROYED; +import static com.android.server.am.ActivityStack.ActivityState.DESTROYING; +import static com.android.server.am.ActivityStack.ActivityState.PAUSED; +import static com.android.server.am.ActivityStack.ActivityState.PAUSING; +import static com.android.server.am.ActivityStack.ActivityState.RESUMED; +import static com.android.server.am.ActivityStack.ActivityState.STOPPING; + +import android.app.Activity; +import android.app.ActivityTaskManager; +import android.app.ActivityThread; +import android.app.IApplicationThread; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.os.RemoteException; +import android.util.ArraySet; +import android.util.Log; +import android.util.Slog; + +import com.android.internal.app.HeavyWeightSwitcherActivity; +import com.android.internal.util.function.pooled.PooledLambda; +import com.android.internal.util.function.pooled.PooledRunnable; + +import java.io.PrintWriter; +import java.util.ArrayList; + +/** + * The Activity Manager (AM) package manages the lifecycle of processes in the system through + * {@link ProcessRecord}. However, it is important for the Window Manager (WM) package to be aware + * of the processes and their state since it affects how WM manages windows and activities. This + * class that allows the {@link ProcessRecord} object in the AM package to communicate important + * changes to its state to the WM package in a structured way. WM package also uses + * {@link WindowProcessListener} to request changes to the process state on the AM side. + * Note that public calls into this class are assumed to be originating from outside the + * window manager so the window manager lock is held and appropriate permissions are checked before + * calls are allowed to proceed. + */ +public class WindowProcessController { + private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_AM; + private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE; + + // all about the first app in the process + final ApplicationInfo mInfo; + final String mName; + final int mUid; + // The process of this application; 0 if none + private volatile int mPid; + // user of process. + final int mUserId; + // The owner of this window process controller object. Mainly for identification when we + // communicate back to the activity manager side. + public final Object mOwner; + // List of packages running in the process + final ArraySet<String> mPkgList = new ArraySet<>(); + private final WindowProcessListener mListener; + private final ActivityTaskManagerService mAtm; + // The actual proc... may be null only if 'persistent' is true (in which case we are in the + // process of launching the app) + private volatile IApplicationThread mThread; + // Currently desired scheduling class + private volatile int mCurSchedGroup; + // Last reported process state; + private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT; + // are we in the process of crashing? + private volatile boolean mCrashing; + // does the app have a not responding dialog? + private volatile boolean mNotResponding; + // always keep this application running? + private volatile boolean mPersistent; + // The ABI this process was launched with + private volatile String mRequiredAbi; + // Running any services that are foreground? + private volatile boolean mHasForegroundServices; + + // Thread currently set for VR scheduling + int mVrThreadTid; + + // all activities running in the process + private final ArrayList<ActivityRecord> mActivities = new ArrayList<>(); + // any tasks this process had run root activities in + private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<>(); + + WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name, + int uid, int userId, Object owner, WindowProcessListener listener) { + mInfo = info; + mName = name; + mUid = uid; + mUserId = userId; + mOwner = owner; + mListener = listener; + mAtm = atm; + } + + public void setPid(int pid) { + mPid = pid; + } + + int getPid() { + return mPid; + } + + public void setThread(IApplicationThread thread) { + mThread = thread; + } + + IApplicationThread getThread() { + return mThread; + } + + boolean hasThread() { + return mThread != null; + } + + public void setCurrentSchedulingGroup(int curSchedGroup) { + mCurSchedGroup = curSchedGroup; + } + + int getCurrentSchedulingGroup() { + return mCurSchedGroup; + } + + public void setReportedProcState(int repProcState) { + mRepProcState = repProcState; + } + + int getReportedProcState() { + return mRepProcState; + } + + public void setCrashing(boolean crashing) { + mCrashing = crashing; + } + + boolean isCrashing() { + return mCrashing; + } + + public void setNotResponding(boolean notResponding) { + mNotResponding = notResponding; + } + + boolean isNotResponding() { + return mNotResponding; + } + + public void setPersistent(boolean persistent) { + mPersistent = persistent; + } + + boolean isPersistent() { + return mPersistent; + } + + public void setHasForegroundServices(boolean hasForegroundServices) { + mHasForegroundServices = hasForegroundServices; + } + + boolean hasForegroundServices() { + return mHasForegroundServices; + } + + public void setRequiredAbi(String requiredAbi) { + mRequiredAbi = requiredAbi; + } + + String getRequiredAbi() { + return mRequiredAbi; + } + + public void addPackage(String packageName) { + synchronized (mAtm.mGlobalLock) { + mPkgList.add(packageName); + } + } + + public void clearPackageList() { + synchronized (mAtm.mGlobalLock) { + mPkgList.clear(); + } + } + + void addActivityIfNeeded(ActivityRecord r) { + if (mActivities.contains(r)) { + return; + } + mActivities.add(r); + } + + void removeActivity(ActivityRecord r) { + mActivities.remove(r); + } + + public void clearActivities() { + synchronized (mAtm.mGlobalLock) { + mActivities.clear(); + } + } + + public boolean hasActivities() { + synchronized (mAtm.mGlobalLock) { + return !mActivities.isEmpty(); + } + } + + public boolean hasVisibleActivities() { + synchronized (mAtm.mGlobalLock) { + for (int i = mActivities.size() - 1; i >= 0; --i) { + final ActivityRecord r = mActivities.get(i); + if (r.visible) { + return true; + } + } + } + return false; + } + + public boolean hasActivitiesOrRecentTasks() { + synchronized (mAtm.mGlobalLock) { + return !mActivities.isEmpty() || !mRecentTasks.isEmpty(); + } + } + + public void stopFreezingActivities() { + synchronized (mAtm.mGlobalLock) { + int i = mActivities.size(); + while (i > 0) { + i--; + mActivities.get(i).stopFreezingScreenLocked(true); + } + } + } + + public void finishActivities() { + synchronized (mAtm.mGlobalLock) { + ArrayList<ActivityRecord> activities = new ArrayList<>(mActivities); + for (int i = 0; i < activities.size(); i++) { + final ActivityRecord r = activities.get(i); + if (!r.finishing && r.isInStackLocked()) { + r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED, + null, "finish-heavy", true); + } + } + } + } + + public boolean isInterestingToUser() { + synchronized (mAtm.mGlobalLock) { + final int size = mActivities.size(); + for (int i = 0; i < size; i++) { + ActivityRecord r = mActivities.get(i); + if (r.isInterestingToUserLocked()) { + return true; + } + } + } + return false; + } + + public boolean hasRunningActivity(String packageName) { + synchronized (mAtm.mGlobalLock) { + for (int i = mActivities.size() - 1; i >= 0; --i) { + final ActivityRecord r = mActivities.get(i); + if (packageName.equals(r.packageName)) { + return true; + } + } + } + return false; + } + + public void clearPackagePreferredForHomeActivities() { + synchronized (mAtm.mGlobalLock) { + for (int i = mActivities.size() - 1; i >= 0; --i) { + final ActivityRecord r = mActivities.get(i); + if (r.isActivityTypeHome()) { + Log.i(TAG, "Clearing package preferred activities from " + r.packageName); + try { + ActivityThread.getPackageManager() + .clearPackagePreferredActivities(r.packageName); + } catch (RemoteException c) { + // pm is in same process, this will never happen. + } + } + } + } + } + + boolean hasStartedActivity(ActivityRecord launchedActivity) { + for (int i = mActivities.size() - 1; i >= 0; i--) { + final ActivityRecord activity = mActivities.get(i); + if (launchedActivity == activity) { + continue; + } + if (!activity.stopped) { + return true; + } + } + return false; + } + + + public void updateIntentForHeavyWeightActivity(Intent intent) { + synchronized (mAtm.mGlobalLock) { + if (mActivities.isEmpty()) { + return; + } + ActivityRecord hist = mActivities.get(0); + intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName); + intent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.getTask().taskId); + } + } + + boolean shouldKillProcessForRemovedTask(TaskRecord tr) { + for (int k = 0; k < mActivities.size(); k++) { + final TaskRecord otherTask = mActivities.get(k).getTask(); + if (tr.taskId != otherTask.taskId && otherTask.inRecents) { + // Don't kill process(es) that has an activity in a different task that is + // also in recents. + return false; + } + } + return true; + } + + ArraySet<TaskRecord> getReleaseSomeActivitiesTasks() { + // Examine all activities currently running in the process. + TaskRecord firstTask = null; + // Tasks is non-null only if two or more tasks are found. + ArraySet<TaskRecord> tasks = null; + if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Trying to release some activities in " + this); + for (int i = 0; i < mActivities.size(); i++) { + final ActivityRecord r = mActivities.get(i); + // First, if we find an activity that is in the process of being destroyed, + // then we just aren't going to do anything for now; we want things to settle + // down before we try to prune more activities. + if (r.finishing || r.isState(DESTROYING, DESTROYED)) { + if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Abort release; already destroying: " + r); + return null; + } + // Don't consider any activies that are currently not in a state where they + // can be destroyed. + if (r.visible || !r.stopped || !r.haveState + || r.isState(RESUMED, PAUSING, PAUSED, STOPPING)) { + if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Not releasing in-use activity: " + r); + continue; + } + + final TaskRecord task = r.getTask(); + if (task != null) { + if (DEBUG_RELEASE) Slog.d(TAG_RELEASE, "Collecting release task " + task + + " from " + r); + if (firstTask == null) { + firstTask = task; + } else if (firstTask != task) { + if (tasks == null) { + tasks = new ArraySet<>(); + tasks.add(firstTask); + } + tasks.add(task); + } + } + } + + return tasks; + } + + public interface ComputeOomAdjCallback { + void onVisibleActivity(); + void onPausedActivity(); + void onStoppingActivity(boolean finishing); + void onOtherActivity(); + } + + public int computeOomAdjFromActivities(int minTaskLayer, ComputeOomAdjCallback callback) { + synchronized (mAtm.mGlobalLock) { + final int activitiesSize = mActivities.size(); + for (int j = 0; j < activitiesSize; j++) { + final ActivityRecord r = mActivities.get(j); + if (r.app != this) { + Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app + + " instead of expected " + this); + if (r.app == null || (r.app.mUid == mUid)) { + // Only fix things up when they look sane + r.setProcess(this); + } else { + continue; + } + } + if (r.visible) { + callback.onVisibleActivity(); + final TaskRecord task = r.getTask(); + if (task != null && minTaskLayer > 0) { + final int layer = task.mLayerRank; + if (layer >= 0 && minTaskLayer > layer) { + minTaskLayer = layer; + } + } + break; + } else if (r.isState(PAUSING, PAUSED)) { + callback.onPausedActivity(); + } else if (r.isState(STOPPING)) { + callback.onStoppingActivity(r.finishing); + } else { + callback.onOtherActivity(); + } + } + } + + return minTaskLayer; + } + + void clearProfilerIfNeeded() { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + mAtm.mH.post(() -> mListener.clearProfilerIfNeeded()); + } + + void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru, + boolean activityChange, boolean updateOomAdj) { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + final Runnable r = PooledLambda.obtainRunnable(WindowProcessListener::updateProcessInfo, + mListener, updateServiceConnectionActivities, updateLru, activityChange, + updateOomAdj); + mAtm.mH.post(r); + } + + void updateServiceConnectionActivities() { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + mAtm.mH.post(() -> mListener.updateServiceConnectionActivities()); + } + + void setPendingUiClean(boolean pendingUiClean) { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + final Runnable r = PooledLambda.obtainRunnable( + WindowProcessListener::setPendingUiClean, mListener, pendingUiClean); + mAtm.mH.post(r); + } + + void setPendingUiCleanAndForceProcessStateUpTo(int newState) { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + final Runnable r = PooledLambda.obtainRunnable( + WindowProcessListener::setPendingUiCleanAndForceProcessStateUpTo, + mListener, newState); + mAtm.mH.post(r); + } + + void setRemoved(boolean removed) { + if (mListener == null) return; + // Posting on handler so WM lock isn't held when we call into AM. + final Runnable r = PooledLambda.obtainRunnable( + WindowProcessListener::setRemoved, mListener, removed); + mAtm.mH.post(r); + } + + void addRecentTask(TaskRecord task) { + mRecentTasks.add(task); + } + + void removeRecentTask(TaskRecord task) { + mRecentTasks.remove(task); + } + + public boolean hasRecentTasks() { + synchronized (mAtm.mGlobalLock) { + return !mRecentTasks.isEmpty(); + } + } + + public void clearRecentTasks() { + synchronized (mAtm.mGlobalLock) { + for (int i = mRecentTasks.size() - 1; i >= 0; i--) { + mRecentTasks.get(i).clearRootProcess(); + } + mRecentTasks.clear(); + } + } + + public void dump(PrintWriter pw, String prefix) { + synchronized (mAtm.mGlobalLock) { + if (mActivities.size() > 0) { + pw.print(prefix); pw.println("Activities:"); + for (int i = 0; i < mActivities.size(); i++) { + pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i)); + } + } + + if (mRecentTasks.size() > 0) { + pw.println(prefix + "Recent Tasks:"); + for (int i = 0; i < mRecentTasks.size(); i++) { + pw.println(prefix + " - " + mRecentTasks.get(i)); + } + } + + if (mVrThreadTid != 0) { + pw.print(prefix); pw.print("mVrThreadTid="); pw.println(mVrThreadTid); + } + } + } + +} diff --git a/services/core/java/com/android/server/am/WindowProcessListener.java b/services/core/java/com/android/server/am/WindowProcessListener.java new file mode 100644 index 000000000000..92e4461c4452 --- /dev/null +++ b/services/core/java/com/android/server/am/WindowProcessListener.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.am; + +/** + * Interface used by the owner/creator of a process that owns windows to listen to changes from the + * WM side. + * @see WindowProcessController + */ +public interface WindowProcessListener { + + /** Clear the profiler record if we are currently profiling this process. */ + void clearProfilerIfNeeded(); + + /** Update the service connection for this process based on activities it might have. */ + void updateServiceConnectionActivities(); + + /** Set or clear flag that we would like to clean-up UI resources for this process. */ + void setPendingUiClean(boolean pendingUiClean); + + /** + * Set flag that we would like to clean-up UI resources for this process and force new process + * state. + */ + void setPendingUiCleanAndForceProcessStateUpTo(int newState); + + /** Update the process information. */ + void updateProcessInfo(boolean updateServiceConnectionActivities, boolean updateLru, + boolean activityChange, boolean updateOomAdj); + + /** Set process package been removed from device. */ + void setRemoved(boolean removed); +} diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 571ee42b140f..6971f718a13c 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -20,8 +20,6 @@ import static android.Manifest.permission.REMOTE_AUDIO_PLAYBACK; import static android.media.AudioManager.RINGER_MODE_NORMAL; import static android.media.AudioManager.RINGER_MODE_SILENT; import static android.media.AudioManager.RINGER_MODE_VIBRATE; -import static android.media.AudioManager.STREAM_ALARM; -import static android.media.AudioManager.STREAM_MUSIC; import static android.media.AudioManager.STREAM_SYSTEM; import static android.os.Process.FIRST_APPLICATION_UID; import static android.provider.Settings.Secure.VOLUME_HUSH_MUTE; @@ -33,7 +31,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.IUidObserver; @@ -142,6 +139,7 @@ import com.android.server.audio.AudioServiceEvents.PhoneStateEvent; import com.android.server.audio.AudioServiceEvents.VolumeEvent; import com.android.server.audio.AudioServiceEvents.WiredDevConnectEvent; import com.android.server.pm.UserManagerService; +import com.android.server.wm.ActivityTaskManagerInternal; import org.xmlpull.v1.XmlPullParserException; diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java index 079f3ead402a..65ccecdcafff 100644 --- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java +++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java @@ -21,7 +21,6 @@ import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; -import android.app.ActivityTaskManagerInternal; import android.app.AppOpsManager; import android.app.IApplicationThread; import android.content.ComponentName; @@ -42,6 +41,7 @@ import android.text.TextUtils; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; +import com.android.server.wm.ActivityTaskManagerInternal; import java.util.ArrayList; import java.util.List; diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index a52470d5f21e..93230401eb20 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.IApplicationThread; import android.app.PendingIntent; @@ -64,6 +63,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.wm.ActivityTaskManagerInternal; import java.util.Collections; import java.util.List; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 2a4a976f5905..9a156231de6a 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -90,7 +90,6 @@ import static android.os.storage.StorageManager.FLAG_STORAGE_CE; import static android.os.storage.StorageManager.FLAG_STORAGE_DE; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDWR; - import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT; import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME; @@ -121,7 +120,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.ResourcesManager; @@ -321,11 +319,7 @@ import com.android.server.pm.permission.PermissionsState; import com.android.server.pm.permission.PermissionsState.PermissionState; import com.android.server.security.VerityUtils; import com.android.server.storage.DeviceStorageMonitorInternal; - -import dalvik.system.CloseGuard; -import dalvik.system.VMRuntime; - -import libcore.io.IoUtils; +import com.android.server.wm.ActivityTaskManagerInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -371,6 +365,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; +import dalvik.system.CloseGuard; +import dalvik.system.VMRuntime; +import libcore.io.IoUtils; + /** * Keep track of all those APKs everywhere. * <p> diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 6e7eae17a28a..46935f085911 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -27,7 +27,6 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityManagerNative; -import android.app.ActivityTaskManagerInternal; import android.app.IActivityManager; import android.app.IStopUserCallback; import android.app.KeyguardManager; @@ -99,8 +98,7 @@ import com.android.server.LockGuard; import com.android.server.SystemService; import com.android.server.am.UserState; import com.android.server.storage.DeviceStorageMonitorInternal; - -import libcore.io.IoUtils; +import com.android.server.wm.ActivityTaskManagerInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -123,6 +121,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; +import libcore.io.IoUtils; + /** * Service for {@link UserManager}. * diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 71e342e9021f..b99f8d6c8170 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -124,7 +124,6 @@ import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN; import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION; import static android.view.WindowManagerGlobal.ADD_OKAY; import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED; - import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT; import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED; @@ -155,8 +154,6 @@ import static com.android.server.wm.WindowManagerPolicyProto.WINDOW_MANAGER_DRAW import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; -import android.app.ActivityTaskManagerInternal.SleepToken; import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.AppOpsManager; @@ -275,8 +272,8 @@ import com.android.internal.policy.KeyguardDismissCallback; import com.android.internal.policy.PhoneWindow; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.ScreenshotHelper; import com.android.internal.util.ScreenShapeHelper; +import com.android.internal.util.ScreenshotHelper; import com.android.internal.widget.PointerLocationView; import com.android.server.GestureLauncherService; import com.android.server.LocalServices; @@ -286,6 +283,8 @@ import com.android.server.policy.keyguard.KeyguardServiceDelegate.DrawnListener; import com.android.server.policy.keyguard.KeyguardStateMonitor.StateCallback; import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.vr.VrManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal.SleepToken; import com.android.server.wm.AppTransition; import com.android.server.wm.DisplayFrames; import com.android.server.wm.WindowManagerInternal; diff --git a/services/core/java/com/android/server/vr/Vr2dDisplay.java b/services/core/java/com/android/server/vr/Vr2dDisplay.java index 9183b086445b..a16dbb726613 100644 --- a/services/core/java/com/android/server/vr/Vr2dDisplay.java +++ b/services/core/java/com/android/server/vr/Vr2dDisplay.java @@ -3,9 +3,7 @@ package com.android.server.vr; import static android.view.Display.INVALID_DISPLAY; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.Vr2dDisplayProperties; -import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -14,19 +12,15 @@ import android.graphics.PixelFormat; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.ImageReader; -import android.os.Build; import android.os.Handler; -import android.os.IBinder; -import android.os.Message; import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemProperties; import android.service.vr.IPersistentVrStateCallbacks; import android.service.vr.IVrManager; import android.util.Log; import android.view.Surface; import com.android.server.LocalServices; +import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.WindowManagerInternal; /** diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index 50bf57fdc2d8..5c45afcfd376 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -18,15 +18,13 @@ package com.android.server.vr; import static android.view.Display.INVALID_DISPLAY; import android.Manifest; -import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; -import android.app.ActivityTaskManagerInternal.ScreenObserver; +import android.annotation.NonNull; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.INotificationManager; -import android.app.Vr2dDisplayProperties; import android.app.NotificationManager; -import android.annotation.NonNull; +import android.app.Vr2dDisplayProperties; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; @@ -60,30 +58,30 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; - -import com.android.server.FgThread; -import com.android.server.wm.WindowManagerInternal; import android.view.inputmethod.InputMethodManagerInternal; import com.android.internal.R; import com.android.internal.util.DumpUtils; +import com.android.server.FgThread; import com.android.server.LocalServices; import com.android.server.SystemConfig; import com.android.server.SystemService; -import com.android.server.utils.ManagedApplicationService.PendingEvent; +import com.android.server.utils.ManagedApplicationService; +import com.android.server.utils.ManagedApplicationService.BinderChecker; import com.android.server.utils.ManagedApplicationService.LogEvent; import com.android.server.utils.ManagedApplicationService.LogFormattable; +import com.android.server.utils.ManagedApplicationService.PendingEvent; import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener; -import com.android.server.utils.ManagedApplicationService; -import com.android.server.utils.ManagedApplicationService.BinderChecker; +import com.android.server.wm.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal.ScreenObserver; +import com.android.server.wm.WindowManagerInternal; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.lang.StringBuilder; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; diff --git a/core/java/android/app/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index fa78db5c3d6d..3885cf99da36 100644 --- a/core/java/android/app/ActivityTaskManagerInternal.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java @@ -14,10 +14,13 @@ * limitations under the License */ -package android.app; +package com.android.server.wm; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.AppProtoEnums; +import android.app.IActivityManager; +import android.app.IApplicationThread; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; @@ -28,6 +31,7 @@ import android.util.SparseIntArray; import android.view.RemoteAnimationAdapter; import com.android.internal.app.IVoiceInteractor; +import com.android.server.am.WindowProcessController; import java.util.List; @@ -210,11 +214,6 @@ public abstract class ActivityTaskManagerInternal { */ public abstract void setFocusedActivity(IBinder token); - /** - * Returns {@code true} if {@code uid} is running an activity from {@code packageName}. - */ - public abstract boolean hasRunningActivity(int uid, @Nullable String packageName); - public abstract void registerScreenObserver(ScreenObserver observer); /** @@ -263,4 +262,8 @@ public abstract class ActivityTaskManagerInternal { */ public abstract void onUserStopped(int userId); public abstract boolean isGetTasksAllowed(String caller, int callingPid, int callingUid); + + public abstract void onProcessAdded(WindowProcessController proc); + public abstract void onProcessRemoved(String name, int uid); + public abstract void onCleanUpApplicationRecord(WindowProcessController proc); } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index b61069529761..6f5fea960c7e 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -16,13 +16,13 @@ package com.android.server.wm; -import static android.app.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_CLOSING; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM; import static com.android.server.wm.AnimationAdapterProto.REMOTE; import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS; @@ -48,11 +48,14 @@ import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.inputmethod.InputMethodManagerInternal; + +import com.google.android.collect.Sets; + import com.android.internal.annotations.VisibleForTesting; import com.android.server.LocalServices; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import com.android.server.wm.utils.InsetUtils; -import com.google.android.collect.Sets; + import java.io.PrintWriter; import java.util.ArrayList; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d43338db571a..399078a6be37 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -117,7 +117,6 @@ import android.app.ActivityManager; import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityManagerInternal; import android.app.ActivityTaskManager; -import android.app.ActivityTaskManagerInternal; import android.app.ActivityThread; import android.app.AppOpsManager; import android.app.IActivityManager; diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 1a8753dd51dc..aced8e46ab10 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -16,18 +16,10 @@ package com.android.server.wm; -import static android.app.ActivityTaskManagerInternal.APP_TRANSITION_SNAPSHOT; -import static android.app.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN; -import static android.app.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN; - -import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; -import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE; -import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN; -import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; -import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE; import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; +import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER; @@ -39,10 +31,17 @@ import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_BACK; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; +import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE; +import static android.view.WindowManager.TRANSIT_TRANSLUCENT_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_WALLPAPER_CLOSE; import static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_CLOSE; import static android.view.WindowManager.TRANSIT_WALLPAPER_INTRA_OPEN; import static android.view.WindowManager.TRANSIT_WALLPAPER_OPEN; +import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; +import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; +import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SNAPSHOT; +import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN; +import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN; import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index c3a8d6c8ef91..4456ed0929f9 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -563,11 +563,10 @@ public final class SystemServer { // TODO: Might need to move after migration to WM. ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); - mActivityManagerService = mSystemServiceManager.startService( - ActivityManagerService.Lifecycle.class).getService(); + mActivityManagerService = ActivityManagerService.Lifecycle.startService( + mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); - mActivityManagerService.setActivityTaskManager(atm); traceEnd(); // Power manager needs to be started early because other services need it. diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java index 077b4558f402..583a9dd3a342 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java @@ -50,7 +50,7 @@ import static com.android.server.am.LaunchParamsController.LaunchParamsModifier. @RunWith(AndroidJUnit4.class) public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { private ActivityLaunchParamsModifier mModifier; - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStack mStack; private TaskRecord mTask; private ActivityRecord mActivity; @@ -62,7 +62,7 @@ public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { @Override public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mModifier = new ActivityLaunchParamsModifier(mService.mStackSupervisor); mCurrent = new LaunchParams(); mResult = new LaunchParams(); @@ -104,12 +104,12 @@ public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { mActivity, null /*source*/, options /*options*/, mCurrent, mResult)); // Does not support freeform - mService.mActivityTaskManager.mSupportsFreeformWindowManagement = false; + mService.mSupportsFreeformWindowManagement = false; assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options)); assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/, mActivity, null /*source*/, options /*options*/, mCurrent, mResult)); - mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true; + mService.mSupportsFreeformWindowManagement = true; options.setLaunchBounds(new Rect()); assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options)); @@ -130,7 +130,7 @@ public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { public void testBoundsExtraction() throws Exception { // Make activity resizeable and enable freeform mode. mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; - mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true; + mService.mSupportsFreeformWindowManagement = true; ActivityOptions options = ActivityOptions.makeBasic(); final Rect proposedBounds = new Rect(20, 30, 45, 40); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java index 3172323713ea..dd3e5a8a33fe 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java @@ -73,7 +73,7 @@ import org.mockito.invocation.InvocationOnMock; @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityRecordTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private TestActivityStack mStack; private TaskRecord mTask; private ActivityRecord mActivity; @@ -83,7 +83,7 @@ public class ActivityRecordTests extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build(); @@ -126,7 +126,7 @@ public class ActivityRecordTests extends ActivityTestsBase { pauseFound.value = true; } return null; - }).when(mActivity.app.thread).scheduleTransaction(any()); + }).when(mActivity.app.getThread()).scheduleTransaction(any()); mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped"); @@ -236,7 +236,7 @@ public class ActivityRecordTests extends ActivityTestsBase { private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable, boolean activityResizeable, boolean expected) { - mService.mActivityTaskManager.mSupportsMultiWindow = true; + mService.mSupportsMultiWindow = true; final TaskRecord task = taskPresent ? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java index 0674d851a7f5..a44661d590c8 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java @@ -68,7 +68,7 @@ import java.util.ArrayList; @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStackSupervisorTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStackSupervisor mSupervisor; private ActivityStack mFullscreenStack; @@ -77,7 +77,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mSupervisor = mService.mStackSupervisor; mFullscreenStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); @@ -278,7 +278,7 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase { assertEquals(originalStackCount + 1, defaultDisplay.getChildCount()); // Let's pretend that the app has crashed. - firstActivity.app.thread = null; + firstActivity.app.setThread(null); mService.mStackSupervisor.finishTopCrashedActivitiesLocked(firstActivity.app, "test"); // Verify that the stack was removed. diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java index 01425ed51b55..0d0a6ba573cd 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java @@ -61,7 +61,7 @@ import org.junit.Test; @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStackTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStackSupervisor mSupervisor; private ActivityDisplay mDefaultDisplay; private ActivityStack mStack; @@ -72,7 +72,7 @@ public class ActivityStackTests extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mSupervisor = mService.mStackSupervisor; mDefaultDisplay = mService.mStackSupervisor.getDefaultDisplay(); mStack = mDefaultDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java index df31042ab589..f5ae46cd19ed 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java @@ -19,7 +19,9 @@ package com.android.server.am; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; +import android.app.IApplicationThread; import android.content.Intent; +import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -49,7 +51,7 @@ import java.util.Random; @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStartControllerTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStartController mController; private Factory mFactory; private ActivityStarter mStarter; @@ -57,10 +59,10 @@ public class ActivityStartControllerTests extends ActivityTestsBase { @Override public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mFactory = mock(Factory.class); - mController = new ActivityStartController(mService.mActivityTaskManager, mService.mStackSupervisor, mFactory); - mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager, + mController = new ActivityStartController(mService, mService.mStackSupervisor, mFactory); + mStarter = spy(new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class))); doReturn(mStarter).when(mFactory).obtain(); } @@ -77,11 +79,14 @@ public class ActivityStartControllerTests extends ActivityTestsBase { final int startFlags = random.nextInt(); final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - final ProcessRecord process= new ProcessRecord(null, null, - mService.mContext.getApplicationInfo(), "name", 12345); + final WindowProcessController wpc = new WindowProcessController(mService, + mService.mContext.getApplicationInfo(), "name", 12345, + UserHandle.getUserId(12345), mock(Object.class), + mock(WindowProcessListener.class)); + wpc.setThread(mock(IApplicationThread.class)); mController.addPendingActivityLaunch( - new PendingActivityLaunch(activity, source, startFlags, stack, process)); + new PendingActivityLaunch(activity, source, startFlags, stack, wpc)); final boolean resume = random.nextBoolean(); mController.doPendingActivityLaunches(resume); @@ -96,7 +101,7 @@ public class ActivityStartControllerTests extends ActivityTestsBase { @Test public void testRecycling() throws Exception { final Intent intent = new Intent(); - final ActivityStarter optionStarter = new ActivityStarter(mController, mService.mActivityTaskManager, + final ActivityStarter optionStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); optionStarter .setIntent(intent) diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java index 274d9e5683f8..267e689f0a91 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java @@ -88,7 +88,7 @@ import java.util.ArrayList; @Presubmit @RunWith(AndroidJUnit4.class) public class ActivityStarterTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStarter mStarter; private ActivityStartController mController; @@ -107,9 +107,9 @@ public class ActivityStarterTests extends ActivityTestsBase { @Override public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mController = mock(ActivityStartController.class); - mStarter = new ActivityStarter(mController, mService.mActivityTaskManager, mService.mStackSupervisor, + mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); } @@ -134,7 +134,7 @@ public class ActivityStarterTests extends ActivityTestsBase { assertTrue(task2.getStack() instanceof PinnedActivityStack); mStarter.updateBounds(task2, bounds); - verify(mService.mActivityTaskManager, times(1)).resizeStack(eq(task2.getStack().mStackId), + verify(mService, times(1)).resizeStack(eq(task2.getStack().mStackId), eq(bounds), anyBoolean(), anyBoolean(), anyBoolean(), anyInt()); // In the case of no animation, the stack and task bounds should be set immediately. @@ -189,20 +189,21 @@ public class ActivityStarterTests extends ActivityTestsBase { */ private void verifyStartActivityPreconditions(int preconditions, int launchFlags, int expectedResult) { - final ActivityManagerService service = createActivityManagerService(); + final ActivityTaskManagerService service = mService; final IPackageManager packageManager = mock(IPackageManager.class); final ActivityStartController controller = mock(ActivityStartController.class); - final ActivityStarter starter = new ActivityStarter(controller, service.mActivityTaskManager, + final ActivityStarter starter = new ActivityStarter(controller, service, service.mStackSupervisor, mock(ActivityStartInterceptor.class)); + prepareStarter(launchFlags); final IApplicationThread caller = mock(IApplicationThread.class); // If no caller app, return {@code null} {@link ProcessRecord}. final ProcessRecord record = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP) - ? null : new ProcessRecord(null, mock(BatteryStatsImpl.class), + ? null : new ProcessRecord(service.mAm, mock(BatteryStatsImpl.class), mock(ApplicationInfo.class), null, 0); - doReturn(record).when(service).getRecordForAppLocked(anyObject()); + doReturn(record).when(service.mAm).getRecordForAppLocked(anyObject()); final Intent intent = new Intent(); intent.setFlags(launchFlags); @@ -236,7 +237,7 @@ public class ActivityStarterTests extends ActivityTestsBase { } if (containsConditions(preconditions, PRECONDITION_DISALLOW_APP_SWITCHING)) { - doReturn(false).when(service.mActivityTaskManager).checkAppSwitchAllowedLocked( + doReturn(false).when(service).checkAppSwitchAllowedLocked( anyInt(), anyInt(), anyInt(), anyInt(), any()); } @@ -282,7 +283,7 @@ public class ActivityStarterTests extends ActivityTestsBase { // Ensure that {@link ActivityOptions} are aborted with unsuccessful result. if (expectedResult != START_SUCCESS) { - final ActivityStarter optionStarter = new ActivityStarter(mController, mService.mActivityTaskManager, + final ActivityStarter optionStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); final ActivityOptions options = spy(ActivityOptions.makeBasic()); @@ -336,7 +337,7 @@ public class ActivityStarterTests extends ActivityTestsBase { info.applicationInfo = new ApplicationInfo(); info.applicationInfo.packageName = ActivityBuilder.getDefaultComponent().getPackageName(); - return new ActivityStarter(mController, mService.mActivityTaskManager, + return new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)) .setIntent(intent) .setActivityInfo(info); @@ -456,7 +457,7 @@ public class ActivityStarterTests extends ActivityTestsBase { final ActivityStarter starter = prepareStarter(0); - final LockTaskController lockTaskController = mService.mActivityTaskManager.getLockTaskController(); + final LockTaskController lockTaskController = mService.getLockTaskController(); doReturn(true).when(lockTaskController).isLockTaskModeViolation(any()); final int result = starter.setReason("testTaskModeViolation").execute(); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index dd30e7075b18..1dd7b4cf63de 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -51,6 +51,7 @@ import android.graphics.Rect; import android.hardware.display.DisplayManager; import android.os.HandlerThread; import android.os.Looper; +import android.os.UserHandle; import android.service.voice.IVoiceInteractionSession; import android.support.test.InstrumentationRegistry; import android.testing.DexmakerShareClassLoaderRule; @@ -104,32 +105,33 @@ public class ActivityTestsBase { mHandlerThread.quitSafely(); } + protected ActivityTaskManagerService createActivityTaskManagerService() { + final TestActivityTaskManagerService atm = spy(new TestActivityTaskManagerService(mContext)); + setupActivityManagerService(atm); + return atm; + } + protected ActivityManagerService createActivityManagerService() { - final ActivityManagerService service = - setupActivityManagerService(new TestActivityManagerService(mContext)); + final TestActivityTaskManagerService atm = spy(new TestActivityTaskManagerService(mContext)); + return setupActivityManagerService(atm); + } + + ActivityManagerService setupActivityManagerService(TestActivityTaskManagerService atm) { + final ActivityManagerService am = spy(new TestActivityManagerService(mContext, atm)); + setupActivityManagerService(am, atm); AttributeCache.init(mContext); - return service; + return am; } - protected ActivityManagerService setupActivityManagerService( - ActivityManagerService service, ActivityTaskManagerService atm) { - service = spy(service); - // Makes sure activity task is created with the spy object. - atm = spy(atm); - service.setActivityTaskManager(atm); - atm.mAmInternal = service.new LocalService(); + void setupActivityManagerService(ActivityManagerService am, ActivityTaskManagerService atm) { + atm.setActivityManagerService(am); + atm.mAmInternal = am.new LocalService(); // Makes sure the supervisor is using with the spy object. atm.mStackSupervisor.setService(atm); - doReturn(mock(IPackageManager.class)).when(service).getPackageManager(); - doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt()); - service.mWindowManager = prepareMockWindowManager(); - atm.setWindowManager(service.mWindowManager); - return service; - } - - protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) { - return setupActivityManagerService( - service, new TestActivityTaskManagerService(service.mContext)); + doReturn(mock(IPackageManager.class)).when(am).getPackageManager(); + doNothing().when(am).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt()); + am.mWindowManager = prepareMockWindowManager(); + atm.setWindowManager(am.mWindowManager); } /** @@ -141,7 +143,7 @@ public class ActivityTestsBase { - private final ActivityManagerService mService; + private final ActivityTaskManagerService mService; private ComponentName mComponent; private TaskRecord mTaskRecord; @@ -150,7 +152,7 @@ public class ActivityTestsBase { private ActivityStack mStack; private int mActivityFlags; - ActivityBuilder(ActivityManagerService service) { + ActivityBuilder(ActivityTaskManagerService service) { mService = service; } @@ -210,8 +212,7 @@ public class ActivityTestsBase { aInfo.applicationInfo.uid = mUid; aInfo.flags |= mActivityFlags; - final ActivityRecord activity = new ActivityRecord(mService.mActivityTaskManager, - null /* caller */, + final ActivityRecord activity = new ActivityRecord(mService, null /* caller */, 0 /* launchedFromPid */, 0, null, intent, null, aInfo /*aInfo*/, new Configuration(), null /* resultTo */, null /* resultWho */, 0 /* reqCode */, false /*componentSpecified*/, false /* rootVoiceInteraction */, @@ -222,10 +223,12 @@ public class ActivityTestsBase { mTaskRecord.addActivityToTop(activity); } - activity.setProcess(new ProcessRecord(null, null, - mService.mContext.getApplicationInfo(), "name", 12345)); - activity.app.thread = mock(IApplicationThread.class); - + final WindowProcessController wpc = new WindowProcessController(mService, + mService.mContext.getApplicationInfo(), "name", 12345, + UserHandle.getUserId(12345), mock(Object.class), + mock(WindowProcessListener.class)); + wpc.setThread(mock(IApplicationThread.class)); + activity.setProcess(wpc); return activity; } } @@ -412,8 +415,8 @@ public class ActivityTestsBase { */ protected static class TestActivityManagerService extends ActivityManagerService { - TestActivityManagerService(Context context) { - super(context); + TestActivityManagerService(Context context, TestActivityTaskManagerService atm) { + super(context, atm); } @Override diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java index aaec2382f403..fbe552dbcbbc 100644 --- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java @@ -57,15 +57,15 @@ import static org.junit.Assert.assertNotEquals; @Presubmit @RunWith(AndroidJUnit4.class) public class LaunchParamsControllerTests extends ActivityTestsBase { - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private LaunchParamsController mController; @Before @Override public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); - mController = new LaunchParamsController(mService.mActivityTaskManager); + mService = createActivityTaskManagerService(); + mController = new LaunchParamsController(mService); } /** @@ -200,9 +200,9 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { mController.registerModifier(positioner); - doNothing().when(mService.mActivityTaskManager).moveStackToDisplay(anyInt(), anyInt()); + doNothing().when(mService).moveStackToDisplay(anyInt(), anyInt()); mController.layoutTask(task, null /* windowLayout */); - verify(mService.mActivityTaskManager, times(1)).moveStackToDisplay(eq(task.getStackId()), + verify(mService, times(1)).moveStackToDisplay(eq(task.getStackId()), eq(params.mPreferredDisplayId)); } diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index 982809a3a175..a4e4409f3eb9 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -94,7 +94,7 @@ public class RecentTasksTest extends ActivityTestsBase { private static int INVALID_STACK_ID = 999; private Context mContext = InstrumentationRegistry.getContext(); - private ActivityTaskManagerService mService; + private TestActivityTaskManagerService mService; private ActivityDisplay mDisplay; private ActivityDisplay mOtherDisplay; private ActivityStack mStack; @@ -145,8 +145,9 @@ public class RecentTasksTest extends ActivityTestsBase { super.setUp(); mTaskPersister = new TestTaskPersister(mContext.getFilesDir()); - mService = setupActivityManagerService(new MyTestActivityManagerService(mContext), - new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager; + mService = spy(new MyTestActivityTaskManagerService(mContext)); + final ActivityManagerService am = spy(new MyTestActivityManagerService(mContext, mService)); + setupActivityManagerService(am, mService); mRecentTasks = (TestRecentTasks) mService.getRecentTasks(); mRecentTasks.loadParametersFromResources(mContext.getResources()); mHomeStack = mService.mStackSupervisor.getDefaultDisplay().createStack( @@ -839,8 +840,8 @@ public class RecentTasksTest extends ActivityTestsBase { } private class MyTestActivityManagerService extends TestActivityManagerService { - MyTestActivityManagerService(Context context) { - super(context); + MyTestActivityManagerService(Context context, TestActivityTaskManagerService atm) { + super(context, atm); } @Override diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java index 1f2bca64ca4a..b642d263af3c 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java @@ -25,6 +25,7 @@ import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -50,7 +51,7 @@ import org.junit.runner.RunWith; public class RecentsAnimationTest extends ActivityTestsBase { private Context mContext = InstrumentationRegistry.getContext(); - private ActivityTaskManagerService mService; + private TestActivityTaskManagerService mService; private ComponentName mRecentsComponent; @Before @@ -59,9 +60,8 @@ public class RecentsAnimationTest extends ActivityTestsBase { super.setUp(); mRecentsComponent = new ComponentName(mContext.getPackageName(), "RecentsActivity"); - mService = setupActivityManagerService(new TestActivityManagerService(mContext), - new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager; - AttributeCache.init(mContext); + mService = spy(new MyTestActivityTaskManagerService(mContext)); + setupActivityManagerService(mService); } @Test @@ -70,14 +70,14 @@ public class RecentsAnimationTest extends ActivityTestsBase { WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); ActivityStack recentsStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); - ActivityRecord recentsActivity = new ActivityBuilder(mService.mAm) + ActivityRecord recentsActivity = new ActivityBuilder(mService) .setComponent(mRecentsComponent) .setCreateTask(true) .setStack(recentsStack) .build(); ActivityStack fullscreenStack2 = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - ActivityRecord fsActivity = new ActivityBuilder(mService.mAm) + ActivityRecord fsActivity = new ActivityBuilder(mService) .setComponent(new ComponentName(mContext.getPackageName(), "App1")) .setCreateTask(true) .setStack(fullscreenStack2) diff --git a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java index c6ce7e1188e8..944f20f7ff0f 100644 --- a/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RunningTasksTest.java @@ -50,7 +50,7 @@ import java.util.ArrayList; public class RunningTasksTest extends ActivityTestsBase { private Context mContext = InstrumentationRegistry.getContext(); - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private RunningTasks mRunningTasks; @@ -59,7 +59,7 @@ public class RunningTasksTest extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mRunningTasks = new RunningTasks(); } diff --git a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java index 3d323f0eb783..f71a6e75a25f 100644 --- a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java +++ b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java @@ -57,7 +57,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { private final static Rect STACK_BOUNDS = new Rect(0, 0, STACK_WIDTH, STACK_HEIGHT); - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityStack mStack; private TaskRecord mTask; @@ -71,7 +71,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); - mService = createActivityManagerService(); + mService = createActivityTaskManagerService(); mStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */); mStack.requestResize(STACK_BOUNDS); diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index 3d64f2a1e95a..2de5d87c063c 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -41,7 +41,6 @@ import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.IUidObserver; import android.app.usage.UsageStatsManagerInternal; import android.content.ActivityNotFoundException; @@ -93,6 +92,7 @@ import com.android.server.SystemService; import com.android.server.pm.LauncherAppsService.LauncherAppsImpl; import com.android.server.pm.ShortcutUser.PackageWithUser; +import com.android.server.wm.ActivityTaskManagerInternal; import org.junit.Assert; import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java index 3514e5a22b89..c4c2ad926954 100644 --- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java @@ -14,7 +14,6 @@ import static org.mockito.Mockito.when; import static org.testng.Assert.assertThrows; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.app.AppOpsManager; import android.app.IApplicationThread; import android.content.ComponentName; @@ -32,6 +31,8 @@ import android.os.UserManager; import android.platform.test.annotations.Presubmit; import android.util.SparseArray; +import com.android.server.wm.ActivityTaskManagerInternal; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java index 69cfaad37f8c..d13c3c9efc20 100644 --- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java @@ -29,7 +29,6 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; import android.content.Context; import android.hardware.display.DisplayManagerInternal; import android.os.PowerManagerInternal; diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index a919d38ab6ba..63945a9b0b47 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -20,8 +20,8 @@ import static com.android.internal.usb.DumpUtils.writeAccessory; import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import android.app.ActivityManager; -import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; + +import com.android.server.wm.ActivityTaskManagerInternal; import android.app.KeyguardManager; import android.app.Notification; import android.app.NotificationChannel; diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 4e49782085df..c5d6dc7da5a7 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -19,7 +19,7 @@ package com.android.server.voiceinteraction; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManagerInternal; -import android.app.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 54f99a66f5ea..92aa152413a6 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -23,10 +23,9 @@ import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import android.app.ActivityManager; -import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; -import android.app.ActivityTaskManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import android.app.IActivityManager; import android.app.IActivityTaskManager; import android.content.BroadcastReceiver; @@ -50,7 +49,6 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.view.IWindowManager; -import com.android.internal.app.IVoiceInteractionSessionListener; import com.android.internal.app.IVoiceInteractionSessionShowCallback; import com.android.internal.app.IVoiceInteractor; import com.android.server.LocalServices; diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index 606d0275e60a..01f5d9c11f3e 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -16,9 +16,9 @@ package com.android.server.voiceinteraction; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA; -import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA; +import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import static android.app.AppOpsManager.OP_ASSIST_SCREENSHOT; import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; |