From cae015fea398e1d99c0b538991535330f31fe543 Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Fri, 8 Feb 2013 14:31:27 -0800 Subject: [PATCH] Make ActivityStack.mHistory private. Isolate the Activity history for later conversion to Task-based management. Change-Id: I4b6bf22de035c768aa705df0cc4f84486e8ede56 --- .../server/am/ActivityManagerService.java | 297 +++--------------- .../com/android/server/am/ActivityStack.java | 270 +++++++++++++++- .../android/server/am/CompatModePackages.java | 16 +- .../server/am/PendingThumbnailsRecord.java | 4 +- 4 files changed, 308 insertions(+), 279 deletions(-) diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 7b6e79ea9ee28..9a64a7e002e06 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -37,6 +37,7 @@ import dalvik.system.Zygote; import android.app.Activity; import android.app.ActivityManager; +import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManagerNative; import android.app.ActivityOptions; import android.app.ActivityThread; @@ -328,7 +329,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * List of intents that were used to start the most recent tasks. */ - final ArrayList mRecentTasks = new ArrayList(); + private final ArrayList mRecentTasks = new ArrayList(); public class PendingActivityExtras extends Binder implements Runnable { public final ActivityRecord activity; @@ -596,13 +597,8 @@ public final class ActivityManagerService extends ActivityManagerNative * List of PendingThumbnailsRecord objects of clients who are still * waiting to receive all of the thumbnails for a task. */ - final ArrayList mPendingThumbnails = new ArrayList(); - - /** - * List of HistoryRecord objects that have been finished and must - * still report back to a pending thumbnail receiver. - */ - final ArrayList mCancelledThumbnails = new ArrayList(); + final ArrayList mPendingThumbnails = + new ArrayList(); final ProviderMap mProviderMap; @@ -2932,22 +2928,13 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public boolean willActivityBeVisible(IBinder token) { synchronized(this) { - int i; - for (i=mMainStack.mHistory.size()-1; i>=0; i--) { - ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); - if (r.appToken == token) { - return true; - } - if (r.fullscreen && !r.finishing) { - return false; - } - } - return true; + return mMainStack.willActivityBeVisibleLocked(token); } } - + public void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim) { synchronized(this) { @@ -3717,13 +3704,7 @@ public final class ActivityManagerService extends ActivityManagerNative } mWindowManager.closeSystemDialogs(reason); - for (int i=mMainStack.mHistory.size()-1; i>=0; i--) { - ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); - if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { - r.stack.finishActivityLocked(r, i, - Activity.RESULT_CANCELED, null, "close-sys", true); - } - } + mMainStack.closeSystemDialogsLocked(); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, @@ -3930,37 +3911,12 @@ public final class ActivityManagerService extends ActivityManagerNative boolean didSomething = killPackageProcessesLocked(name, appId, userId, -100, callerWillRestart, true, doit, evenPersistent, name == null ? ("force stop user " + userId) : ("force stop " + name)); - - TaskRecord lastTask = null; - for (i=0; i getTasks(int maxNum, int flags, IThumbnailReceiver receiver) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); - PendingThumbnailsRecord pending = null; - IApplicationThread topThumbnail = null; + PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); ActivityRecord topRecord = null; synchronized(this) { @@ -5701,88 +5657,19 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } - int pos = mMainStack.mHistory.size()-1; - ActivityRecord next = - pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; - ActivityRecord top = null; - TaskRecord curTask = null; - int numActivities = 0; - int numRunning = 0; - while (pos >= 0 && maxNum > 0) { - final ActivityRecord r = next; - pos--; - next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null; + topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list); - // Initialize state for next task if needed. - if (top == null || - (top.state == ActivityState.INITIALIZING - && top.task == r.task)) { - top = r; - curTask = r.task; - numActivities = numRunning = 0; - } - - // Add 'r' into the current task. - numActivities++; - if (r.app != null && r.app.thread != null) { - numRunning++; - } - - if (localLOGV) Slog.v( - TAG, r.intent.getComponent().flattenToShortString() - + ": task=" + r.task); - - // If the next one is a different task, generate a new - // TaskInfo entry for what we have. - if (next == null || next.task != curTask) { - ActivityManager.RunningTaskInfo ci - = new ActivityManager.RunningTaskInfo(); - ci.id = curTask.taskId; - ci.baseActivity = r.intent.getComponent(); - ci.topActivity = top.intent.getComponent(); - if (top.thumbHolder != null) { - ci.description = top.thumbHolder.lastDescription; - } - ci.numActivities = numActivities; - ci.numRunning = numRunning; - //System.out.println( - // "#" + maxNum + ": " + " descr=" + ci.description); - if (ci.thumbnail == null && receiver != null) { - if (localLOGV) Slog.v( - TAG, "State=" + top.state + "Idle=" + top.idle - + " app=" + top.app - + " thr=" + (top.app != null ? top.app.thread : null)); - if (top.state == ActivityState.RESUMED - || top.state == ActivityState.PAUSING) { - if (top.idle && top.app != null - && top.app.thread != null) { - topRecord = top; - topThumbnail = top.app.thread; - } else { - top.thumbnailNeeded = true; - } - } - if (pending == null) { - pending = new PendingThumbnailsRecord(receiver); - } - pending.pendingRecords.add(top); - } - list.add(ci); - maxNum--; - top = null; - } - } - - if (pending != null) { + if (!pending.pendingRecords.isEmpty()) { mPendingThumbnails.add(pending); } } if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); - if (topThumbnail != null) { + if (topRecord != null) { if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); try { + IApplicationThread topThumbnail = topRecord.app.thread; topThumbnail.requestThumbnail(topRecord.appToken); } catch (Exception e) { Slog.w(TAG, "Exception thrown when requesting thumbnail", e); @@ -6017,43 +5904,6 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } - private final int findAffinityTaskTopLocked(int startIndex, String affinity) { - int j; - TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task; - TaskRecord jt = startTask; - - // First look backwards - for (j=startIndex-1; j>=0; j--) { - ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); - if (r.task != jt) { - jt = r.task; - if (affinity.equals(jt.affinity)) { - return j; - } - } - } - - // Now look forwards - final int N = mMainStack.mHistory.size(); - jt = startTask; - for (j=startIndex+1; j=0; i--) { - ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i); - if (hr.task.taskId == task) { - if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { - mMainStack.mUserLeaving = true; - } - if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) { - // Caller wants the home activity moved with it. To accomplish this, - // we'll just move the home task to the top first. - mMainStack.moveHomeToFrontLocked(); - } - mMainStack.moveTaskToFrontLocked(hr.task, null, options); - return; - } + if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) { + return; } } finally { Binder.restoreCallingIdentity(origId); @@ -6135,7 +5973,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("moveActivityTaskToBack"); synchronized(this) { final long origId = Binder.clearCallingIdentity(); - int taskId = getTaskForActivityLocked(token, !nonRoot); + int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot); if (taskId >= 0) { return mMainStack.moveTaskToBackLocked(taskId, null); } @@ -6165,27 +6003,10 @@ public final class ActivityManagerService extends ActivityManagerNative public int getTaskForActivity(IBinder token, boolean onlyRoot) { synchronized(this) { - return getTaskForActivityLocked(token, onlyRoot); + return mMainStack.getTaskForActivityLocked(token, onlyRoot); } } - int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { - final int N = mMainStack.mHistory.size(); - TaskRecord lastTask = null; - for (int i=0; i=0; i--) { - ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); - if (r.app == app) { - Slog.w(TAG, " Force finishing activity " - + r.intent.getComponent().flattenToShortString()); - r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, - null, "crashed", false); - } - } + mMainStack.handleAppCrashLocked(app); if (!app.persistent) { // We don't want to start this process again until the user // explicitly does so... but for persistent process, we really @@ -8205,7 +8015,7 @@ public final class ActivityManagerService extends ActivityManagerNative // re-start our crashing activity once it gets resumed again. index--; if (index >= 0) { - r = (ActivityRecord)mMainStack.mHistory.get(index); + r = mMainStack.getActivityAtIndex(index); if (r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { @@ -9236,8 +9046,7 @@ public final class ActivityManagerService extends ActivityManagerNative int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); pw.println(" Main stack:"); - dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, - dumpPackage); + mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); pw.println(" "); pw.println(" Running activities (most recent first):"); dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, @@ -9767,32 +9576,10 @@ public final class ActivityManagerService extends ActivityManagerNative */ protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { - ArrayList activities = new ArrayList(); - - if ("all".equals(name)) { - synchronized (this) { - for (ActivityRecord r1 : (ArrayList)mMainStack.mHistory) { - activities.add(r1); - } - } - } else if ("top".equals(name)) { - synchronized (this) { - final int N = mMainStack.mHistory.size(); - if (N > 0) { - activities.add((ActivityRecord)mMainStack.mHistory.get(N-1)); - } - } - } else { - ItemMatcher matcher = new ItemMatcher(); - matcher.build(name); - - synchronized (this) { - for (ActivityRecord r1 : (ArrayList)mMainStack.mHistory) { - if (matcher.match(r1, r1.intent.getComponent())) { - activities.add(r1); - } - } - } + ArrayList activities; + + synchronized (this) { + activities = mMainStack.getDumpActivitiesLocked(name); } if (activities.size() <= 0) { @@ -10044,7 +9831,7 @@ public final class ActivityManagerService extends ActivityManagerNative return needSep; } - private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, + static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, String prefix, String label, boolean complete, boolean brief, boolean client, String dumpPackage) { TaskRecord lastTask = null; @@ -12584,8 +12371,8 @@ public final class ActivityManagerService extends ActivityManagerNative if (srec == null) { return false; } - ArrayList history = srec.stack.mHistory; - final int start = history.indexOf(srec); + ActivityStack stack = srec.stack; + final int start = stack.indexOfActivityLocked(srec); if (start < 0) { // Current activity is not in history stack; do nothing. return false; @@ -12596,13 +12383,13 @@ public final class ActivityManagerService extends ActivityManagerNative if (dest != null) { TaskRecord tr = srec.task; for (int i = start - 1; i >= 0; i--) { - ActivityRecord r = history.get(i); + ActivityRecord r = stack.getActivityAtIndex(i); if (tr != r.task) { // Couldn't find parent in the same task; stop at the one above this. // (Root of current task; in-app "home" behavior) // Always at least finish the current activity. finishTo = Math.min(start - 1, i + 1); - parent = history.get(finishTo); + parent = stack.getActivityAtIndex(finishTo); break; } else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) { @@ -12632,7 +12419,7 @@ public final class ActivityManagerService extends ActivityManagerNative } final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { - ActivityRecord r = history.get(i); + ActivityRecord r = stack.getActivityAtIndex(i); mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true); // Only return the supplied result for the first activity finished diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index e164d0e9bee37..d969709c9a9c7 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -21,8 +21,8 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.os.BatteryStatsImpl; +import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; -import com.android.server.am.ActivityRecord.Token; import com.android.server.wm.AppTransition; import android.app.Activity; @@ -30,10 +30,12 @@ import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; import android.app.IActivityManager; +import android.app.IThumbnailReceiver; import android.app.IThumbnailRetriever; import android.app.IApplicationThread; import android.app.PendingIntent; import android.app.ResultInfo; +import android.app.ActivityManager.RunningTaskInfo; import android.app.IActivityManager.WaitResult; import android.content.ComponentName; import android.content.Context; @@ -64,7 +66,9 @@ import android.util.Log; import android.util.Slog; import android.view.Display; +import java.io.FileDescriptor; import java.io.IOException; +import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; @@ -151,9 +155,9 @@ final class ActivityStack { /** * The back history of all previous (and possibly still - * running) activities. It contains HistoryRecord objects. + * running) activities. It contains #ActivityRecord objects. */ - final ArrayList mHistory = new ArrayList(); + private final ArrayList mHistory = new ArrayList(); /** * Used for validating app tokens with window manager. @@ -290,6 +294,12 @@ final class ActivityStack { private ActivityRecord mLastScreenshotActivity = null; private Bitmap mLastScreenshotBitmap = null; + /** + * List of ActivityRecord objects that have been finished and must + * still report back to a pending thumbnail receiver. + */ + private final ArrayList mCancelledThumbnails = new ArrayList(); + int mThumbnailWidth = -1; int mThumbnailHeight = -1; @@ -507,6 +517,31 @@ final class ActivityStack { return null; } + // TODO: This exposes mHistory too much, replace usage with ActivityStack methods. + final ActivityRecord getActivityAtIndex(int index) { + if (index >= 0 && index < mHistory.size()) { + return mHistory.get(index); + } + return null; + } + + int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { + TaskRecord lastTask = null; + final int N = mHistory.size(); + for (int i = 0; i < N; i++) { + ActivityRecord r = mHistory.get(i); + if (r.appToken == token) { + if (!onlyRoot || lastTask != r.task) { + return r.task.taskId; + } + return -1; + } + lastTask = r.task; + } + + return -1; + } + private final boolean updateLRUListLocked(ActivityRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); @@ -3589,9 +3624,9 @@ final class ActivityStack { finishes = new ArrayList(mFinishingActivities); mFinishingActivities.clear(); } - if ((NT=mService.mCancelledThumbnails.size()) > 0) { - thumbnails = new ArrayList(mService.mCancelledThumbnails); - mService.mCancelledThumbnails.clear(); + if ((NT=mCancelledThumbnails.size()) > 0) { + thumbnails = new ArrayList(mCancelledThumbnails); + mCancelledThumbnails.clear(); } if (mMainStack) { @@ -3814,7 +3849,7 @@ final class ActivityStack { // There are clients waiting to receive thumbnails so, in case // this is an activity that someone is waiting for, add it // to the pending list so we can correctly update the clients. - mService.mCancelledThumbnails.add(r); + mCancelledThumbnails.add(r); } if (immediate) { @@ -3974,7 +4009,7 @@ final class ActivityStack { // There are clients waiting to receive thumbnails so, in case // this is an activity that someone is waiting for, add it // to the pending list so we can correctly update the clients. - mService.mCancelledThumbnails.add(r); + mCancelledThumbnails.add(r); } // Get rid of any pending idle timeouts. @@ -4322,6 +4357,25 @@ final class ActivityStack { mService.mWindowManager.prepareAppTransition(transit, false); } + final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) { + for (int i = mHistory.size() - 1; i >= 0; i--) { + ActivityRecord hr = mHistory.get(i); + if (hr.task.taskId == taskId) { + if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) { + mUserLeaving = true; + } + if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { + // Caller wants the home activity moved with it. To accomplish this, + // we'll just move the home task to the top first. + moveHomeToFrontLocked(); + } + moveTaskToFrontLocked(hr.task, null, options); + return true; + } + } + return false; + } + final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) { if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr); @@ -4787,4 +4841,204 @@ final class ActivityStack { public void dismissKeyguardOnNextActivityLocked() { mDismissKeyguardOnNextActivity = true; } + + boolean willActivityBeVisibleLocked(IBinder token) { + int i; + for (i = mHistory.size() - 1; i >= 0; i--) { + ActivityRecord r = mHistory.get(i); + if (r.appToken == token) { + return true; + } + if (r.fullscreen && !r.finishing) { + return false; + } + } + return true; + } + + void closeSystemDialogsLocked() { + for (int i = mHistory.size() - 1; i >= 0; i--) { + ActivityRecord r = mHistory.get(i); + if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) { + r.stack.finishActivityLocked(r, i, + Activity.RESULT_CANCELED, null, "close-sys", true); + } + } + } + + boolean forceStopPackageLocked(String name, boolean doit, boolean evenPersistent, int userId) { + boolean didSomething = false; + TaskRecord lastTask = null; + final int N = mHistory.size(); + for (int i = 0; i < N; i++) { + ActivityRecord r = mHistory.get(i); + final boolean samePackage = r.packageName.equals(name) + || (name == null && r.userId == userId); + if ((userId == UserHandle.USER_ALL || r.userId == userId) + && (samePackage || r.task == lastTask) + && (r.app == null || evenPersistent || !r.app.persistent)) { + if (!doit) { + if (r.finishing) { + // If this activity is just finishing, then it is not + // interesting as far as something to stop. + continue; + } + return true; + } + didSomething = true; + Slog.i(TAG, " Force finishing activity " + r); + if (samePackage) { + if (r.app != null) { + r.app.removed = true; + } + r.app = null; + } + lastTask = r.task; + if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, + null, "force-stop", true)) { + i--; + } + } + } + return didSomething; + } + + ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver, + PendingThumbnailsRecord pending, List list) { + ActivityRecord topRecord = null; + int pos = mHistory.size() - 1; + ActivityRecord next = pos >= 0 ? mHistory.get(pos) : null; + ActivityRecord top = null; + TaskRecord curTask = null; + int numActivities = 0; + int numRunning = 0; + while (pos >= 0 && maxNum > 0) { + final ActivityRecord r = next; + pos--; + next = pos >= 0 ? mHistory.get(pos) : null; + + // Initialize state for next task if needed. + if (top == null || (top.state == ActivityState.INITIALIZING && top.task == r.task)) { + top = r; + curTask = r.task; + numActivities = numRunning = 0; + } + + // Add 'r' into the current task. + numActivities++; + if (r.app != null && r.app.thread != null) { + numRunning++; + } + + if (localLOGV) Slog.v( + TAG, r.intent.getComponent().flattenToShortString() + + ": task=" + r.task); + + // If the next one is a different task, generate a new + // TaskInfo entry for what we have. + if (next == null || next.task != curTask) { + RunningTaskInfo ci = new RunningTaskInfo(); + ci.id = curTask.taskId; + ci.baseActivity = r.intent.getComponent(); + ci.topActivity = top.intent.getComponent(); + if (top.thumbHolder != null) { + ci.description = top.thumbHolder.lastDescription; + } + ci.numActivities = numActivities; + ci.numRunning = numRunning; + //System.out.println( + // "#" + maxNum + ": " + " descr=" + ci.description); + if (receiver != null) { + if (localLOGV) Slog.v( + TAG, "State=" + top.state + "Idle=" + top.idle + + " app=" + top.app + + " thr=" + (top.app != null ? top.app.thread : null)); + if (top.state == ActivityState.RESUMED || top.state == ActivityState.PAUSING) { + if (top.idle && top.app != null && top.app.thread != null) { + topRecord = top; + } else { + top.thumbnailNeeded = true; + } + } + pending.pendingRecords.add(top); + } + list.add(ci); + maxNum--; + top = null; + } + } + return topRecord; + } + + public void unhandledBackLocked() { + int top = mHistory.size() - 1; + if (DEBUG_SWITCH) Slog.d( + TAG, "Performing unhandledBack(): top activity at " + top); + if (top > 0) { + finishActivityLocked(mHistory.get(top), + top, Activity.RESULT_CANCELED, null, "unhandled-back", true); + } + } + + void handleAppCrashLocked(ProcessRecord app) { + for (int i = mHistory.size() - 1; i >= 0; i--) { + ActivityRecord r = mHistory.get(i); + if (r.app == app) { + Slog.w(TAG, " Force finishing activity " + + r.intent.getComponent().flattenToShortString()); + r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, + null, "crashed", false); + } + } + } + + void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, boolean dumpAll, + boolean dumpClient, String dumpPackage) { + ActivityManagerService.dumpHistoryList(fd, pw, mHistory, " ", "Hist", true, !dumpAll, + dumpClient, dumpPackage); + } + + ArrayList getDumpActivitiesLocked(String name) { + ArrayList activities = new ArrayList(); + + if ("all".equals(name)) { + for (ActivityRecord r1 : mHistory) { + activities.add(r1); + } + } else if ("top".equals(name)) { + final int N = mHistory.size(); + if (N > 0) { + activities.add(mHistory.get(N-1)); + } + } else { + ItemMatcher matcher = new ItemMatcher(); + matcher.build(name); + + for (ActivityRecord r1 : mHistory) { + if (matcher.match(r1, r1.intent.getComponent())) { + activities.add(r1); + } + } + } + + return activities; + } + + ActivityRecord restartPackage(String packageName) { + ActivityRecord starting = topRunningActivityLocked(null); + + // All activities that came from the package must be + // restarted as if there was a config change. + for (int i = mHistory.size() - 1; i >= 0; i--) { + ActivityRecord a = mHistory.get(i); + if (a.info.packageName.equals(packageName)) { + a.forceNewConfig = true; + if (starting != null && a == starting && a.visible) { + a.startFreezingScreenLocked(starting.app, ActivityInfo.CONFIG_SCREEN_LAYOUT); + } + } + } + + return starting; + } } diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index 3a6492e2957b1..863bdad421777 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -295,20 +295,8 @@ public class CompatModePackages { Message msg = mHandler.obtainMessage(MSG_WRITE); mHandler.sendMessageDelayed(msg, 10000); - ActivityRecord starting = mService.mMainStack.topRunningActivityLocked(null); - - // All activities that came from the package must be - // restarted as if there was a config change. - for (int i=mService.mMainStack.mHistory.size()-1; i>=0; i--) { - ActivityRecord a = (ActivityRecord)mService.mMainStack.mHistory.get(i); - if (a.info.packageName.equals(packageName)) { - a.forceNewConfig = true; - if (starting != null && a == starting && a.visible) { - a.startFreezingScreenLocked(starting.app, - ActivityInfo.CONFIG_SCREEN_LAYOUT); - } - } - } + + ActivityRecord starting = mService.mMainStack.restartPackage(packageName); // Tell all processes that loaded this package about the change. for (int i=mService.mLruProcesses.size()-1; i>=0; i--) { diff --git a/services/java/com/android/server/am/PendingThumbnailsRecord.java b/services/java/com/android/server/am/PendingThumbnailsRecord.java index ed478c9741c8b..c4607916bb394 100644 --- a/services/java/com/android/server/am/PendingThumbnailsRecord.java +++ b/services/java/com/android/server/am/PendingThumbnailsRecord.java @@ -27,13 +27,13 @@ import java.util.HashSet; class PendingThumbnailsRecord { final IThumbnailReceiver receiver; // who is waiting. - HashSet pendingRecords; // HistoryRecord objects we still wait for. + final HashSet pendingRecords; // HistoryRecord objects we still wait for. boolean finished; // Is pendingRecords empty? PendingThumbnailsRecord(IThumbnailReceiver _receiver) { receiver = _receiver; - pendingRecords = new HashSet(); + pendingRecords = new HashSet(); finished = false; } }