Loading services/java/com/android/server/am/ActivityManagerService.java +4 −114 Original line number Diff line number Diff line Loading @@ -2838,13 +2838,10 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<activities.size(); i++) { ActivityRecord r = activities.get(i); if (!r.finishing) { int index = mMainStack.indexOfTokenLocked(r.appToken); if (index >= 0) { mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-heavy", true); } } } mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); Loading Loading @@ -8002,33 +7999,7 @@ public final class ActivityManagerService extends ActivityManagerNative } mMainStack.resumeTopActivityLocked(null); } else { 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 = mMainStack.getActivityAtIndex(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); } } } } mMainStack.finishTopRunningActivityLocked(app); } // Bump up the crash count of any services currently running in the proc. Loading Loading @@ -12370,7 +12341,6 @@ 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); Loading @@ -12378,87 +12348,7 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } ActivityStack stack = srec.stack; final int start = stack.indexOfActivityLocked(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 = 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 = stack.getActivityAtIndex(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 = stack.getActivityAtIndex(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; return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData); } } Loading services/java/com/android/server/am/ActivityRecord.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.server.am.ActivityStack.ActivityState; import android.app.Activity; import android.app.ActivityOptions; import android.app.ResultInfo; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; Loading Loading @@ -95,9 +96,9 @@ final class ActivityRecord { ActivityRecord resultTo; // who started this entry, so will get our reply final String resultWho; // additional identifier for use by resultTo. final int requestCode; // code given by requester (resultTo) ArrayList results; // pending ActivityResult objs we have received ArrayList<ResultInfo> results; // pending ActivityResult objs we have received HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act ArrayList newIntents; // any pending new intents for single-top mode ArrayList<Intent> newIntents; // any pending new intents for single-top mode ActivityOptions pendingOptions; // most recently given options HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. Loading services/java/com/android/server/am/ActivityStack.java +165 −35 Original line number Diff line number Diff line Loading @@ -24,11 +24,13 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.wm.AppTransition; import com.android.server.wm.TaskGroup; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IThumbnailReceiver; import android.app.IThumbnailRetriever; Loading Loading @@ -501,14 +503,10 @@ final class ActivityStack { return null; } final int indexOfTokenLocked(IBinder token) { private final int indexOfTokenLocked(IBinder token) { return mHistory.indexOf(ActivityRecord.forToken(token)); } final int indexOfActivityLocked(ActivityRecord r) { return mHistory.indexOf(r); } final ActivityRecord isInStackLocked(IBinder token) { ActivityRecord r = ActivityRecord.forToken(token); if (mHistory.contains(r)) { Loading @@ -517,14 +515,6 @@ 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(); Loading Loading @@ -745,9 +735,15 @@ final class ActivityStack { try { profileFd = profileFd.dup(); } catch (IOException e) { if (profileFd != null) { try { profileFd.close(); } catch (IOException o) { } profileFd = null; } } } app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), Loading Loading @@ -1758,7 +1754,7 @@ final class ActivityStack { try { // Deliver all pending results. ArrayList a = next.results; ArrayList<ResultInfo> a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { Loading Loading @@ -2156,6 +2152,7 @@ final class ActivityStack { } i++; } mService.mWindowManager.moveTaskToBottom(target.task.taskId); if (taskTop == p) { taskTop = below; } Loading Loading @@ -2304,6 +2301,8 @@ final class ActivityStack { validateAppTokensLocked(); } } // TODO: This is wrong because it doesn't take lastReparentPos into account. mService.mWindowManager.moveTaskToTop(task.taskId); replyChainEnd = -1; // Now we've moved it in to place... but what if this is Loading Loading @@ -2413,7 +2412,7 @@ final class ActivityStack { if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { if (!ret.finishing) { int index = indexOfTokenLocked(ret.appToken); int index = mHistory.indexOf(ret); if (index >= 0) { finishActivityLocked(ret, index, Activity.RESULT_CANCELED, null, "clear", false); Loading Loading @@ -3568,7 +3567,7 @@ final class ActivityStack { } // Get the activity record. int index = indexOfActivityLocked(r); int index = mHistory.indexOf(r); if (index >= 0) { res = r; Loading Loading @@ -3654,7 +3653,7 @@ final class ActivityStack { // Stop any activities that are scheduled to do so but have been // waiting for the next one to start. for (i=0; i<NS; i++) { ActivityRecord r = (ActivityRecord)stops.get(i); ActivityRecord r = stops.get(i); synchronized (mService) { if (r.finishing) { finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); Loading @@ -3667,7 +3666,7 @@ final class ActivityStack { // Finish any activities that are scheduled to do so but have been // waiting for the next one to start. for (i=0; i<NF; i++) { ActivityRecord r = (ActivityRecord)finishes.get(i); ActivityRecord r = finishes.get(i); synchronized (mService) { activityRemoved = destroyActivityLocked(r, true, false, "finish-idle"); } Loading @@ -3675,7 +3674,7 @@ final class ActivityStack { // Report back to any thumbnail receivers. for (i=0; i<NT; i++) { ActivityRecord r = (ActivityRecord)thumbnails.get(i); ActivityRecord r = thumbnails.get(i); mService.sendPendingThumbnail(r, null, null, null, true); } Loading Loading @@ -3730,7 +3729,7 @@ final class ActivityStack { int i; for (i=mHistory.size()-1; i>=0; i--) { ActivityRecord r = (ActivityRecord)mHistory.get(i); ActivityRecord r = mHistory.get(i); if (r.resultTo == self && r.requestCode == requestCode) { if ((r.resultWho == null && resultWho == null) || (r.resultWho != null && r.resultWho.equals(resultWho))) { Loading @@ -3742,6 +3741,36 @@ final class ActivityStack { mService.updateOomAdjLocked(); } final void finishTopRunningActivityLocked(ProcessRecord app) { ActivityRecord r = 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 = mHistory.indexOf(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 = mHistory.get(index); if (r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { if (!r.isHomeActivity || mService.mHomeProcess != r.app) { Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); } } } } } final boolean finishActivityAffinityLocked(IBinder token) { int index = indexOfTokenLocked(token); if (DEBUG_RESULTS) Slog.v( Loading Loading @@ -3796,6 +3825,19 @@ final class ActivityStack { r.icicle = null; } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { int index = mHistory.indexOf(r); if (index >= 0) { return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj); } return false; } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. Loading Loading @@ -3892,7 +3934,7 @@ final class ActivityStack { private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) { final int index = indexOfActivityLocked(r); final int index = mHistory.indexOf(r); if (index < 0) { return null; } Loading Loading @@ -3948,16 +3990,102 @@ final class ActivityStack { resumeTopActivityLocked(null); } return activityRemoved ? null : r; } else { } // Need to go through the full pause cycle to get this // activity into the stopped state and then finish it. if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r); mFinishingActivities.add(r); resumeTopActivityLocked(null); } return r; } final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { final int start = mHistory.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; ComponentName dest = destIntent.getComponent(); if (dest != null) { TaskRecord tr = srec.task; for (int i = start - 1; i >= 0; i--) { ActivityRecord r = mHistory.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 = mHistory.get(finishTo); break; } else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) { finishTo = i; parent = r; foundParentInTask = true; break; } } } IActivityController controller = mService.mController; if (controller != null) { ActivityRecord next = topRunningActivityLocked(srec.appToken, 0); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { resumeOK = controller.activityResuming(next.packageName); } catch (RemoteException e) { mService.mController = null; } if (!resumeOK) { return false; } } } final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { ActivityRecord r = mHistory.get(i); 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 = 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; } requestFinishActivityLocked(parent.appToken, resultCode, resultData, "navigate-up", true); } } Binder.restoreCallingIdentity(origId); return foundParentInTask; } /** * Perform the common clean-up of an activity record. This is called both * as part of destroyActivityLocked() (when destroying the client-side Loading Loading @@ -4216,7 +4344,7 @@ final class ActivityStack { mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); } int index = indexOfActivityLocked(r); int index = mHistory.indexOf(r); if (index >= 0) { if (r.state == ActivityState.DESTROYING) { cleanUpActivityLocked(r, true, false); Loading @@ -4230,15 +4358,15 @@ final class ActivityStack { } } private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app, String listName) { private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list, ProcessRecord app, String listName) { int i = list.size(); if (DEBUG_CLEANUP) Slog.v( TAG, "Removing app " + app + " from list " + listName + " with " + i + " entries"); while (i > 0) { i--; ActivityRecord r = (ActivityRecord)list.get(i); ActivityRecord r = list.get(i); if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r); if (r.app == app) { if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!"); Loading @@ -4264,7 +4392,7 @@ final class ActivityStack { TAG, "Removing app " + app + " from history with " + i + " entries"); while (i > 0) { i--; ActivityRecord r = (ActivityRecord)mHistory.get(i); ActivityRecord r = mHistory.get(i); if (DEBUG_CLEANUP) Slog.v( TAG, "Record #" + i + " " + r + ": app=" + r.app); if (r.app == app) { Loading Loading @@ -4440,6 +4568,7 @@ final class ActivityStack { if (VALIDATE_TOKENS) { validateAppTokensLocked(); } mService.mWindowManager.moveTaskToTop(task); finishTaskMoveLocked(task); EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task); Loading Loading @@ -4532,6 +4661,7 @@ final class ActivityStack { if (VALIDATE_TOKENS) { validateAppTokensLocked(); } mService.mWindowManager.moveTaskToBottom(task); finishTaskMoveLocked(task); return true; Loading Loading @@ -4561,9 +4691,8 @@ final class ActivityStack { TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true); if (info.numSubThumbbails <= 0) { return info.mainThumbnail != null ? info.mainThumbnail : tr.lastThumbnail; } else { return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail; } return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail; } public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex, Loading Loading @@ -4643,6 +4772,7 @@ final class ActivityStack { } if (thumbs.numSubThumbbails > 0) { thumbs.retriever = new IThumbnailRetriever.Stub() { @Override public Bitmap getThumbnail(int index) { if (index < 0 || index >= thumbs.subtasks.size()) { return null; Loading services/java/com/android/server/wm/DisplayContent.java +135 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes services/java/com/android/server/am/TaskGroup.java→services/java/com/android/server/wm/TaskGroup.java +1 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ package com.android.server.am; package com.android.server.wm; import android.view.IApplicationToken; Loading Loading
services/java/com/android/server/am/ActivityManagerService.java +4 −114 Original line number Diff line number Diff line Loading @@ -2838,13 +2838,10 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<activities.size(); i++) { ActivityRecord r = activities.get(i); if (!r.finishing) { int index = mMainStack.indexOfTokenLocked(r.appToken); if (index >= 0) { mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-heavy", true); } } } mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, mHeavyWeightProcess.userId, 0)); Loading Loading @@ -8002,33 +7999,7 @@ public final class ActivityManagerService extends ActivityManagerNative } mMainStack.resumeTopActivityLocked(null); } else { 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 = mMainStack.getActivityAtIndex(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); } } } } mMainStack.finishTopRunningActivityLocked(app); } // Bump up the crash count of any services currently running in the proc. Loading Loading @@ -12370,7 +12341,6 @@ 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); Loading @@ -12378,87 +12348,7 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } ActivityStack stack = srec.stack; final int start = stack.indexOfActivityLocked(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 = 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 = stack.getActivityAtIndex(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 = stack.getActivityAtIndex(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; return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData); } } Loading
services/java/com/android/server/am/ActivityRecord.java +3 −2 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.server.am.ActivityStack.ActivityState; import android.app.Activity; import android.app.ActivityOptions; import android.app.ResultInfo; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; Loading Loading @@ -95,9 +96,9 @@ final class ActivityRecord { ActivityRecord resultTo; // who started this entry, so will get our reply final String resultWho; // additional identifier for use by resultTo. final int requestCode; // code given by requester (resultTo) ArrayList results; // pending ActivityResult objs we have received ArrayList<ResultInfo> results; // pending ActivityResult objs we have received HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act ArrayList newIntents; // any pending new intents for single-top mode ArrayList<Intent> newIntents; // any pending new intents for single-top mode ActivityOptions pendingOptions; // most recently given options HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. Loading
services/java/com/android/server/am/ActivityStack.java +165 −35 Original line number Diff line number Diff line Loading @@ -24,11 +24,13 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.am.ActivityManagerService.PendingActivityLaunch; import com.android.server.wm.AppTransition; import com.android.server.wm.TaskGroup; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.AppGlobals; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IThumbnailReceiver; import android.app.IThumbnailRetriever; Loading Loading @@ -501,14 +503,10 @@ final class ActivityStack { return null; } final int indexOfTokenLocked(IBinder token) { private final int indexOfTokenLocked(IBinder token) { return mHistory.indexOf(ActivityRecord.forToken(token)); } final int indexOfActivityLocked(ActivityRecord r) { return mHistory.indexOf(r); } final ActivityRecord isInStackLocked(IBinder token) { ActivityRecord r = ActivityRecord.forToken(token); if (mHistory.contains(r)) { Loading @@ -517,14 +515,6 @@ 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(); Loading Loading @@ -745,9 +735,15 @@ final class ActivityStack { try { profileFd = profileFd.dup(); } catch (IOException e) { if (profileFd != null) { try { profileFd.close(); } catch (IOException o) { } profileFd = null; } } } app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), Loading Loading @@ -1758,7 +1754,7 @@ final class ActivityStack { try { // Deliver all pending results. ArrayList a = next.results; ArrayList<ResultInfo> a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { Loading Loading @@ -2156,6 +2152,7 @@ final class ActivityStack { } i++; } mService.mWindowManager.moveTaskToBottom(target.task.taskId); if (taskTop == p) { taskTop = below; } Loading Loading @@ -2304,6 +2301,8 @@ final class ActivityStack { validateAppTokensLocked(); } } // TODO: This is wrong because it doesn't take lastReparentPos into account. mService.mWindowManager.moveTaskToTop(task.taskId); replyChainEnd = -1; // Now we've moved it in to place... but what if this is Loading Loading @@ -2413,7 +2412,7 @@ final class ActivityStack { if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { if (!ret.finishing) { int index = indexOfTokenLocked(ret.appToken); int index = mHistory.indexOf(ret); if (index >= 0) { finishActivityLocked(ret, index, Activity.RESULT_CANCELED, null, "clear", false); Loading Loading @@ -3568,7 +3567,7 @@ final class ActivityStack { } // Get the activity record. int index = indexOfActivityLocked(r); int index = mHistory.indexOf(r); if (index >= 0) { res = r; Loading Loading @@ -3654,7 +3653,7 @@ final class ActivityStack { // Stop any activities that are scheduled to do so but have been // waiting for the next one to start. for (i=0; i<NS; i++) { ActivityRecord r = (ActivityRecord)stops.get(i); ActivityRecord r = stops.get(i); synchronized (mService) { if (r.finishing) { finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); Loading @@ -3667,7 +3666,7 @@ final class ActivityStack { // Finish any activities that are scheduled to do so but have been // waiting for the next one to start. for (i=0; i<NF; i++) { ActivityRecord r = (ActivityRecord)finishes.get(i); ActivityRecord r = finishes.get(i); synchronized (mService) { activityRemoved = destroyActivityLocked(r, true, false, "finish-idle"); } Loading @@ -3675,7 +3674,7 @@ final class ActivityStack { // Report back to any thumbnail receivers. for (i=0; i<NT; i++) { ActivityRecord r = (ActivityRecord)thumbnails.get(i); ActivityRecord r = thumbnails.get(i); mService.sendPendingThumbnail(r, null, null, null, true); } Loading Loading @@ -3730,7 +3729,7 @@ final class ActivityStack { int i; for (i=mHistory.size()-1; i>=0; i--) { ActivityRecord r = (ActivityRecord)mHistory.get(i); ActivityRecord r = mHistory.get(i); if (r.resultTo == self && r.requestCode == requestCode) { if ((r.resultWho == null && resultWho == null) || (r.resultWho != null && r.resultWho.equals(resultWho))) { Loading @@ -3742,6 +3741,36 @@ final class ActivityStack { mService.updateOomAdjLocked(); } final void finishTopRunningActivityLocked(ProcessRecord app) { ActivityRecord r = 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 = mHistory.indexOf(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 = mHistory.get(index); if (r.state == ActivityState.RESUMED || r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { if (!r.isHomeActivity || mService.mHomeProcess != r.app) { Slog.w(TAG, " Force finishing activity " + r.intent.getComponent().flattenToShortString()); r.stack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, null, "crashed", false); } } } } } final boolean finishActivityAffinityLocked(IBinder token) { int index = indexOfTokenLocked(token); if (DEBUG_RESULTS) Slog.v( Loading Loading @@ -3796,6 +3825,19 @@ final class ActivityStack { r.icicle = null; } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. */ final boolean finishActivityLocked(ActivityRecord r, int resultCode, Intent resultData, String reason, boolean oomAdj) { int index = mHistory.indexOf(r); if (index >= 0) { return finishActivityLocked(r, index, resultCode, resultData, reason, false, oomAdj); } return false; } /** * @return Returns true if this activity has been removed from the history * list, or false if it is still in the list and will be removed later. Loading Loading @@ -3892,7 +3934,7 @@ final class ActivityStack { private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) { final int index = indexOfActivityLocked(r); final int index = mHistory.indexOf(r); if (index < 0) { return null; } Loading Loading @@ -3948,16 +3990,102 @@ final class ActivityStack { resumeTopActivityLocked(null); } return activityRemoved ? null : r; } else { } // Need to go through the full pause cycle to get this // activity into the stopped state and then finish it. if (localLOGV) Slog.v(TAG, "Enqueueing pending finish: " + r); mFinishingActivities.add(r); resumeTopActivityLocked(null); } return r; } final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode, Intent resultData) { final int start = mHistory.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; ComponentName dest = destIntent.getComponent(); if (dest != null) { TaskRecord tr = srec.task; for (int i = start - 1; i >= 0; i--) { ActivityRecord r = mHistory.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 = mHistory.get(finishTo); break; } else if (r.info.packageName.equals(dest.getPackageName()) && r.info.name.equals(dest.getClassName())) { finishTo = i; parent = r; foundParentInTask = true; break; } } } IActivityController controller = mService.mController; if (controller != null) { ActivityRecord next = topRunningActivityLocked(srec.appToken, 0); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { resumeOK = controller.activityResuming(next.packageName); } catch (RemoteException e) { mService.mController = null; } if (!resumeOK) { return false; } } } final long origId = Binder.clearCallingIdentity(); for (int i = start; i > finishTo; i--) { ActivityRecord r = mHistory.get(i); 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 = 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; } requestFinishActivityLocked(parent.appToken, resultCode, resultData, "navigate-up", true); } } Binder.restoreCallingIdentity(origId); return foundParentInTask; } /** * Perform the common clean-up of an activity record. This is called both * as part of destroyActivityLocked() (when destroying the client-side Loading Loading @@ -4216,7 +4344,7 @@ final class ActivityStack { mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); } int index = indexOfActivityLocked(r); int index = mHistory.indexOf(r); if (index >= 0) { if (r.state == ActivityState.DESTROYING) { cleanUpActivityLocked(r, true, false); Loading @@ -4230,15 +4358,15 @@ final class ActivityStack { } } private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app, String listName) { private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list, ProcessRecord app, String listName) { int i = list.size(); if (DEBUG_CLEANUP) Slog.v( TAG, "Removing app " + app + " from list " + listName + " with " + i + " entries"); while (i > 0) { i--; ActivityRecord r = (ActivityRecord)list.get(i); ActivityRecord r = list.get(i); if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r); if (r.app == app) { if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!"); Loading @@ -4264,7 +4392,7 @@ final class ActivityStack { TAG, "Removing app " + app + " from history with " + i + " entries"); while (i > 0) { i--; ActivityRecord r = (ActivityRecord)mHistory.get(i); ActivityRecord r = mHistory.get(i); if (DEBUG_CLEANUP) Slog.v( TAG, "Record #" + i + " " + r + ": app=" + r.app); if (r.app == app) { Loading Loading @@ -4440,6 +4568,7 @@ final class ActivityStack { if (VALIDATE_TOKENS) { validateAppTokensLocked(); } mService.mWindowManager.moveTaskToTop(task); finishTaskMoveLocked(task); EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task); Loading Loading @@ -4532,6 +4661,7 @@ final class ActivityStack { if (VALIDATE_TOKENS) { validateAppTokensLocked(); } mService.mWindowManager.moveTaskToBottom(task); finishTaskMoveLocked(task); return true; Loading Loading @@ -4561,9 +4691,8 @@ final class ActivityStack { TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true); if (info.numSubThumbbails <= 0) { return info.mainThumbnail != null ? info.mainThumbnail : tr.lastThumbnail; } else { return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail; } return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail; } public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex, Loading Loading @@ -4643,6 +4772,7 @@ final class ActivityStack { } if (thumbs.numSubThumbbails > 0) { thumbs.retriever = new IThumbnailRetriever.Stub() { @Override public Bitmap getThumbnail(int index) { if (index < 0 || index >= thumbs.subtasks.size()) { return null; Loading
services/java/com/android/server/wm/DisplayContent.java +135 −10 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/java/com/android/server/am/TaskGroup.java→services/java/com/android/server/wm/TaskGroup.java +1 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. */ package com.android.server.am; package com.android.server.wm; import android.view.IApplicationToken; Loading