Loading core/java/android/view/IWindowManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ interface IWindowManager void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); void moveAppToken(int index, IBinder token); void moveAppTokensToTop(in List<IBinder> tokens); void moveAppTokensToBottom(in List<IBinder> tokens); // Re-evaluate the current orientation from the caller's state. // If there is a change, the new Configuration is returned and the Loading services/java/com/android/server/am/ActivityManagerService.java +365 −42 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ 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; Loading Loading @@ -197,7 +196,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; static final boolean DEBUG_MU = localLOGV || false; static final boolean DEBUG_IMMERSIVE = localLOGV || false; static final boolean VALIDATE_TOKENS = true; static final boolean VALIDATE_TOKENS = false; static final boolean SHOW_ACTIVITY_START_TIME = true; // Control over CPU and battery monitoring. Loading Loading @@ -329,7 +328,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * List of intents that were used to start the most recent tasks. */ private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); public class PendingActivityExtras extends Binder implements Runnable { public final ActivityRecord activity; Loading Loading @@ -597,8 +596,13 @@ 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<PendingThumbnailsRecord> mPendingThumbnails = new ArrayList<PendingThumbnailsRecord>(); 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 ProviderMap mProviderMap; Loading Loading @@ -2838,10 +2842,13 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<activities.size(); i++) { ActivityRecord r = activities.get(i); if (!r.finishing) { mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED, int index = mMainStack.indexOfTokenLocked(r.appToken); if (index >= 0) { mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "finish-heavy", true); } } } mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); Loading Loading @@ -2925,10 +2932,19 @@ public final class ActivityManagerService extends ActivityManagerNative } } @Override public boolean willActivityBeVisible(IBinder token) { synchronized(this) { return mMainStack.willActivityBeVisibleLocked(token); 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; } } Loading Loading @@ -3701,7 +3717,13 @@ public final class ActivityManagerService extends ActivityManagerNative } mWindowManager.closeSystemDialogs(reason); mMainStack.closeSystemDialogsLocked(); 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); } } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, Loading Loading @@ -3909,11 +3931,36 @@ public final class ActivityManagerService extends ActivityManagerNative -100, callerWillRestart, true, doit, evenPersistent, name == null ? ("force stop user " + userId) : ("force stop " + name)); if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { TaskRecord lastTask = null; for (i=0; i<mMainStack.mHistory.size(); i++) { ActivityRecord r = (ActivityRecord)mMainStack.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--; } } } if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { Loading Loading @@ -5623,12 +5670,12 @@ public final class ActivityManagerService extends ActivityManagerNative // TASK MANAGEMENT // ========================================================= @Override public List<RunningTaskInfo> getTasks(int maxNum, int flags, public List getTasks(int maxNum, int flags, IThumbnailReceiver receiver) { ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); ArrayList list = new ArrayList(); PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); PendingThumbnailsRecord pending = null; IApplicationThread topThumbnail = null; ActivityRecord topRecord = null; synchronized(this) { Loading @@ -5654,19 +5701,88 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list); 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; // 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 (!pending.pendingRecords.isEmpty()) { 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) { mPendingThumbnails.add(pending); } } if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); if (topRecord != null) { if (topThumbnail != 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); Loading Loading @@ -5901,6 +6017,43 @@ 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<N; j++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); if (r.task != jt) { if (affinity.equals(jt.affinity)) { return j; } jt = r.task; } } // Might it be at the top? if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { return N-1; } return -1; } /** * TODO: Add mController hook */ Loading Loading @@ -5929,9 +6082,21 @@ public final class ActivityManagerService extends ActivityManagerNative mMainStack.moveTaskToFrontLocked(tr, null, options); return; } if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) { for (int i=mMainStack.mHistory.size()-1; i>=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; } } } finally { Binder.restoreCallingIdentity(origId); } Loading Loading @@ -5970,7 +6135,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("moveActivityTaskToBack"); synchronized(this) { final long origId = Binder.clearCallingIdentity(); int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot); int taskId = getTaskForActivityLocked(token, !nonRoot); if (taskId >= 0) { return mMainStack.moveTaskToBackLocked(taskId, null); } Loading Loading @@ -6000,10 +6165,27 @@ public final class ActivityManagerService extends ActivityManagerNative public int getTaskForActivity(IBinder token, boolean onlyRoot) { synchronized(this) { return mMainStack.getTaskForActivityLocked(token, onlyRoot); return getTaskForActivityLocked(token, onlyRoot); } } int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { final int N = mMainStack.mHistory.size(); TaskRecord lastTask = null; for (int i=0; i<N; i++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); if (r.appToken == token) { if (!onlyRoot || lastTask != r.task) { return r.task.taskId; } return -1; } lastTask = r.task; } return -1; } // ========================================================= // THUMBNAILS // ========================================================= Loading Loading @@ -6909,10 +7091,13 @@ public final class ActivityManagerService extends ActivityManagerNative "unhandledBack()"); synchronized(this) { int count = mMainStack.mHistory.size(); if (DEBUG_SWITCH) Slog.d( TAG, "Performing unhandledBack(): stack size = " + count); if (count > 1) { final long origId = Binder.clearCallingIdentity(); try { mMainStack.unhandledBackLocked(); } finally { mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); Binder.restoreCallingIdentity(origId); } } Loading Loading @@ -7974,7 +8159,15 @@ public final class ActivityManagerService extends ActivityManagerNative + " has crashed too many times: killing!"); EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, app.userId, app.info.processName, app.uid); mMainStack.handleAppCrashLocked(app); for (int i=mMainStack.mHistory.size()-1; 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); } } if (!app.persistent) { // We don't want to start this process again until the user // explicitly does so... but for persistent process, we really Loading @@ -7999,7 +8192,33 @@ public final class ActivityManagerService extends ActivityManagerNative } mMainStack.resumeTopActivityLocked(null); } else { mMainStack.finishTopRunningActivityLocked(app); ActivityRecord r = mMainStack.topRunningActivityLocked(null); if (r != null && r.app == app) { // If the top running activity is from this crashing // process, then terminate it to avoid getting in a loop. Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); int index = mMainStack.indexOfActivityLocked(r); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); // Also terminate any activities below it that aren't yet // stopped, to avoid a situation where one will get // re-start our crashing activity once it gets resumed again. index--; if (index >= 0) { r = (ActivityRecord)mMainStack.mHistory.get(index); if (r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { if (!r.isHomeActivity || mHomeProcess != r.app) { Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); } } } } } // Bump up the crash count of any services currently running in the proc. Loading Loading @@ -9018,7 +9237,8 @@ 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:"); mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, dumpPackage); pw.println(" "); pw.println(" Running activities (most recent first):"); dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, Loading Loading @@ -9548,10 +9768,32 @@ public final class ActivityManagerService extends ActivityManagerNative */ protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { ArrayList<ActivityRecord> activities; ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); if ("all".equals(name)) { synchronized (this) { for (ActivityRecord r1 : (ArrayList<ActivityRecord>)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) { activities = mMainStack.getDumpActivitiesLocked(name); for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { if (matcher.match(r1, r1.intent.getComponent())) { activities.add(r1); } } } } if (activities.size() <= 0) { Loading Loading @@ -9803,7 +10045,7 @@ public final class ActivityManagerService extends ActivityManagerNative return needSep; } static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, private 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; Loading Loading @@ -12341,14 +12583,95 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData) { ComponentName dest = destIntent.getComponent(); synchronized (this) { ActivityRecord srec = ActivityRecord.forToken(token); if (srec == null) { return false; } ActivityStack stack = srec.stack; return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData); ArrayList<ActivityRecord> history = srec.stack.mHistory; final int start = history.indexOf(srec); if (start < 0) { // Current activity is not in history stack; do nothing. return false; } int finishTo = start - 1; ActivityRecord parent = null; boolean foundParentInTask = false; if (dest != null) { TaskRecord tr = srec.task; for (int i = start - 1; i >= 0; i--) { ActivityRecord r = history.get(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); break; } else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) { finishTo = i; parent = r; foundParentInTask = true; break; } } } if (mController != null) { ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { resumeOK = mController.activityResuming(next.packageName); } catch (RemoteException e) { mController = null; } if (!resumeOK) { return false; } } } final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { ActivityRecord r = history.get(i); mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true); // Only return the supplied result for the first activity finished resultCode = Activity.RESULT_CANCELED; resultData = null; } if (parent != null && foundParentInTask) { final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( destIntent.getComponent(), 0, srec.userId); int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, null, aInfo, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, 0, null, true, null); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { foundParentInTask = false; } mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, resultData, "navigate-up", true); } } Binder.restoreCallingIdentity(origId); return foundParentInTask; } } Loading
core/java/android/view/IWindowManager.aidl +3 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,9 @@ interface IWindowManager void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); void moveAppToken(int index, IBinder token); void moveAppTokensToTop(in List<IBinder> tokens); void moveAppTokensToBottom(in List<IBinder> tokens); // Re-evaluate the current orientation from the caller's state. // If there is a change, the new Configuration is returned and the Loading
services/java/com/android/server/am/ActivityManagerService.java +365 −42 Original line number Diff line number Diff line Loading @@ -37,7 +37,6 @@ 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; Loading Loading @@ -197,7 +196,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; static final boolean DEBUG_MU = localLOGV || false; static final boolean DEBUG_IMMERSIVE = localLOGV || false; static final boolean VALIDATE_TOKENS = true; static final boolean VALIDATE_TOKENS = false; static final boolean SHOW_ACTIVITY_START_TIME = true; // Control over CPU and battery monitoring. Loading Loading @@ -329,7 +328,7 @@ public final class ActivityManagerService extends ActivityManagerNative /** * List of intents that were used to start the most recent tasks. */ private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); public class PendingActivityExtras extends Binder implements Runnable { public final ActivityRecord activity; Loading Loading @@ -597,8 +596,13 @@ 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<PendingThumbnailsRecord> mPendingThumbnails = new ArrayList<PendingThumbnailsRecord>(); 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 ProviderMap mProviderMap; Loading Loading @@ -2838,10 +2842,13 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<activities.size(); i++) { ActivityRecord r = activities.get(i); if (!r.finishing) { mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED, int index = mMainStack.indexOfTokenLocked(r.appToken); if (index >= 0) { mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "finish-heavy", true); } } } mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); Loading Loading @@ -2925,10 +2932,19 @@ public final class ActivityManagerService extends ActivityManagerNative } } @Override public boolean willActivityBeVisible(IBinder token) { synchronized(this) { return mMainStack.willActivityBeVisibleLocked(token); 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; } } Loading Loading @@ -3701,7 +3717,13 @@ public final class ActivityManagerService extends ActivityManagerNative } mWindowManager.closeSystemDialogs(reason); mMainStack.closeSystemDialogsLocked(); 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); } } broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, Loading Loading @@ -3909,11 +3931,36 @@ public final class ActivityManagerService extends ActivityManagerNative -100, callerWillRestart, true, doit, evenPersistent, name == null ? ("force stop user " + userId) : ("force stop " + name)); if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { TaskRecord lastTask = null; for (i=0; i<mMainStack.mHistory.size(); i++) { ActivityRecord r = (ActivityRecord)mMainStack.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--; } } } if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { Loading Loading @@ -5623,12 +5670,12 @@ public final class ActivityManagerService extends ActivityManagerNative // TASK MANAGEMENT // ========================================================= @Override public List<RunningTaskInfo> getTasks(int maxNum, int flags, public List getTasks(int maxNum, int flags, IThumbnailReceiver receiver) { ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); ArrayList list = new ArrayList(); PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); PendingThumbnailsRecord pending = null; IApplicationThread topThumbnail = null; ActivityRecord topRecord = null; synchronized(this) { Loading @@ -5654,19 +5701,88 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list); 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; // 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 (!pending.pendingRecords.isEmpty()) { 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) { mPendingThumbnails.add(pending); } } if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); if (topRecord != null) { if (topThumbnail != 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); Loading Loading @@ -5901,6 +6017,43 @@ 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<N; j++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j); if (r.task != jt) { if (affinity.equals(jt.affinity)) { return j; } jt = r.task; } } // Might it be at the top? if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) { return N-1; } return -1; } /** * TODO: Add mController hook */ Loading Loading @@ -5929,9 +6082,21 @@ public final class ActivityManagerService extends ActivityManagerNative mMainStack.moveTaskToFrontLocked(tr, null, options); return; } if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) { for (int i=mMainStack.mHistory.size()-1; i>=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; } } } finally { Binder.restoreCallingIdentity(origId); } Loading Loading @@ -5970,7 +6135,7 @@ public final class ActivityManagerService extends ActivityManagerNative enforceNotIsolatedCaller("moveActivityTaskToBack"); synchronized(this) { final long origId = Binder.clearCallingIdentity(); int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot); int taskId = getTaskForActivityLocked(token, !nonRoot); if (taskId >= 0) { return mMainStack.moveTaskToBackLocked(taskId, null); } Loading Loading @@ -6000,10 +6165,27 @@ public final class ActivityManagerService extends ActivityManagerNative public int getTaskForActivity(IBinder token, boolean onlyRoot) { synchronized(this) { return mMainStack.getTaskForActivityLocked(token, onlyRoot); return getTaskForActivityLocked(token, onlyRoot); } } int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { final int N = mMainStack.mHistory.size(); TaskRecord lastTask = null; for (int i=0; i<N; i++) { ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i); if (r.appToken == token) { if (!onlyRoot || lastTask != r.task) { return r.task.taskId; } return -1; } lastTask = r.task; } return -1; } // ========================================================= // THUMBNAILS // ========================================================= Loading Loading @@ -6909,10 +7091,13 @@ public final class ActivityManagerService extends ActivityManagerNative "unhandledBack()"); synchronized(this) { int count = mMainStack.mHistory.size(); if (DEBUG_SWITCH) Slog.d( TAG, "Performing unhandledBack(): stack size = " + count); if (count > 1) { final long origId = Binder.clearCallingIdentity(); try { mMainStack.unhandledBackLocked(); } finally { mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1), count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true); Binder.restoreCallingIdentity(origId); } } Loading Loading @@ -7974,7 +8159,15 @@ public final class ActivityManagerService extends ActivityManagerNative + " has crashed too many times: killing!"); EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, app.userId, app.info.processName, app.uid); mMainStack.handleAppCrashLocked(app); for (int i=mMainStack.mHistory.size()-1; 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); } } if (!app.persistent) { // We don't want to start this process again until the user // explicitly does so... but for persistent process, we really Loading @@ -7999,7 +8192,33 @@ public final class ActivityManagerService extends ActivityManagerNative } mMainStack.resumeTopActivityLocked(null); } else { mMainStack.finishTopRunningActivityLocked(app); ActivityRecord r = mMainStack.topRunningActivityLocked(null); if (r != null && r.app == app) { // If the top running activity is from this crashing // process, then terminate it to avoid getting in a loop. Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); int index = mMainStack.indexOfActivityLocked(r); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); // Also terminate any activities below it that aren't yet // stopped, to avoid a situation where one will get // re-start our crashing activity once it gets resumed again. index--; if (index >= 0) { r = (ActivityRecord)mMainStack.mHistory.get(index); if (r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { if (!r.isHomeActivity || mHomeProcess != r.app) { Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); } } } } } // Bump up the crash count of any services currently running in the proc. Loading Loading @@ -9018,7 +9237,8 @@ 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:"); mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage); dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient, dumpPackage); pw.println(" "); pw.println(" Running activities (most recent first):"); dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false, Loading Loading @@ -9548,10 +9768,32 @@ public final class ActivityManagerService extends ActivityManagerNative */ protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { ArrayList<ActivityRecord> activities; ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); if ("all".equals(name)) { synchronized (this) { for (ActivityRecord r1 : (ArrayList<ActivityRecord>)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) { activities = mMainStack.getDumpActivitiesLocked(name); for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) { if (matcher.match(r1, r1.intent.getComponent())) { activities.add(r1); } } } } if (activities.size() <= 0) { Loading Loading @@ -9803,7 +10045,7 @@ public final class ActivityManagerService extends ActivityManagerNative return needSep; } static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list, private 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; Loading Loading @@ -12341,14 +12583,95 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData) { ComponentName dest = destIntent.getComponent(); synchronized (this) { ActivityRecord srec = ActivityRecord.forToken(token); if (srec == null) { return false; } ActivityStack stack = srec.stack; return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData); ArrayList<ActivityRecord> history = srec.stack.mHistory; final int start = history.indexOf(srec); if (start < 0) { // Current activity is not in history stack; do nothing. return false; } int finishTo = start - 1; ActivityRecord parent = null; boolean foundParentInTask = false; if (dest != null) { TaskRecord tr = srec.task; for (int i = start - 1; i >= 0; i--) { ActivityRecord r = history.get(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); break; } else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) { finishTo = i; parent = r; foundParentInTask = true; break; } } } if (mController != null) { ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { resumeOK = mController.activityResuming(next.packageName); } catch (RemoteException e) { mController = null; } if (!resumeOK) { return false; } } } final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { ActivityRecord r = history.get(i); mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true); // Only return the supplied result for the first activity finished resultCode = Activity.RESULT_CANCELED; resultData = null; } if (parent != null && foundParentInTask) { final int parentLaunchMode = parent.info.launchMode; final int destIntentFlags = destIntent.getFlags(); if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK || parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP || (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) { parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent); } else { try { ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo( destIntent.getComponent(), 0, srec.userId); int res = mMainStack.startActivityLocked(srec.app.thread, destIntent, null, aInfo, parent.appToken, null, 0, -1, parent.launchedFromUid, parent.launchedFromPackage, 0, null, true, null); foundParentInTask = res == ActivityManager.START_SUCCESS; } catch (RemoteException e) { foundParentInTask = false; } mMainStack.requestFinishActivityLocked(parent.appToken, resultCode, resultData, "navigate-up", true); } } Binder.restoreCallingIdentity(origId); return foundParentInTask; } }