Loading services/core/java/com/android/server/am/ActiveServices.java +41 −33 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import android.app.ActivityThread; import android.os.Build; Loading Loading @@ -119,14 +120,13 @@ public final class ActiveServices { // at the same time. final int mMaxStartingBackground; final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>(); final SparseArray<ServiceMap> mServiceMap = new SparseArray<>(); /** * All currently bound service connections. Keys are the IBinder of * the client's IServiceConnection. */ final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<>(); /** * List of services that we have been asked to start, Loading @@ -134,20 +134,20 @@ public final class ActiveServices { * while waiting for their corresponding application thread to get * going. */ final ArrayList<ServiceRecord> mPendingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>(); /** * List of services that are scheduled to restart following a crash. */ final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>(); /** * List of services that are in the process of being destroyed. */ final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>(); /** Temporary list for holding the results of calls to {@link #collectPackageServicesLocked} */ private ArrayList<ServiceRecord> mTmpCollectionResults = null; /** Amount of time to allow a last ANR message to exist before freeing the memory. */ static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours Loading @@ -162,10 +162,6 @@ public final class ActiveServices { } }; static final class DelayingProcess extends ArrayList<ServiceRecord> { long timeoout; } /** * Information about services for a single user. */ Loading Loading @@ -2076,14 +2072,16 @@ public final class ActiveServices { } } private boolean collectForceStopServicesLocked(String name, int userId, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services, ArrayList<ServiceRecord> result) { private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) { boolean didSomething = false; for (int i=0; i<services.size(); i++) { for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord service = services.valueAt(i); if ((name == null || service.packageName.equals(name)) final boolean sameComponent = packageName == null || (service.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(service.name.getClassName()))); if (sameComponent && (service.app == null || evenPersistent || !service.app.persistent)) { if (!doit) { return true; Loading @@ -2098,19 +2096,27 @@ public final class ActiveServices { } service.app = null; service.isolatedProc = null; result.add(service); if (mTmpCollectionResults == null) { mTmpCollectionResults = new ArrayList<>(); } mTmpCollectionResults.add(service); } } return didSomething; } boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) { boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean doit) { boolean didSomething = false; ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); if (mTmpCollectionResults != null) { mTmpCollectionResults.clear(); } if (userId == UserHandle.USER_ALL) { for (int i=0; i<mServiceMap.size(); i++) { didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName, services); for (int i = mServiceMap.size() - 1; i >= 0; i--) { didSomething |= collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName); if (!doit && didSomething) { return true; } Loading @@ -2119,22 +2125,24 @@ public final class ActiveServices { ServiceMap smap = mServiceMap.get(userId); if (smap != null) { ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName; didSomething = collectForceStopServicesLocked(name, userId, evenPersistent, doit, items, services); didSomething = collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, items); } } int N = services.size(); for (int i=0; i<N; i++) { bringDownServiceLocked(services.get(i)); if (mTmpCollectionResults != null) { for (int i = mTmpCollectionResults.size() - 1; i >= 0; i--) { bringDownServiceLocked(mTmpCollectionResults.get(i)); } mTmpCollectionResults.clear(); } return didSomething; } void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) { ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); ArrayList<ServiceRecord> services = new ArrayList<>(); ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId); for (int i=0; i<alls.size(); i++) { for (int i = alls.size() - 1; i >= 0; i--) { ServiceRecord sr = alls.valueAt(i); if (sr.packageName.equals(component.getPackageName())) { services.add(sr); Loading @@ -2142,7 +2150,7 @@ public final class ActiveServices { } // Take care of any running services associated with the app. for (int i=0; i<services.size(); i++) { for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord sr = services.get(i); if (sr.startRequested) { if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +116 −47 Original line number Diff line number Diff line Loading @@ -5363,27 +5363,105 @@ public final class ActivityManagerService extends ActivityManagerNative return N > 0; } private final boolean forceStopPackageLocked(String name, int appId, private void cleanupDisabledPackageComponentsLocked( String packageName, int userId, String[] changedClasses) { Set<String> disabledClasses = null; boolean packageDisabled = false; IPackageManager pm = AppGlobals.getPackageManager(); if (changedClasses == null) { // Nothing changed... return; } // Determine enable/disable state of the package and its components. int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; for (int i = changedClasses.length - 1; i >= 0; i--) { final String changedClass = changedClasses[i]; if (changedClass.equals(packageName)) { try { // Entire package setting changed enabled = pm.getApplicationEnabledSetting(packageName, (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER); } catch (RemoteException e) { // Can't happen... } packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; if (packageDisabled) { // Entire package is disabled. // No need to continue to check component states. disabledClasses = null; break; } } else { try { enabled = pm.getComponentEnabledSetting( new ComponentName(packageName, changedClass), (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER); } catch (RemoteException e) { // Can't happen... } if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { if (disabledClasses == null) { disabledClasses = new ArraySet<>(changedClasses.length); } disabledClasses.add(changedClass); } } } if (!packageDisabled && disabledClasses == null) { // Nothing to do here... return; } // Clean-up disabled activities. if (mStackSupervisor.finishDisabledPackageActivitiesLocked( packageName, disabledClasses, true, false, userId) && mBooted) { mStackSupervisor.resumeTopActivitiesLocked(); mStackSupervisor.scheduleIdleLocked(); } // Clean-up disabled tasks cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId); // Clean-up disabled services. mServices.bringDownDisabledPackageServicesLocked( packageName, disabledClasses, userId, false, true); // Clean-up disabled providers. ArrayList<ContentProviderRecord> providers = new ArrayList<>(); mProviderMap.collectPackageProvidersLocked( packageName, disabledClasses, true, false, userId, providers); for (int i = providers.size() - 1; i >= 0; i--) { removeDyingProviderLocked(null, providers.get(i), true); } } private final boolean forceStopPackageLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, int userId, String reason) { int i; int N; if (userId == UserHandle.USER_ALL && name == null) { if (userId == UserHandle.USER_ALL && packageName == null) { Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); } if (appId < 0 && name != null) { if (appId < 0 && packageName != null) { try { appId = UserHandle.getAppId( AppGlobals.getPackageManager().getPackageUid(name, 0)); AppGlobals.getPackageManager().getPackageUid(packageName, 0)); } catch (RemoteException e) { } } if (doit) { if (name != null) { Slog.i(TAG, "Force stopping " + name + " appid=" + appId if (packageName != null) { Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId + " user=" + userId + ": " + reason); } else { Slog.i(TAG, "Force stopping u" + userId + ": " + reason); Loading @@ -5395,7 +5473,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (i = ba.size() - 1; i >= 0; i--) { boolean remove = false; final int entUid = ba.keyAt(i); if (name != null) { if (packageName != null) { if (userId == UserHandle.USER_ALL) { if (UserHandle.getAppId(entUid) == appId) { remove = true; Loading @@ -5418,46 +5496,47 @@ public final class ActivityManagerService extends ActivityManagerNative } } boolean didSomething = killPackageProcessesLocked(name, appId, userId, boolean didSomething = killPackageProcessesLocked(packageName, appId, userId, -100, callerWillRestart, true, doit, evenPersistent, name == null ? ("stop user " + userId) : ("stop " + name)); packageName == null ? ("stop user " + userId) : ("stop " + packageName)); if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { if (mStackSupervisor.finishDisabledPackageActivitiesLocked( packageName, null, doit, evenPersistent, userId)) { if (!doit) { return true; } didSomething = true; } if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { if (mServices.bringDownDisabledPackageServicesLocked( packageName, null, userId, evenPersistent, doit)) { if (!doit) { return true; } didSomething = true; } if (name == null) { if (packageName == null) { // Remove all sticky broadcasts from this user. mStickyBroadcasts.remove(userId); } ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, ArrayList<ContentProviderRecord> providers = new ArrayList<>(); if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent, userId, providers)) { if (!doit) { return true; } didSomething = true; } N = providers.size(); for (i=0; i<N; i++) { for (i = providers.size() - 1; i >= 0; i--) { removeDyingProviderLocked(null, providers.get(i), true); } // Remove transient permissions granted from/to this package/user removeUriPermissionsForPackageLocked(name, userId, false); removeUriPermissionsForPackageLocked(packageName, userId, false); if (name == null || uninstalling) { if (packageName == null || uninstalling) { // Remove pending intents. For now we only do this when force // stopping users, because we have some problems when doing this // for packages -- app widgets are not currently cleaned up for Loading @@ -5476,7 +5555,7 @@ public final class ActivityManagerService extends ActivityManagerNative it.remove(); continue; } if (name == null) { if (packageName == null) { // Stopping user, remove all objects for the user. if (pir.key.userId != userId) { // Not the same user, skip it. Loading @@ -5491,7 +5570,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Different user, skip it. continue; } if (!pir.key.packageName.equals(name)) { if (!pir.key.packageName.equals(packageName)) { // Different package, skip it. continue; } Loading @@ -5510,10 +5589,10 @@ public final class ActivityManagerService extends ActivityManagerNative } if (doit) { if (purgeCache && name != null) { if (purgeCache && packageName != null) { AttributeCache ac = AttributeCache.instance(); if (ac != null) { ac.removePackage(name); ac.removePackage(packageName); } } if (mBooted) { Loading Loading @@ -8331,30 +8410,21 @@ public final class ActivityManagerService extends ActivityManagerNative } } private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { final IPackageManager pm = AppGlobals.getPackageManager(); final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, int userId) { for (int i = mRecentTasks.size() - 1; i >= 0; i--) { TaskRecord tr = mRecentTasks.get(i); if (tr.userId != userId) continue; if (userId != UserHandle.USER_ALL && tr.userId != userId) { continue; } ComponentName cn = tr.intent.getComponent(); if (cn != null && cn.getPackageName().equals(packageName)) { // Skip if component still exists in the package. if (componentsKnownToExist.contains(cn)) continue; try { ActivityInfo info = pm.getActivityInfo(cn, 0, userId); if (info != null) { componentsKnownToExist.add(cn); } else { final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName) && (filterByClasses == null || filterByClasses.contains(cn.getClassName())); if (sameComponent) { removeTaskByIdLocked(tr.taskId, false); } } catch (RemoteException e) { Log.e(TAG, "Activity info query failed. component=" + cn, e); } } } } Loading Loading @@ -16076,7 +16146,9 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.notePackageUninstalled(ssp); } } else { removeTasksByRemovedPackageComponentsLocked(ssp, userId); cleanupDisabledPackageComponentsLocked(ssp, userId, intent.getStringArrayExtra( Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); if (userId == UserHandle.USER_OWNER) { mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); } Loading @@ -16094,9 +16166,6 @@ public final class ActivityManagerService extends ActivityManagerNative intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); mCompatModePackages.handlePackageAddedLocked(ssp, replacing); if (replacing) { removeTasksByRemovedPackageComponentsLocked(ssp, userId); } if (userId == UserHandle.USER_OWNER) { mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); } services/core/java/com/android/server/am/ActivityStack.java +9 −5 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; /** * State and management of a single stack of activities. Loading Loading @@ -4000,7 +4001,8 @@ final class ActivityStack { } } boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId) { boolean didSomething = false; TaskRecord lastTask = null; ComponentName homeActivity = null; Loading @@ -4009,10 +4011,12 @@ final class ActivityStack { int numActivities = activities.size(); for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { ActivityRecord r = activities.get(activityNdx); final boolean samePackage = r.packageName.equals(name) || (name == null && r.userId == userId); final boolean sameComponent = (r.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(r.realActivity.getClassName()))) || (packageName == null && r.userId == userId); if ((userId == UserHandle.USER_ALL || r.userId == userId) && (samePackage || r.task == lastTask) && (sameComponent || r.task == lastTask) && (r.app == null || evenPersistent || !r.app.persistent)) { if (!doit) { if (r.finishing) { Loading @@ -4032,7 +4036,7 @@ final class ActivityStack { } didSomething = true; Slog.i(TAG, " Force finishing activity " + r); if (samePackage) { if (sameComponent) { if (r.app != null) { r.app.removed = true; } Loading services/core/java/com/android/server/am/ActivityStackSupervisor.java +5 −2 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; public final class ActivityStackSupervisor implements DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; Loading Loading @@ -2507,14 +2508,16 @@ public final class ActivityStackSupervisor implements DisplayListener { /** * @return true if some activity was finished (or would have finished if doit were true). */ boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId) { boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; final int numStacks = stacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { if (stack.finishDisabledPackageActivitiesLocked( packageName, filterByClasses, doit, evenPersistent, userId)) { didSomething = true; } } Loading services/core/java/com/android/server/am/BroadcastQueue.java +2 −2 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public final class BroadcastQueue { * a bunch of processes to execute IntentReceiver components. Background- * and foreground-priority broadcasts are queued separately. */ final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>(); final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>(); /** * List of all active broadcasts that are to be executed one at a time. Loading @@ -94,7 +94,7 @@ public final class BroadcastQueue { * broadcasts, separate background- and foreground-priority queues are * maintained. */ final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>(); final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>(); /** * Historical data of past broadcasts, for debugging. This is a ring buffer Loading Loading
services/core/java/com/android/server/am/ActiveServices.java +41 −33 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import android.app.ActivityThread; import android.os.Build; Loading Loading @@ -119,14 +120,13 @@ public final class ActiveServices { // at the same time. final int mMaxStartingBackground; final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>(); final SparseArray<ServiceMap> mServiceMap = new SparseArray<>(); /** * All currently bound service connections. Keys are the IBinder of * the client's IServiceConnection. */ final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<>(); /** * List of services that we have been asked to start, Loading @@ -134,20 +134,20 @@ public final class ActiveServices { * while waiting for their corresponding application thread to get * going. */ final ArrayList<ServiceRecord> mPendingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>(); /** * List of services that are scheduled to restart following a crash. */ final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>(); /** * List of services that are in the process of being destroyed. */ final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<ServiceRecord>(); final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>(); /** Temporary list for holding the results of calls to {@link #collectPackageServicesLocked} */ private ArrayList<ServiceRecord> mTmpCollectionResults = null; /** Amount of time to allow a last ANR message to exist before freeing the memory. */ static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours Loading @@ -162,10 +162,6 @@ public final class ActiveServices { } }; static final class DelayingProcess extends ArrayList<ServiceRecord> { long timeoout; } /** * Information about services for a single user. */ Loading Loading @@ -2076,14 +2072,16 @@ public final class ActiveServices { } } private boolean collectForceStopServicesLocked(String name, int userId, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services, ArrayList<ServiceRecord> result) { private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses, boolean evenPersistent, boolean doit, ArrayMap<ComponentName, ServiceRecord> services) { boolean didSomething = false; for (int i=0; i<services.size(); i++) { for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord service = services.valueAt(i); if ((name == null || service.packageName.equals(name)) final boolean sameComponent = packageName == null || (service.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(service.name.getClassName()))); if (sameComponent && (service.app == null || evenPersistent || !service.app.persistent)) { if (!doit) { return true; Loading @@ -2098,19 +2096,27 @@ public final class ActiveServices { } service.app = null; service.isolatedProc = null; result.add(service); if (mTmpCollectionResults == null) { mTmpCollectionResults = new ArrayList<>(); } mTmpCollectionResults.add(service); } } return didSomething; } boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) { boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses, int userId, boolean evenPersistent, boolean doit) { boolean didSomething = false; ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); if (mTmpCollectionResults != null) { mTmpCollectionResults.clear(); } if (userId == UserHandle.USER_ALL) { for (int i=0; i<mServiceMap.size(); i++) { didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName, services); for (int i = mServiceMap.size() - 1; i >= 0; i--) { didSomething |= collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, mServiceMap.valueAt(i).mServicesByName); if (!doit && didSomething) { return true; } Loading @@ -2119,22 +2125,24 @@ public final class ActiveServices { ServiceMap smap = mServiceMap.get(userId); if (smap != null) { ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName; didSomething = collectForceStopServicesLocked(name, userId, evenPersistent, doit, items, services); didSomething = collectPackageServicesLocked(packageName, filterByClasses, evenPersistent, doit, items); } } int N = services.size(); for (int i=0; i<N; i++) { bringDownServiceLocked(services.get(i)); if (mTmpCollectionResults != null) { for (int i = mTmpCollectionResults.size() - 1; i >= 0; i--) { bringDownServiceLocked(mTmpCollectionResults.get(i)); } mTmpCollectionResults.clear(); } return didSomething; } void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) { ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>(); ArrayList<ServiceRecord> services = new ArrayList<>(); ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId); for (int i=0; i<alls.size(); i++) { for (int i = alls.size() - 1; i >= 0; i--) { ServiceRecord sr = alls.valueAt(i); if (sr.packageName.equals(component.getPackageName())) { services.add(sr); Loading @@ -2142,7 +2150,7 @@ public final class ActiveServices { } // Take care of any running services associated with the app. for (int i=0; i<services.size(); i++) { for (int i = services.size() - 1; i >= 0; i--) { ServiceRecord sr = services.get(i); if (sr.startRequested) { if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +116 −47 Original line number Diff line number Diff line Loading @@ -5363,27 +5363,105 @@ public final class ActivityManagerService extends ActivityManagerNative return N > 0; } private final boolean forceStopPackageLocked(String name, int appId, private void cleanupDisabledPackageComponentsLocked( String packageName, int userId, String[] changedClasses) { Set<String> disabledClasses = null; boolean packageDisabled = false; IPackageManager pm = AppGlobals.getPackageManager(); if (changedClasses == null) { // Nothing changed... return; } // Determine enable/disable state of the package and its components. int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; for (int i = changedClasses.length - 1; i >= 0; i--) { final String changedClass = changedClasses[i]; if (changedClass.equals(packageName)) { try { // Entire package setting changed enabled = pm.getApplicationEnabledSetting(packageName, (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER); } catch (RemoteException e) { // Can't happen... } packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; if (packageDisabled) { // Entire package is disabled. // No need to continue to check component states. disabledClasses = null; break; } } else { try { enabled = pm.getComponentEnabledSetting( new ComponentName(packageName, changedClass), (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER); } catch (RemoteException e) { // Can't happen... } if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) { if (disabledClasses == null) { disabledClasses = new ArraySet<>(changedClasses.length); } disabledClasses.add(changedClass); } } } if (!packageDisabled && disabledClasses == null) { // Nothing to do here... return; } // Clean-up disabled activities. if (mStackSupervisor.finishDisabledPackageActivitiesLocked( packageName, disabledClasses, true, false, userId) && mBooted) { mStackSupervisor.resumeTopActivitiesLocked(); mStackSupervisor.scheduleIdleLocked(); } // Clean-up disabled tasks cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId); // Clean-up disabled services. mServices.bringDownDisabledPackageServicesLocked( packageName, disabledClasses, userId, false, true); // Clean-up disabled providers. ArrayList<ContentProviderRecord> providers = new ArrayList<>(); mProviderMap.collectPackageProvidersLocked( packageName, disabledClasses, true, false, userId, providers); for (int i = providers.size() - 1; i >= 0; i--) { removeDyingProviderLocked(null, providers.get(i), true); } } private final boolean forceStopPackageLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, int userId, String reason) { int i; int N; if (userId == UserHandle.USER_ALL && name == null) { if (userId == UserHandle.USER_ALL && packageName == null) { Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); } if (appId < 0 && name != null) { if (appId < 0 && packageName != null) { try { appId = UserHandle.getAppId( AppGlobals.getPackageManager().getPackageUid(name, 0)); AppGlobals.getPackageManager().getPackageUid(packageName, 0)); } catch (RemoteException e) { } } if (doit) { if (name != null) { Slog.i(TAG, "Force stopping " + name + " appid=" + appId if (packageName != null) { Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId + " user=" + userId + ": " + reason); } else { Slog.i(TAG, "Force stopping u" + userId + ": " + reason); Loading @@ -5395,7 +5473,7 @@ public final class ActivityManagerService extends ActivityManagerNative for (i = ba.size() - 1; i >= 0; i--) { boolean remove = false; final int entUid = ba.keyAt(i); if (name != null) { if (packageName != null) { if (userId == UserHandle.USER_ALL) { if (UserHandle.getAppId(entUid) == appId) { remove = true; Loading @@ -5418,46 +5496,47 @@ public final class ActivityManagerService extends ActivityManagerNative } } boolean didSomething = killPackageProcessesLocked(name, appId, userId, boolean didSomething = killPackageProcessesLocked(packageName, appId, userId, -100, callerWillRestart, true, doit, evenPersistent, name == null ? ("stop user " + userId) : ("stop " + name)); packageName == null ? ("stop user " + userId) : ("stop " + packageName)); if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { if (mStackSupervisor.finishDisabledPackageActivitiesLocked( packageName, null, doit, evenPersistent, userId)) { if (!doit) { return true; } didSomething = true; } if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { if (mServices.bringDownDisabledPackageServicesLocked( packageName, null, userId, evenPersistent, doit)) { if (!doit) { return true; } didSomething = true; } if (name == null) { if (packageName == null) { // Remove all sticky broadcasts from this user. mStickyBroadcasts.remove(userId); } ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, ArrayList<ContentProviderRecord> providers = new ArrayList<>(); if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent, userId, providers)) { if (!doit) { return true; } didSomething = true; } N = providers.size(); for (i=0; i<N; i++) { for (i = providers.size() - 1; i >= 0; i--) { removeDyingProviderLocked(null, providers.get(i), true); } // Remove transient permissions granted from/to this package/user removeUriPermissionsForPackageLocked(name, userId, false); removeUriPermissionsForPackageLocked(packageName, userId, false); if (name == null || uninstalling) { if (packageName == null || uninstalling) { // Remove pending intents. For now we only do this when force // stopping users, because we have some problems when doing this // for packages -- app widgets are not currently cleaned up for Loading @@ -5476,7 +5555,7 @@ public final class ActivityManagerService extends ActivityManagerNative it.remove(); continue; } if (name == null) { if (packageName == null) { // Stopping user, remove all objects for the user. if (pir.key.userId != userId) { // Not the same user, skip it. Loading @@ -5491,7 +5570,7 @@ public final class ActivityManagerService extends ActivityManagerNative // Different user, skip it. continue; } if (!pir.key.packageName.equals(name)) { if (!pir.key.packageName.equals(packageName)) { // Different package, skip it. continue; } Loading @@ -5510,10 +5589,10 @@ public final class ActivityManagerService extends ActivityManagerNative } if (doit) { if (purgeCache && name != null) { if (purgeCache && packageName != null) { AttributeCache ac = AttributeCache.instance(); if (ac != null) { ac.removePackage(name); ac.removePackage(packageName); } } if (mBooted) { Loading Loading @@ -8331,30 +8410,21 @@ public final class ActivityManagerService extends ActivityManagerNative } } private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) { final IPackageManager pm = AppGlobals.getPackageManager(); final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, int userId) { for (int i = mRecentTasks.size() - 1; i >= 0; i--) { TaskRecord tr = mRecentTasks.get(i); if (tr.userId != userId) continue; if (userId != UserHandle.USER_ALL && tr.userId != userId) { continue; } ComponentName cn = tr.intent.getComponent(); if (cn != null && cn.getPackageName().equals(packageName)) { // Skip if component still exists in the package. if (componentsKnownToExist.contains(cn)) continue; try { ActivityInfo info = pm.getActivityInfo(cn, 0, userId); if (info != null) { componentsKnownToExist.add(cn); } else { final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName) && (filterByClasses == null || filterByClasses.contains(cn.getClassName())); if (sameComponent) { removeTaskByIdLocked(tr.taskId, false); } } catch (RemoteException e) { Log.e(TAG, "Activity info query failed. component=" + cn, e); } } } } Loading Loading @@ -16076,7 +16146,9 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.notePackageUninstalled(ssp); } } else { removeTasksByRemovedPackageComponentsLocked(ssp, userId); cleanupDisabledPackageComponentsLocked(ssp, userId, intent.getStringArrayExtra( Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST)); if (userId == UserHandle.USER_OWNER) { mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); } Loading @@ -16094,9 +16166,6 @@ public final class ActivityManagerService extends ActivityManagerNative intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); mCompatModePackages.handlePackageAddedLocked(ssp, replacing); if (replacing) { removeTasksByRemovedPackageComponentsLocked(ssp, userId); } if (userId == UserHandle.USER_OWNER) { mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp); }
services/core/java/com/android/server/am/ActivityStack.java +9 −5 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Set; /** * State and management of a single stack of activities. Loading Loading @@ -4000,7 +4001,8 @@ final class ActivityStack { } } boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId) { boolean didSomething = false; TaskRecord lastTask = null; ComponentName homeActivity = null; Loading @@ -4009,10 +4011,12 @@ final class ActivityStack { int numActivities = activities.size(); for (int activityNdx = 0; activityNdx < numActivities; ++activityNdx) { ActivityRecord r = activities.get(activityNdx); final boolean samePackage = r.packageName.equals(name) || (name == null && r.userId == userId); final boolean sameComponent = (r.packageName.equals(packageName) && (filterByClasses == null || filterByClasses.contains(r.realActivity.getClassName()))) || (packageName == null && r.userId == userId); if ((userId == UserHandle.USER_ALL || r.userId == userId) && (samePackage || r.task == lastTask) && (sameComponent || r.task == lastTask) && (r.app == null || evenPersistent || !r.app.persistent)) { if (!doit) { if (r.finishing) { Loading @@ -4032,7 +4036,7 @@ final class ActivityStack { } didSomething = true; Slog.i(TAG, " Force finishing activity " + r); if (samePackage) { if (sameComponent) { if (r.app != null) { r.app.removed = true; } Loading
services/core/java/com/android/server/am/ActivityStackSupervisor.java +5 −2 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; public final class ActivityStackSupervisor implements DisplayListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM; Loading Loading @@ -2507,14 +2508,16 @@ public final class ActivityStackSupervisor implements DisplayListener { /** * @return true if some activity was finished (or would have finished if doit were true). */ boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { boolean finishDisabledPackageActivitiesLocked(String packageName, Set<String> filterByClasses, boolean doit, boolean evenPersistent, int userId) { boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; final int numStacks = stacks.size(); for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { if (stack.finishDisabledPackageActivitiesLocked( packageName, filterByClasses, doit, evenPersistent, userId)) { didSomething = true; } } Loading
services/core/java/com/android/server/am/BroadcastQueue.java +2 −2 Original line number Diff line number Diff line Loading @@ -85,7 +85,7 @@ public final class BroadcastQueue { * a bunch of processes to execute IntentReceiver components. Background- * and foreground-priority broadcasts are queued separately. */ final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>(); final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>(); /** * List of all active broadcasts that are to be executed one at a time. Loading @@ -94,7 +94,7 @@ public final class BroadcastQueue { * broadcasts, separate background- and foreground-priority queues are * maintained. */ final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>(); final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>(); /** * Historical data of past broadcasts, for debugging. This is a ring buffer Loading