- /**
- * Monitor for package changes and update our internal state.
- */
- private final PackageMonitor mPackageMonitor = new PackageMonitor() {
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- // Remove all tasks with activities in the specified package from the list of recent tasks
- final int eventUserId = getChangingUserId();
- synchronized (ActivityManagerService.this) {
- for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
- TaskRecord tr = mRecentTasks.get(i);
- if (tr.userId != eventUserId) continue;
-
- ComponentName cn = tr.intent.getComponent();
- if (cn != null && cn.getPackageName().equals(packageName)) {
- // If the package name matches, remove the task
- removeTaskByIdLocked(tr.taskId, true);
- }
- }
- }
- }
-
- @Override
- public boolean onPackageChanged(String packageName, int uid, String[] components) {
- onPackageModified(packageName);
- return true;
- }
-
- @Override
- public void onPackageModified(String packageName) {
- final int eventUserId = getChangingUserId();
- final IPackageManager pm = AppGlobals.getPackageManager();
- final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
- new ArrayList<Pair<Intent, Integer>>();
- final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
- final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
- // Copy the list of recent tasks so that we don't hold onto the lock on
- // ActivityManagerService for long periods while checking if components exist.
- synchronized (ActivityManagerService.this) {
- for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
- TaskRecord tr = mRecentTasks.get(i);
- if (tr.userId != eventUserId) continue;
-
- recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
- }
- }
- // Check the recent tasks and filter out all tasks with components that no longer exist.
- for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
- Pair<Intent, Integer> p = recentTaskIntents.get(i);
- ComponentName cn = p.first.getComponent();
- if (cn != null && cn.getPackageName().equals(packageName)) {
- if (componentsKnownToExist.contains(cn)) {
- // If we know that the component still exists in the package, then skip
- continue;
- }
- try {
- ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
- if (info != null) {
- componentsKnownToExist.add(cn);
- } else {
- tasksToRemove.add(p.second);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to query activity info for component: " + cn, e);
- }
- }
- }
- // Prune all the tasks with removed components from the list of recent tasks
- synchronized (ActivityManagerService.this) {
- for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
- removeTaskByIdLocked(tasksToRemove.get(i), false);
- }
- }
- }
-
- @Override
- public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
- // Force stop the specified packages
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
- if (packages != null) {
- for (String pkg : packages) {
- synchronized (ActivityManagerService.this) {
- if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
- userId, "finished booting")) {
- return true;
- }
- }
- }
- }
- return false;
- }
- };
-