From 2ad920759b1981eaf526fd37a314fbc5a3ed90ae Mon Sep 17 00:00:00 2001 From: Craig Mautner Date: Mon, 25 Feb 2013 16:19:24 -0800 Subject: [PATCH] Revert ActivityManager changes for tasks. DO NOT MERGE Keeping all activity=>task changes in master and removing them from jb-mr2. Revert "Update histories simultaneously." Revert "Add null check to setAppGroupId." Revert "Fix crashing bug in validator." Revert "Switch topRunning* and moveTaskTo*" Revert "Begin switch over to task based history." Revert "Reset and reuse Iterators and don't new() one." Revert "Remove AppWindowToken lists." Revert "Fix build." Revert "Remove unused App methods." Revert "Stop using AppToken movement and start using Task." Revert "Replace access to mAppTokens with AppTokenIterator" Revert "Refactor setAppOpVisibility implementation." Revert "Add AppWindowTokens to TaskList." Revert "Make ActivityStack.mHistory private." Revert "Migrate AppWindowToken lists into DisplayContent." Change-Id: I5722c9a4956dccb52864207e2967690bc58e4ebb --- core/java/android/view/IWindowManager.aidl | 3 + .../server/am/ActivityManagerService.java | 407 +++++++- .../com/android/server/am/ActivityRecord.java | 12 +- .../com/android/server/am/ActivityStack.java | 926 ++---------------- .../android/server/am/CompatModePackages.java | 16 +- .../server/am/PendingThumbnailsRecord.java | 4 +- .../com/android/server/am/TaskRecord.java | 74 +- .../com/android/server/wm/AppWindowToken.java | 4 - .../com/android/server/wm/DisplayContent.java | 214 +--- .../java/com/android/server/wm/TaskGroup.java | 31 - .../java/com/android/server/wm/TaskList.java | 35 - .../com/android/server/wm/WindowAnimator.java | 36 +- .../server/wm/WindowManagerService.java | 819 +++++++++------- .../com/android/server/wm/WindowState.java | 14 +- .../com/android/server/wm/WindowToken.java | 1 + .../tests/WindowManagerPermissionTests.java | 32 +- .../src/android/view/IWindowManagerImpl.java | 18 + 17 files changed, 1031 insertions(+), 1615 deletions(-) delete mode 100644 services/java/com/android/server/wm/TaskGroup.java delete mode 100644 services/java/com/android/server/wm/TaskList.java diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index e4ecb5c8063b5..f0c6241644d84 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -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 tokens); + void moveAppTokensToBottom(in List tokens); // Re-evaluate the current orientation from the caller's state. // If there is a change, the new Configuration is returned and the diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 22af3d5b33576..f226683ac14d5 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -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; @@ -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. @@ -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 mRecentTasks = new ArrayList(); + final ArrayList mRecentTasks = new ArrayList(); public class PendingActivityExtras extends Binder implements Runnable { public final ActivityRecord activity; @@ -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 mPendingThumbnails = - new ArrayList(); + 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; @@ -2838,8 +2842,11 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i= 0) { + mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED, + null, "finish-heavy", true); + } } } @@ -2925,13 +2932,22 @@ 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; } } - + public void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim) { synchronized(this) { @@ -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, @@ -3908,12 +3930,37 @@ 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)); - - if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) { - if (!doit) { - return true; + + TaskRecord lastTask = null; + for (i=0; i getTasks(int maxNum, int flags, + public List getTasks(int maxNum, int flags, IThumbnailReceiver receiver) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList(); - PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); + PendingThumbnailsRecord pending = null; + IApplicationThread topThumbnail = null; ActivityRecord topRecord = null; synchronized(this) { @@ -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; - if (!pending.pendingRecords.isEmpty()) { + // 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) { 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); @@ -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=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); @@ -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); } @@ -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=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 @@ -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. @@ -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, @@ -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 activities; - - synchronized (this) { - activities = mMainStack.getDumpActivitiesLocked(name); + 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); + } + } + } } if (activities.size() <= 0) { @@ -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; @@ -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 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; } } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index a2f337296deb7..cde17c9b39bae 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -22,7 +22,6 @@ 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; @@ -96,9 +95,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 results; // pending ActivityResult objs we have received HashSet> pendingResults; // all pending intents for this act - ArrayList newIntents; // any pending new intents for single-top mode + ArrayList newIntents; // any pending new intents for single-top mode ActivityOptions pendingOptions; // most recently given options HashSet connections; // All ConnectionRecord we hold UriPermissionOwner uriPermissions; // current special URI access perms. @@ -471,8 +470,6 @@ final class ActivityRecord { void setTask(TaskRecord newTask, ThumbnailHolder newThumbHolder, boolean isRoot) { if (inHistory && !finishing) { if (task != null) { - // TODO: If this is the last ActivityRecord in task, remove from ActivityStack. - task.removeActivity(this); task.numActivities--; } if (newTask != null) { @@ -507,7 +504,6 @@ final class ActivityRecord { inHistory = false; if (task != null && !finishing) { task.numActivities--; - task = null; } clearOptionsLocked(); } @@ -542,7 +538,7 @@ final class ActivityRecord { ActivityResult r = new ActivityResult(from, resultWho, requestCode, resultCode, resultData); if (results == null) { - results = new ArrayList(); + results = new ArrayList(); } results.add(r); } @@ -953,8 +949,6 @@ final class ActivityRecord { StringBuilder sb = new StringBuilder(128); sb.append("ActivityRecord{"); sb.append(Integer.toHexString(System.identityHashCode(this))); - sb.append(" t"); - sb.append(task.taskId); sb.append(" u"); sb.append(userId); sb.append(' '); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index e0b80150fe306..526b24f052b3c 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -21,23 +21,18 @@ 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.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; 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; @@ -54,7 +49,6 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.os.Binder; import android.os.Bundle; -import android.os.Debug; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -67,12 +61,9 @@ import android.os.UserHandle; import android.util.EventLog; import android.util.Log; import android.util.Slog; -import android.util.SparseArray; 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; @@ -100,8 +91,7 @@ final class ActivityStack { static final boolean DEBUG_APP = false; static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS; - static final boolean VALIDATE_TASK_REPLACE = true; - + // How long we wait until giving up on the last activity telling us it // is idle. static final int IDLE_TIMEOUT = 10*1000; @@ -140,7 +130,7 @@ final class ActivityStack { // Set to false to disable the preview that is shown while a new activity // is being started. static final boolean SHOW_APP_STARTING_PREVIEW = true; - + enum ActivityState { INITIALIZING, RESUMED, @@ -157,28 +147,17 @@ final class ActivityStack { final boolean mMainStack; final Context mContext; - + /** * The back history of all previous (and possibly still - * running) activities. It contains #ActivityRecord objects. + * running) activities. It contains HistoryRecord objects. */ - private final ArrayList mHistory = new ArrayList(); - - /** - * The back history of all previous (and possibly still - * running) activities. It contains #TaskRecord objects. - */ - private ArrayList mTaskHistory = new ArrayList(); - - /** - * Mapping from taskId to TaskRecord - */ - private SparseArray mTaskIdToTaskRecord = new SparseArray(); + final ArrayList mHistory = new ArrayList(); /** * Used for validating app tokens with window manager. */ - final ArrayList mValidateAppTokens = new ArrayList(); + final ArrayList mValidateAppTokens = new ArrayList(); /** * List of running activities, sorted by recent usage. @@ -310,12 +289,6 @@ 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; @@ -345,8 +318,6 @@ final class ActivityStack { final Handler mHandler; - String mLastHistoryModifier; - final class ActivityStackHandler extends Handler { //public Handler() { // if (localLOGV) Slog.v(TAG, "Handler started!"); @@ -473,66 +444,26 @@ final class ActivityStack { } final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) { - ActivityRecord newAr = newTopRunningActivityLocked(notTop); - int i = mHistory.size()-1; while (i >= 0) { ActivityRecord r = mHistory.get(i); if (!r.finishing && r != notTop && okToShow(r)) { - if (VALIDATE_TASK_REPLACE && newAr != r) logHistories( - "topRunningActivityLocked", true); return r; } i--; } - if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG, - "topRunningActivityLocked: mismatch: newAr!=null"); - return null; - } - - final ActivityRecord newTopRunningActivityLocked(ActivityRecord notTop) { - for (int i = mTaskHistory.size() - 1; i >= 0; --i) { - final TaskRecord task = mTaskHistory.get(i); - final ArrayList activities = task.mActivities; - for (int j = activities.size() - 1; j >= 0; --j) { - ActivityRecord r = activities.get(j); - if (!r.finishing && r != notTop && okToShow(r)) { - return r; - } - } - } return null; } final ActivityRecord topRunningNonDelayedActivityLocked(ActivityRecord notTop) { - ActivityRecord newAr = newTopRunningNonDelayedActivityLocked(notTop); - int i = mHistory.size()-1; while (i >= 0) { ActivityRecord r = mHistory.get(i); if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) { - if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG, - "topRunningNonDelayedActivityLocked: mismatch: newAr=" + newAr + " r=" + r); return r; } i--; } - if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG, - "topRunningNonDelayedActivityLocked: mismatch: newAr!=null"); - return null; - } - - final ActivityRecord newTopRunningNonDelayedActivityLocked(ActivityRecord notTop) { - for (int i = mTaskHistory.size() - 1; i >= 0; --i) { - final TaskRecord task = mTaskHistory.get(i); - final ArrayList activities = task.mActivities; - for (int j = activities.size() - 1; j >= 0; --j) { - ActivityRecord r = activities.get(j); - if (!r.finishing && !r.delayedResume && r != notTop && okToShow(r)) { - return r; - } - } - } return null; } @@ -546,111 +477,35 @@ final class ActivityStack { * @return Returns the HistoryRecord of the next activity on the stack. */ final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) { - ActivityRecord newAr = newTopRunningActivityLocked(token, taskId); - int i = mHistory.size()-1; while (i >= 0) { ActivityRecord r = mHistory.get(i); // Note: the taskId check depends on real taskId fields being non-zero if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId) && okToShow(r)) { - if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG, - "topRunningActivityLocked(token): mismatch: newAr=" + newAr + " r=" + r); return r; } i--; } - if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG, - "topRunningActivityLocked(token): mismatch: newAr!=null"); return null; } - final ActivityRecord newTopRunningActivityLocked(IBinder token, int taskId) { - for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { - TaskRecord task = mTaskHistory.get(taskNdx); - if (task.taskId == taskId) { - continue; - } - ArrayList activities = task.mActivities; - for (int i = activities.size() - 1; i >= 0; --i) { - final ActivityRecord r = activities.get(i); - // Note: the taskId check depends on real taskId fields being non-zero - if (!r.finishing && (token != r.appToken) && okToShow(r)) { - return r; - } - } - } - return null; - } - - private final int indexOfTokenLocked(IBinder token) { + final int indexOfTokenLocked(IBinder token) { return mHistory.indexOf(ActivityRecord.forToken(token)); } - final ActivityRecord isInStackLocked(IBinder token) { - ActivityRecord newAr = newIsInStackLocked(token); + final int indexOfActivityLocked(ActivityRecord r) { + return mHistory.indexOf(r); + } + final ActivityRecord isInStackLocked(IBinder token) { ActivityRecord r = ActivityRecord.forToken(token); if (mHistory.contains(r)) { - if (VALIDATE_TASK_REPLACE && newAr != r) Slog.w(TAG, - "isInStackLocked: mismatch: newAr=" + newAr + " r=" + r); return r; } - if (VALIDATE_TASK_REPLACE && newAr != null) Slog.w(TAG, - "isInStackLocked: mismatch: newAr!=null"); return null; } - final ActivityRecord newIsInStackLocked(IBinder token) { - final ActivityRecord r = ActivityRecord.forToken(token); - if (r != null) { - final TaskRecord task = r.task; - if (mTaskHistory.contains(task) && task.mActivities.contains(r)) { - return r; - } - } - return null; - } - - int getTaskForActivityLocked(IBinder token, boolean onlyRoot) { - int newTaskId = newGetTaskForActivityLocked(token, 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) { - if (VALIDATE_TASK_REPLACE && newTaskId != r.task.taskId) Slog.w(TAG, - "getTaskForActivityLocked: mismatch: new=" + newTaskId - + " taskId=" + r.task.taskId); - return r.task.taskId; - } - if (VALIDATE_TASK_REPLACE && newTaskId != -1) Slog.w(TAG, - "getTaskForActivityLocked: mismatch: newTaskId=" + newTaskId + " not -1."); - return -1; - } - lastTask = r.task; - } - - if (VALIDATE_TASK_REPLACE && newTaskId != -1) Slog.w(TAG, - "getTaskForActivityLocked: mismatch at end: newTaskId=" + newTaskId + " not -1."); - return -1; - } - - int newGetTaskForActivityLocked(IBinder token, boolean onlyRoot) { - final ActivityRecord r = ActivityRecord.forToken(token); - if (r == null) { - return -1; - } - final TaskRecord task = r.task; - switch (task.mActivities.indexOf(r)) { - case -1: return -1; - case 0: return task.taskId; - default: return onlyRoot ? -1 : task.taskId; - } - } - private final boolean updateLRUListLocked(ActivityRecord r) { final boolean hadit = mLRUActivities.remove(r); mLRUActivities.add(r); @@ -743,29 +598,17 @@ final class ActivityStack { * @return whether there are any activities for the specified user. */ final boolean switchUserLocked(int userId, UserStartedState uss) { - if (VALIDATE_TOKENS) { - validateAppTokensLocked(); - } - final boolean newResult = newSwitchUserLocked(userId, uss); - mCurrentUser = userId; mStartingUsers.add(uss); // Only one activity? Nothing to do... - if (mHistory.size() < 2) { - if (VALIDATE_TASK_REPLACE && newResult) Slog.w(TAG, - "switchUserLocked: mismatch: " + newResult + " " + false); + if (mHistory.size() < 2) return false; - } boolean haveActivities = false; // Check if the top activity is from the new user. ActivityRecord top = mHistory.get(mHistory.size() - 1); - if (top.userId == userId) { - if (VALIDATE_TASK_REPLACE && !newResult) Slog.w(TAG, - "switchUserLocked: mismatch: " + newResult + " " + true); - return true; - } + if (top.userId == userId) return true; // Otherwise, move the user's activities to the top. int N = mHistory.size(); int i = 0; @@ -782,44 +625,7 @@ final class ActivityStack { } } // Transition from the old top to the new top - if (VALIDATE_TASK_REPLACE) Slog.w(TAG, - "switchUserLocked: calling resumeTopActivity " + top); resumeTopActivityLocked(top); - if (VALIDATE_TASK_REPLACE && (newResult != haveActivities)) Slog.w(TAG, - "switchUserLocked: mismatch: " + newResult + " " + haveActivities); - return haveActivities; - } - - /* - * Move the activities around in the stack to bring a user to the foreground. - * @return whether there are any activities for the specified user. - */ - final boolean newSwitchUserLocked(int userId, UserStartedState uss) { -// mStartingUsers.add(uss); - if (mCurrentUser == userId) { - return true; - } - mCurrentUser = userId; - - // Move userId's tasks to the top. - boolean haveActivities = false; - TaskRecord task = null; - int index = mTaskHistory.size(); - for (int i = 0; i < index; ++i) { - task = mTaskHistory.get(i); - if (task.userId == userId) { - haveActivities = true; - mTaskHistory.remove(i); - mTaskHistory.add(task); - --index; - } - } - - // task is now the original topmost TaskRecord. Transition from the old top to the new top. - ActivityRecord top = task != null ? task.getTopActivity() : null; - if (VALIDATE_TASK_REPLACE) Slog.w(TAG, - "newSwitchUserLocked: would call resumeTopActivity " + top); -// resumeTopActivityLocked(top); return haveActivities; } @@ -903,13 +709,7 @@ final class ActivityStack { try { profileFd = profileFd.dup(); } catch (IOException e) { - if (profileFd != null) { - try { - profileFd.close(); - } catch (IOException o) { - } - profileFd = null; - } + profileFd = null; } } app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, @@ -1057,9 +857,6 @@ final class ActivityStack { mGoingToSleep.release(); } // Ensure activities are no longer sleeping. - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } for (int i=mHistory.size()-1; i>=0; i--) { ActivityRecord r = mHistory.get(i); r.setSleeping(false); @@ -1104,9 +901,6 @@ final class ActivityStack { // Make sure any stopped but visible activities are now sleeping. // This ensures that the activity's onStop() is called. - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } for (int i=mHistory.size()-1; i>=0; i--) { ActivityRecord r = mHistory.get(i); if (r.state == ActivityState.STOPPING || r.state == ActivityState.STOPPED) { @@ -1251,9 +1045,6 @@ final class ActivityStack { ActivityRecord r = null; synchronized (mService) { - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } int index = indexOfTokenLocked(token); if (index >= 0) { r = mHistory.get(index); @@ -1271,9 +1062,6 @@ final class ActivityStack { ActivityRecord r = null; synchronized (mService) { - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } int index = indexOfTokenLocked(token); if (index >= 0) { r = mHistory.get(index); @@ -1486,9 +1274,6 @@ final class ActivityStack { // If the top activity is not fullscreen, then we need to // make sure any activities under it are now visible. - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } final int count = mHistory.size(); int i = count-1; while (mHistory.get(i) != top) { @@ -1937,7 +1722,7 @@ final class ActivityStack { try { // Deliver all pending results. - ArrayList a = next.results; + ArrayList a = next.results; if (a != null) { final int N = a.size(); if (!next.finishing && N > 0) { @@ -2025,21 +1810,8 @@ final class ActivityStack { return true; } - /** Temporary until startActivityLocked is rewritten for tasks. */ - private int convertAddPos(int addPos) { - final int taskId = mHistory.get(addPos).task.taskId; - addPos--; - int taskOffset = 0; - while (addPos >= 0 && taskId == mHistory.get(addPos).task.taskId) { - ++taskOffset; - --addPos; - } - return taskOffset; - } - private final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition, Bundle options) { - mLastHistoryModifier = "startActivityLocked"; final int NH = mHistory.size(); int addPos = -1; @@ -2064,15 +1836,13 @@ final class ActivityStack { Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here); } - r.task.addActivityToTop(r); mHistory.add(addPos, r); r.putInHistory(); - mService.mWindowManager.addAppToken(convertAddPos(addPos), r.appToken, - r.task.taskId, r.info.screenOrientation, r.fullscreen, + mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId, + r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); if (VALIDATE_TOKENS) { validateAppTokensLocked(); - verifyActivityRecords(true); } ActivityOptions.abort(options); return; @@ -2105,15 +1875,9 @@ final class ActivityStack { here.fillInStackTrace(); Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here); } - r.task.addActivityToTop(r); mHistory.add(addPos, r); r.putInHistory(); r.frontOfTask = newTask; - if (VALIDATE_TASK_REPLACE) { - if (verifyActivityRecords(false)) { - Slog.w(TAG, "startActivityLocked: addPos=" + addPos); - } - } if (NH > 0) { // We want to show the starting preview window if we are // switching to a new task, or the next activity's process is @@ -2139,8 +1903,8 @@ final class ActivityStack { mNoAnimActivities.remove(r); } r.updateOptionsLocked(options); - mService.mWindowManager.addAppToken(convertAddPos(addPos), - r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen, + mService.mWindowManager.addAppToken( + addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); boolean doShow = true; if (newTask) { @@ -2178,7 +1942,7 @@ final class ActivityStack { } else { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. - mService.mWindowManager.addAppToken(convertAddPos(addPos), r.appToken, r.task.taskId, + mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0); ActivityOptions.abort(options); @@ -2190,27 +1954,13 @@ final class ActivityStack { if (doResume) { resumeTopActivityLocked(null); } - if (VALIDATE_TASK_REPLACE) { - if (verifyActivityRecords(true)) { - Slog.w(TAG, "startActivityLocked: addPos=" + addPos); - } - } } final void validateAppTokensLocked() { mValidateAppTokens.clear(); mValidateAppTokens.ensureCapacity(mHistory.size()); - int taskId = Integer.MIN_VALUE; - TaskGroup task = null; for (int i=0; i 0 @@ -2318,20 +2066,19 @@ final class ActivityStack { if (mService.mCurTask <= 0) { mService.mCurTask = 1; } - target.setTask(createTaskRecord(mService.mCurTask, target.info, null, - false), null, false); + target.setTask(new TaskRecord(mService.mCurTask, target.info, null), + null, false); target.task.affinityIntent = target.intent; if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target + " out to new task " + target.task); } - mService.mWindowManager.setAppGroupId(target.appToken, target.task.taskId); + mService.mWindowManager.setAppGroupId(target.appToken, task.taskId); if (replyChainEnd < 0) { replyChainEnd = targetI; } int dstPos = 0; ThumbnailHolder curThumbHolder = target.thumbHolder; boolean gotOptions = !canMoveOptions; - final int taskId = target.task.taskId; for (int srcPos=targetI; srcPos<=replyChainEnd; srcPos++) { p = mHistory.get(srcPos); if (p.finishing) { @@ -2356,15 +2103,14 @@ final class ActivityStack { } mHistory.remove(srcPos); mHistory.add(dstPos, p); - mService.mWindowManager.setAppGroupId(p.appToken, taskId); + mService.mWindowManager.moveAppToken(dstPos, p.appToken); + mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId); dstPos++; + if (VALIDATE_TOKENS) { + validateAppTokensLocked(); + } i++; } - rebuildTaskHistory(); - mService.mWindowManager.moveTaskToBottom(taskId); - if (VALIDATE_TOKENS) { - validateAppTokensLocked(); - } if (taskTop == p) { taskTop = below; } @@ -2384,7 +2130,8 @@ final class ActivityStack { // like these are all in the reply chain. replyChainEnd = targetI+1; while (replyChainEnd < mHistory.size() && - (mHistory.get(replyChainEnd)).task == task) { + (mHistory.get( + replyChainEnd)).task == task) { replyChainEnd++; } replyChainEnd--; @@ -2481,7 +2228,6 @@ final class ActivityStack { if (replyChainEnd < 0) { replyChainEnd = targetI; } - final int taskId = task.taskId; if (DEBUG_TASKS) Slog.v(TAG, "Reparenting task at index " + targetI + " to " + replyChainEnd); for (int srcPos=replyChainEnd; srcPos>=targetI; srcPos--) { @@ -2507,13 +2253,11 @@ final class ActivityStack { if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p + " from " + srcPos + " to " + lastReparentPos + " in to resetting task " + task); - mService.mWindowManager.setAppGroupId(p.appToken, taskId); - } - rebuildTaskHistory(); - // TODO: This is wrong because it doesn't take lastReparentPos into account. - mService.mWindowManager.moveTaskToTop(taskId); - if (VALIDATE_TOKENS) { - validateAppTokensLocked(); + mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken); + mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId); + if (VALIDATE_TOKENS) { + validateAppTokensLocked(); + } } replyChainEnd = -1; @@ -2558,9 +2302,6 @@ final class ActivityStack { } } - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } return taskTop; } @@ -2627,7 +2368,7 @@ final class ActivityStack { if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE && (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) { if (!ret.finishing) { - int index = mHistory.indexOf(ret); + int index = indexOfTokenLocked(ret.appToken); if (index >= 0) { finishActivityLocked(ret, index, Activity.RESULT_CANCELED, null, "clear", false); @@ -2725,7 +2466,6 @@ final class ActivityStack { */ private final ActivityRecord moveActivityToFrontLocked(int where) { ActivityRecord newTop = mHistory.remove(where); - newMoveActivityToFrontLocked(newTop); int top = mHistory.size(); ActivityRecord oldTop = mHistory.get(top-1); if (DEBUG_ADD_REMOVE) { @@ -2735,17 +2475,6 @@ final class ActivityStack { + top, here); } mHistory.add(top, newTop); - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } - return newTop; - } - - private final ActivityRecord newMoveActivityToFrontLocked(ActivityRecord newTop) { - final TaskRecord task = newTop.task; - ActivityRecord oldTop = task.getTopActivity(); - task.mActivities.remove(newTop); - task.mActivities.add(newTop); oldTop.frontOfTask = false; newTop.frontOfTask = true; return newTop; @@ -2756,7 +2485,6 @@ final class ActivityStack { String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options, boolean componentSpecified, ActivityRecord[] outActivity) { - mLastHistoryModifier = "startActivityLocked(IApplicationThread)"; int err = ActivityManager.START_SUCCESS; @@ -3239,7 +2967,7 @@ final class ActivityStack { if (mService.mCurTask <= 0) { mService.mCurTask = 1; } - r.setTask(createTaskRecord(mService.mCurTask, r.info, intent, true), null, true); + r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true); if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " + r.task); } else { @@ -3303,7 +3031,7 @@ final class ActivityStack { N > 0 ? mHistory.get(N-1) : null; r.setTask(prev != null ? prev.task - : createTaskRecord(mService.mCurTask, r.info, intent, true), null, true); + : new TaskRecord(mService.mCurTask, r.info, intent), null, true); if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new guessed " + r.task); } @@ -3795,7 +3523,7 @@ final class ActivityStack { } // Get the activity record. - int index = mHistory.indexOf(r); + int index = indexOfActivityLocked(r); if (index >= 0) { res = r; @@ -3851,9 +3579,9 @@ final class ActivityStack { finishes = new ArrayList(mFinishingActivities); mFinishingActivities.clear(); } - if ((NT=mCancelledThumbnails.size()) > 0) { - thumbnails = new ArrayList(mCancelledThumbnails); - mCancelledThumbnails.clear(); + if ((NT=mService.mCancelledThumbnails.size()) > 0) { + thumbnails = new ArrayList(mService.mCancelledThumbnails); + mService.mCancelledThumbnails.clear(); } if (mMainStack) { @@ -3881,7 +3609,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=0; i--) { - ActivityRecord r = mHistory.get(i); + ActivityRecord r = (ActivityRecord)mHistory.get(i); if (r.resultTo == self && r.requestCode == requestCode) { if ((r.resultWho == null && resultWho == null) || (r.resultWho != null && r.resultWho.equals(resultWho))) { @@ -3969,36 +3697,6 @@ 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( @@ -4053,19 +3751,6 @@ 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. @@ -4119,7 +3804,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. - mCancelledThumbnails.add(r); + mService.mCancelledThumbnails.add(r); } if (immediate) { @@ -4162,7 +3847,7 @@ final class ActivityStack { private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r, int mode, boolean oomAdj) { - final int index = mHistory.indexOf(r); + final int index = indexOfActivityLocked(r); if (index < 0) { return null; } @@ -4218,102 +3903,16 @@ 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); } - - // 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 @@ -4365,7 +3964,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. - mCancelledThumbnails.add(r); + mService.mCancelledThumbnails.add(r); } // Get rid of any pending idle timeouts. @@ -4388,10 +3987,6 @@ final class ActivityStack { here.fillInStackTrace(); Slog.i(TAG, "Removing activity " + r + " from stack"); } - final TaskRecord task = r.task; - if (task != null) { - task.removeActivity(r); - } mHistory.remove(r); r.takeFromHistory(); removeTimeoutsForActivityLocked(r); @@ -4576,7 +4171,7 @@ final class ActivityStack { mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r); } - int index = mHistory.indexOf(r); + int index = indexOfActivityLocked(r); if (index >= 0) { if (r.state == ActivityState.DESTROYING) { cleanUpActivityLocked(r, true, false); @@ -4590,15 +4185,15 @@ final class ActivityStack { } } - private void removeHistoryRecordsForAppLocked(ArrayList list, - ProcessRecord app, String listName) { + private void removeHistoryRecordsForAppLocked(ArrayList 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 = list.get(i); + ActivityRecord r = (ActivityRecord)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!"); @@ -4624,7 +4219,7 @@ final class ActivityStack { TAG, "Removing app " + app + " from history with " + i + " entries"); while (i > 0) { i--; - ActivityRecord r = mHistory.get(i); + ActivityRecord r = (ActivityRecord)mHistory.get(i); if (DEBUG_CLEANUP) Slog.v( TAG, "Record #" + i + " " + r + ": app=" + r.app); if (r.app == app) { @@ -4692,7 +4287,6 @@ final class ActivityStack { * of the stack. */ final void moveHomeToFrontLocked() { - newMoveHomeToFrontLocked(); TaskRecord homeTask = null; for (int i=mHistory.size()-1; i>=0; i--) { ActivityRecord hr = mHistory.get(i); @@ -4702,23 +4296,6 @@ final class ActivityStack { } } if (homeTask != null) { -// moveTaskToFrontLocked(homeTask, null, null); - } - } - - final void newMoveHomeToFrontLocked() { - TaskRecord homeTask = null; - for (int taskNdx = mTaskHistory.size() - 1; homeTask == null && taskNdx >= 0; --taskNdx) { - final ArrayList activities = mTaskHistory.get(taskNdx).mActivities; - for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - if (r.isHomeActivity) { - homeTask = r.task; - break; - } - } - } - if (homeTask != null) { moveTaskToFrontLocked(homeTask, null, null); } } @@ -4735,39 +4312,32 @@ 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); final int task = tr.taskId; int top = mHistory.size()-1; if (top < 0 || (mHistory.get(top)).task.taskId == task) { // nothing to do! + if (reason != null && + (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { + ActivityOptions.abort(options); + } else { + updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); + } return; } + ArrayList moved = new ArrayList(); + + // Applying the affinities may have removed entries from the history, + // so get the size again. + top = mHistory.size()-1; + int pos = top; // Shift all activities with this task up to the top // of the stack, keeping them in the same internal order. - int pos = top; while (pos >= 0) { ActivityRecord r = mHistory.get(pos); if (localLOGV) Slog.v( @@ -4781,37 +4351,18 @@ final class ActivityStack { } mHistory.remove(pos); mHistory.add(top, r); + moved.add(0, r.appToken); top--; } pos--; } - // - // Start new code here! Delete everything above. - // - if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr); - final int numTasks = mTaskHistory.size(); - final int index = mTaskHistory.indexOf(tr); - if (numTasks == 0 || index < 0 || index == numTasks - 1) { - // nothing to do! - if (reason != null && - (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - ActivityOptions.abort(options); - } else { - updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); - } - return; - } - - // Shift all activities with this task up to the top - // of the stack, keeping them in the same internal order. - mTaskHistory.remove(tr); - mTaskHistory.add(tr); - - if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to front transition: task=" + tr); + if (DEBUG_TRANSITION) Slog.v(TAG, + "Prepare to front transition: task=" + tr); if (reason != null && (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); + mService.mWindowManager.prepareAppTransition( + AppTransition.TRANSIT_NONE, false); ActivityRecord r = topRunningActivityLocked(null); if (r != null) { mNoAnimActivities.add(r); @@ -4820,18 +4371,14 @@ final class ActivityStack { } else { updateTransitLocked(AppTransition.TRANSIT_TASK_TO_FRONT, options); } - - mService.mWindowManager.moveTaskToTop(task); - - finishTaskMoveLocked(task); - EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task); - + + mService.mWindowManager.moveAppTokensToTop(moved); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } + + finishTaskMoveLocked(task); + EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, task); } private final void finishTaskMoveLocked(int task) { @@ -4851,7 +4398,7 @@ final class ActivityStack { */ final boolean moveTaskToBackLocked(int task, ActivityRecord reason) { Slog.i(TAG, "moveTaskToBack: " + task); - + // If we have a watcher, preflight the move before committing to it. First check // for *other* available tasks, but if none are available, then try again allowing the // current task to be selected. @@ -4874,14 +4421,11 @@ final class ActivityStack { } } + ArrayList moved = new ArrayList(); + if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to back transition: task=" + task); - - final TaskRecord tr = mTaskIdToTaskRecord.get(task); - mTaskHistory.remove(tr); - mTaskHistory.add(0, tr); - - // BEGIN REGION TO REMOVE. + final int N = mHistory.size(); int bottom = 0; int pos = 0; @@ -4902,18 +4446,16 @@ final class ActivityStack { } mHistory.remove(pos); mHistory.add(bottom, r); + moved.add(r.appToken); bottom++; } pos++; } - if (VALIDATE_TASK_REPLACE) { - verifyActivityRecords(true); - } - // END REGION TO REMOVE if (reason != null && (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { - mService.mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false); + mService.mWindowManager.prepareAppTransition( + AppTransition.TRANSIT_NONE, false); ActivityRecord r = topRunningActivityLocked(null); if (r != null) { mNoAnimActivities.add(r); @@ -4922,8 +4464,7 @@ final class ActivityStack { mService.mWindowManager.prepareAppTransition( AppTransition.TRANSIT_TASK_TO_BACK, false); } - mService.mWindowManager.moveTaskToBottom(task); - + mService.mWindowManager.moveAppTokensToBottom(moved); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -4956,8 +4497,9 @@ 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, @@ -5037,7 +4579,6 @@ 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; @@ -5236,283 +4777,4 @@ 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; - } - - void rebuildTaskHistory() { - mTaskHistory.clear(); - final int numActivities = mHistory.size(); - TaskRecord task = null; - for (int i = 0; i < numActivities; ++i) { - final ActivityRecord r = mHistory.get(i); - if (r.task != task) { - task = r.task; - task.mActivities.clear(); - mTaskHistory.add(task); - } - task.mActivities.add(r); - } - } - - boolean verifyActivityRecords(boolean rebuild) { - final int numHistory = mHistory.size(); - int historyNdx = 0; - - final int numTasks = mTaskHistory.size(); - int taskNdx; - for (taskNdx = historyNdx = 0; taskNdx < numTasks; ++taskNdx) { - final TaskRecord task = mTaskHistory.get(taskNdx); - final ArrayList activities = task.mActivities; - final int numActivities = activities.size(); - int activityNdx; - for (activityNdx = 0; - activityNdx < numActivities && historyNdx < numHistory; - ++activityNdx, ++historyNdx) { - ActivityRecord r1 = mHistory.get(historyNdx); - ActivityRecord r2 = activities.get(activityNdx); - if (r1 != r2) { - break; - } - } - if (activityNdx != numActivities) { - // either a mismatch or mHistory ran out before mTaskHistory. - break; - } - } - if (taskNdx != numTasks || historyNdx != numHistory) { - logHistories("verifyActivityRecords", rebuild); - return true; - } - return false; - } - - private void logHistories(String caller, boolean rebuild) { - Slog.w(TAG, "Mismatch! " + caller + " mHistory=" + mHistory); - ArrayList> nestedRecords = - new ArrayList>(); - for (TaskRecord task : mTaskHistory) { - nestedRecords.add(task.mActivities); - } - Slog.w(TAG, "Mismatch! " + caller + " mTaskHistory" + nestedRecords); - Slog.w(TAG, "Mismatch! " + caller + " lastHistoryModifier=" + mLastHistoryModifier - + " Caller=" + Debug.getCallers(4)); - if (rebuild) { - rebuildTaskHistory(); - } - } - - private TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent, - boolean toTop) { - TaskRecord oldTask = mTaskIdToTaskRecord.get(taskId); - if (oldTask != null) { - Slog.w(TAG, "createTaskRecord: Reusing taskId=" + taskId + " without removing"); - mTaskHistory.remove(oldTask); - } - TaskRecord task = new TaskRecord(taskId, info, intent); - mTaskIdToTaskRecord.put(taskId, task); - if (toTop) { - mTaskHistory.add(task); - } else { - mTaskHistory.add(0, task); - } - return task; - } } diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java index 863bdad421777..3a6492e2957b1 100644 --- a/services/java/com/android/server/am/CompatModePackages.java +++ b/services/java/com/android/server/am/CompatModePackages.java @@ -295,8 +295,20 @@ public class CompatModePackages { Message msg = mHandler.obtainMessage(MSG_WRITE); mHandler.sendMessageDelayed(msg, 10000); - - ActivityRecord starting = mService.mMainStack.restartPackage(packageName); + 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); + } + } + } // 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 c4607916bb394..ed478c9741c8b 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. - final HashSet pendingRecords; // HistoryRecord objects we still wait for. + 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; } } diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java index f9b0d4cfe93bd..1bae9ca53adf2 100644 --- a/services/java/com/android/server/am/TaskRecord.java +++ b/services/java/com/android/server/am/TaskRecord.java @@ -23,7 +23,6 @@ import android.os.UserHandle; import android.util.Slog; import java.io.PrintWriter; -import java.util.ArrayList; class TaskRecord extends ThumbnailHolder { final int taskId; // Unique identifier for this task. @@ -40,11 +39,7 @@ class TaskRecord extends ThumbnailHolder { String stringName; // caching of toString() result. int userId; // user for which this task was created - - int numFullscreen; // Number of fullscreen activities. - - final ArrayList mActivities = new ArrayList(); - + TaskRecord(int _taskId, ActivityInfo info, Intent _intent) { taskId = _taskId; affinity = info.taskAffinity; @@ -109,63 +104,12 @@ class TaskRecord extends ThumbnailHolder { userId = UserHandle.getUserId(info.applicationInfo.uid); } } - - ActivityRecord getTopActivity() { - for (int i = mActivities.size() - 1; i >= 0; --i) { - final ActivityRecord r = mActivities.get(i); - if (r.finishing) { - continue; - } - return r; - } - return null; - } - - void addActivityAtBottom(ActivityRecord r) { - if (!mActivities.remove(r) && r.fullscreen) { - // Was not previously in list. - numFullscreen++; - } - mActivities.add(0, r); - } - - void addActivityToTop(ActivityRecord r) { - if (!mActivities.remove(r) && r.fullscreen) { - // Was not previously in list. - numFullscreen++; - } - // TODO: This only matters to achieve identical results as mHistory. Later we won't need - // to skip over finishing activities. - int i; - for (i = mActivities.size() - 1; i >= 0; --i) { - if (!mActivities.get(i).finishing) { - break; - } - } - if (i >= 0) { - // Add below finishing activities. - mActivities.add(i + 1, r); - } else { - // All activities are finishing, add to top. - mActivities.add(r); - } - } - - /** @return true if this was the last activity in the task */ - boolean removeActivity(ActivityRecord r) { - if (mActivities.remove(r) && r.fullscreen) { - // Was previously in list. - numFullscreen--; - } - return mActivities.size() == 0; - } - + void dump(PrintWriter pw, String prefix) { if (numActivities != 0 || rootWasReset || userId != 0) { pw.print(prefix); pw.print("numActivities="); pw.print(numActivities); pw.print(" rootWasReset="); pw.print(rootWasReset); - pw.print(" userId="); pw.print(userId); - pw.print(" numFullscreen="); pw.println(numFullscreen); + pw.print(" userId="); pw.println(userId); } if (affinity != null) { pw.print(prefix); pw.print("affinity="); pw.println(affinity); @@ -192,7 +136,6 @@ class TaskRecord extends ThumbnailHolder { pw.print(prefix); pw.print("realActivity="); pw.println(realActivity.flattenToShortString()); } - pw.print(prefix); pw.print("Activities="); pw.println(mActivities); if (!askedCompatMode) { pw.print(prefix); pw.print("askedCompatMode="); pw.println(askedCompatMode); } @@ -203,7 +146,6 @@ class TaskRecord extends ThumbnailHolder { pw.print((getInactiveDuration()/1000)); pw.println("s)"); } - @Override public String toString() { if (stringName != null) { return stringName; @@ -214,21 +156,19 @@ class TaskRecord extends ThumbnailHolder { sb.append(" #"); sb.append(taskId); if (affinity != null) { - sb.append(" A="); + sb.append(" A "); sb.append(affinity); } else if (intent != null) { - sb.append(" I="); + sb.append(" I "); sb.append(intent.getComponent().flattenToShortString()); } else if (affinityIntent != null) { - sb.append(" aI="); + sb.append(" aI "); sb.append(affinityIntent.getComponent().flattenToShortString()); } else { sb.append(" ??"); } - sb.append(" U="); + sb.append(" U "); sb.append(userId); - sb.append(" sz="); - sb.append(mActivities.size()); sb.append('}'); return stringName = sb.toString(); } diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index 8cc1d0211132b..fbb501397163a 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -30,10 +30,6 @@ import android.view.View; import android.view.WindowManager; import java.io.PrintWriter; -import java.util.ArrayList; - -class AppTokenList extends ArrayList { -} /** * Version of WindowToken that is specifically for a particular application (or diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 6aae202d23096..59e4b0e6f7302 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -16,17 +16,11 @@ package com.android.server.wm; -import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR; -import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR; - -import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Iterator; -import java.util.NoSuchElementException; class DisplayContentList extends ArrayList { } @@ -39,7 +33,6 @@ class DisplayContentList extends ArrayList { * WindowManagerService.mWindowMap. */ class DisplayContent { -// private final static String TAG = "DisplayContent"; /** Unique identifier of this stack. */ private final int mDisplayId; @@ -73,26 +66,6 @@ class DisplayContent { int pendingLayoutChanges; final boolean isDefaultDisplay; - /** - * Window tokens that are in the process of exiting, but still - * on screen for animations. - */ - final ArrayList mExitingTokens = new ArrayList(); - - /** - * Application tokens that are in the process of exiting, but still - * on screen for animations. - */ - final AppTokenList mExitingAppTokens = new AppTokenList(); - - /** - * Sorted most recent at top, oldest at [0]. - */ - ArrayList mTaskLists = new ArrayList(); - SparseArray mTaskIdToTaskList = new SparseArray(); - - private final AppTokenIterator mTmpAppIterator = new AppTokenIterator(); - /** * @param display May not be null. */ @@ -123,147 +96,6 @@ class DisplayContent { mDisplay.getDisplayInfo(mDisplayInfo); } - /** - * Find the location to insert a new AppWindowToken into the window-ordered app token list. - * @param addPos The location the token was inserted into in mAppTokens. - * @param wtoken The token to insert. - */ - void addAppToken(final int addPos, final AppWindowToken wtoken) { - TaskList task = mTaskIdToTaskList.get(wtoken.groupId); - if (task == null) { - task = new TaskList(wtoken, this); - mTaskIdToTaskList.put(wtoken.groupId, task); - mTaskLists.add(task); - } else { - task.mAppTokens.add(addPos, wtoken); - } - } - - void removeAppToken(final AppWindowToken wtoken) { - final int taskId = wtoken.groupId; - final TaskList task = mTaskIdToTaskList.get(taskId); - if (task != null) { - AppTokenList appTokens = task.mAppTokens; - appTokens.remove(wtoken); - if (appTokens.size() == 0) { - mTaskLists.remove(task); - mTaskIdToTaskList.delete(taskId); - } - } - } - - void setAppTaskId(AppWindowToken wtoken, int newTaskId) { - final int taskId = wtoken.groupId; - TaskList task = mTaskIdToTaskList.get(taskId); - if (task != null) { - AppTokenList appTokens = task.mAppTokens; - appTokens.remove(wtoken); - if (appTokens.size() == 0) { - mTaskIdToTaskList.delete(taskId); - } - } - - task = mTaskIdToTaskList.get(newTaskId); - if (task == null) { - task = new TaskList(wtoken, this); - mTaskIdToTaskList.put(newTaskId, task); - } else { - task.mAppTokens.add(wtoken); - } - - wtoken.groupId = newTaskId; - } - - /** - * Return the utility iterator so we don't have to construct new iterators every time we - * iterate. - * NOTE: Do not ever nest this call or you will have a bad time! - * @param reverse Direction of iterator. - * @return The utility iterator. - */ - AppTokenIterator getTmpAppIterator(boolean reverse) { - mTmpAppIterator.reset(reverse); - return mTmpAppIterator; - } - - class AppTokenIterator implements Iterator { - boolean mReverse; - int mTasksNdx; - int mActivityNdx; - TaskList mTaskList; - - public AppTokenIterator() { - this(FORWARD_ITERATOR); - } - - public AppTokenIterator(boolean reverse) { - reset(reverse); - } - - void reset(boolean reverse) { - mReverse = reverse; - mTasksNdx = reverse ? mTaskLists.size() - 1 : 0; - getNextTaskList(); - } - - private void getNextTaskList() { - if (mReverse) { - if (mTasksNdx >= 0) { - mTaskList = mTaskLists.get(mTasksNdx); - --mTasksNdx; - mActivityNdx = mTaskList.mAppTokens.size() - 1; - } - } else { - if (mTasksNdx < mTaskLists.size()) { - mTaskList = mTaskLists.get(mTasksNdx); - ++mTasksNdx; - mActivityNdx = 0; - } - } - } - - @Override - public boolean hasNext() { - if (mTaskList == null) { - return false; - } - if (mReverse) { - return mActivityNdx >= 0; - } - return mActivityNdx < mTaskList.mAppTokens.size(); - } - - @Override - public AppWindowToken next() { - if (hasNext()) { - AppWindowToken wtoken = mTaskList.mAppTokens.get(mActivityNdx); - mActivityNdx += mReverse ? -1 : 1; - if (!hasNext()) { - getNextTaskList(); - } - return wtoken; - } - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new IllegalArgumentException(); - } - - int size() { - int size = 0; - for (int i = mTaskLists.size() - 1; i >= 0; --i) { - size += mTaskLists.get(i).mAppTokens.size(); - } - return size; - } - - @Override public String toString() { - return mTaskLists.toString(); - } - } - public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.print("Display: mDisplayId="); pw.println(mDisplayId); final String subPrefix = " " + prefix; @@ -287,51 +119,7 @@ class DisplayContent { pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight); pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); - pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded); - AppTokenIterator iterator = getTmpAppIterator(REVERSE_ITERATOR); - int ndx = iterator.size() - 1; - if (ndx >= 0) { - pw.println(); - pw.println(" Application tokens in Z order:"); - while (iterator.hasNext()) { - AppWindowToken wtoken = iterator.next(); - pw.print(" App #"); pw.print(ndx--); - pw.print(' '); pw.print(wtoken); pw.println(":"); - wtoken.dump(pw, " "); - } - } - if (mExitingTokens.size() > 0) { - pw.println(); - pw.println(" Exiting tokens:"); - for (int i=mExitingTokens.size()-1; i>=0; i--) { - WindowToken token = mExitingTokens.get(i); - pw.print(" Exiting #"); pw.print(i); - pw.print(' '); pw.print(token); - pw.println(':'); - token.dump(pw, " "); - } - } - if (mExitingAppTokens.size() > 0) { - pw.println(); - pw.println(" Exiting application tokens:"); - for (int i=mExitingAppTokens.size()-1; i>=0; i--) { - WindowToken token = mExitingAppTokens.get(i); - pw.print(" Exiting App #"); pw.print(i); - pw.print(' '); pw.print(token); - pw.println(':'); - token.dump(pw, " "); - } - } - if (mTaskIdToTaskList.size() > 0) { - pw.println(); - for (int i = 0; i < mTaskIdToTaskList.size(); ++i) { - pw.print(" TaskList #"); pw.print(i); - pw.print(" taskId="); pw.println(mTaskIdToTaskList.keyAt(i)); - pw.print(" mAppTokens="); - pw.println(mTaskIdToTaskList.valueAt(i).mAppTokens); - pw.println(); - } - } + pw.print(subPrefix); pw.print("layoutNeeded="); pw.print(layoutNeeded); pw.println(); } } diff --git a/services/java/com/android/server/wm/TaskGroup.java b/services/java/com/android/server/wm/TaskGroup.java deleted file mode 100644 index 1f1dd5832d558..0000000000000 --- a/services/java/com/android/server/wm/TaskGroup.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -import android.view.IApplicationToken; - -import java.util.ArrayList; - -public class TaskGroup { - public int taskId = -1; - public ArrayList tokens = new ArrayList(); - - @Override - public String toString() { - return "id=" + taskId + " tokens=" + tokens; - } -} diff --git a/services/java/com/android/server/wm/TaskList.java b/services/java/com/android/server/wm/TaskList.java deleted file mode 100644 index 67dfa4f333b44..0000000000000 --- a/services/java/com/android/server/wm/TaskList.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wm; - -class TaskList { -// private final String TAG = "TaskGroup"; - DisplayContent mDisplayContent; - final AppTokenList mAppTokens = new AppTokenList(); - final int taskId; - - TaskList(AppWindowToken wtoken, DisplayContent displayContent) { - taskId = wtoken.groupId; - mAppTokens.add(wtoken); - mDisplayContent = displayContent; - } - - @Override - public String toString() { - return "id=" + taskId + " appTokens=" + mAppTokens; - } -} diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 67daf751d4563..3964782baced9 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -10,8 +10,6 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPA import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING; -import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR; -import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR; import android.content.Context; import android.os.Debug; @@ -28,7 +26,6 @@ import android.view.SurfaceControl; import android.view.WindowManagerPolicy; import android.view.animation.Animation; -import com.android.server.wm.DisplayContent.AppTokenIterator; import com.android.server.wm.WindowManagerService.DisplayContentsIterator; import com.android.server.wm.WindowManagerService.LayoutFields; @@ -175,12 +172,12 @@ public class WindowAnimator { } } - private void updateAppWindowsLocked(int displayId) { + private void updateAppWindowsLocked() { int i; - final DisplayContent displayContent = mService.getDisplayContentLocked(displayId); - AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR); - while (iterator.hasNext()) { - final AppWindowAnimator appAnimator = iterator.next().mAppAnimator; + final ArrayList appTokens = mService.mAnimatingAppTokens; + final int NAT = appTokens.size(); + for (i=0; i appTokens = mService.mAnimatingAppTokens; + final int NT = appTokens.size(); + for (int i=0; i mTokenMap = new HashMap(); + final HashMap mTokenMap = + new HashMap(); + + /** + * Window tokens that are in the process of exiting, but still + * on screen for animations. + */ + final ArrayList mExitingTokens = new ArrayList(); + + /** + * List controlling the ordering of windows in different applications which must + * be kept in sync with ActivityManager. + */ + final ArrayList mAppTokens = new ArrayList(); + + /** + * AppWindowTokens in the Z order they were in at the start of an animation. Between + * animations this list is maintained in the exact order of mAppTokens. If tokens + * are added to mAppTokens during an animation an attempt is made to insert them at the same + * logical location in this list. Note that this list is always in sync with mWindows. + */ + ArrayList mAnimatingAppTokens = new ArrayList(); + + /** + * Application tokens that are in the process of exiting, but still + * on screen for animations. + */ + final ArrayList mExitingAppTokens = new ArrayList(); /** * List of window tokens that have finished starting their application, @@ -422,12 +444,8 @@ public class WindowManagerService extends IWindowManager.Stub String mLastANRState; - /** All DisplayContents in the world, kept here */ + /** All DisplayDontents in the world, kept here */ private SparseArray mDisplayContents = new SparseArray(); - private SparseArray mTaskIdToDisplayContents = - new SparseArray(); - - private final AllWindowsIterator mTmpWindowsIterator = new AllWindowsIterator(); int mRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -901,6 +919,7 @@ public class WindowManagerService extends IWindowManager.Stub final WindowList windows = win.getWindowList(); final int N = windows.size(); final WindowState attached = win.mAttachedWindow; + int i; WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent); if (attached == null) { int tokenWindowsPos = 0; @@ -950,11 +969,12 @@ public class WindowManagerService extends IWindowManager.Stub + client.asBinder() + " (token=" + token + ")"); // Figure out where the window should go, based on the // order of applications. + final int NA = mAnimatingAppTokens.size(); WindowState pos = null; - AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR); - while (iterator.hasNext()) { - AppWindowToken t = iterator.next(); + for (i=NA-1; i>=0; i--) { + AppWindowToken t = mAnimatingAppTokens.get(i); if (t == token) { + i--; break; } @@ -987,14 +1007,15 @@ public class WindowManagerService extends IWindowManager.Stub } else { // Continue looking down until we find the first // token that has windows on this display. - while (iterator.hasNext()) { - AppWindowToken t = iterator.next(); - tokenWindowList = getTokenWindowsOnDisplay(t, displayContent); + while (i >= 0) { + AppWindowToken t = mAnimatingAppTokens.get(i); + tokenWindowList = getTokenWindowsOnDisplay(t, win.mDisplayContent); final int NW = tokenWindowList.size(); if (NW > 0) { pos = tokenWindowList.get(NW-1); break; } + i--; } if (pos != null) { // Move in front of any windows attached to this @@ -1013,8 +1034,7 @@ public class WindowManagerService extends IWindowManager.Stub } else { // Just search for the start of this layer. final int myLayer = win.mBaseLayer; - int i; - for (i = 0; i < N; i++) { + for (i=0; i myLayer) { break; @@ -1032,8 +1052,7 @@ public class WindowManagerService extends IWindowManager.Stub } else { // Figure out where window should go, based on layer. final int myLayer = win.mBaseLayer; - int i; - for (i = N - 1; i >= 0; i--) { + for (i=N-1; i>=0; i--) { if (windows.get(i).mBaseLayer <= myLayer) { break; } @@ -1058,8 +1077,7 @@ public class WindowManagerService extends IWindowManager.Stub final int sublayer = win.mSubLayer; int largestSublayer = Integer.MIN_VALUE; WindowState windowWithLargestSublayer = null; - int i; - for (i = 0; i < NA; i++) { + for (i=0; i= largestSublayer) { @@ -2464,15 +2482,22 @@ public class WindowManagerService extends IWindowManager.Stub public void updateAppOpsState() { synchronized(mWindowMap) { - mTmpWindowsIterator.reset(FORWARD_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - final WindowState win = mTmpWindowsIterator.next(); - if (win.mAppOp != AppOpsManager.OP_NONE) { - final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(), - win.getOwningPackage()); - win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED); + boolean changed = false; + for (int i=0; i tasks) { - synchronized (mWindowMap) { - int t = tasks.size() - 1; - if (t < 0) { - Slog.w(TAG, "validateAppTokens: empty task list"); - return; + public void validateAppTokens(List tokens) { + int v = tokens.size()-1; + int m = mAppTokens.size()-1; + while (v >= 0 && m >= 0) { + AppWindowToken atoken = mAppTokens.get(m); + if (atoken.removed) { + m--; + continue; } - - TaskGroup task = tasks.get(0); - int taskId = task.taskId; - DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId); - if (displayContent == null) { - Slog.w(TAG, "validateAppTokens: no Display for taskId=" + taskId); - return; + if (tokens.get(v) != atoken.token) { + Slog.w(TAG, "Tokens out of sync: external is " + tokens.get(v) + + " @ " + v + ", internal is " + atoken.token + " @ " + m); } - - boolean mismatch = false; - AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR); - for ( ; t >= 0 && !mismatch; --t) { - task = tasks.get(t); - List tokens = task.tokens; - int v = task.tokens.size() - 1; - - DisplayContent lastDisplayContent = displayContent; - displayContent = mTaskIdToDisplayContents.get(taskId); - if (displayContent != lastDisplayContent) { - Slog.w(TAG, "validateAppTokens: displayContent changed in TaskGroup list!"); - return; - } - - while (v >= 0) { - if (!iterator.hasNext()) { - mismatch = true; - break; - } - AppWindowToken atoken = iterator.next(); - if (atoken.removed) { - continue; - } - if (tokens.get(v) != atoken.token) { - mismatch = true; - break; - } - v--; - } - } - - if (mismatch || iterator.hasNext()) { - Slog.w(TAG, "validateAppTokens: Mismatch! ActivityManager=" + tasks); - Slog.w(TAG, "validateAppTokens: Mismatch! WindowManager=" + iterator); - Slog.w(TAG, "validateAppTokens: Mismatch! Callers=" + Debug.getCallers(4)); + v--; + m--; + } + while (v >= 0) { + Slog.w(TAG, "External token not found: " + tokens.get(v) + " @ " + v); + v--; + } + while (m >= 0) { + AppWindowToken atoken = mAppTokens.get(m); + if (!atoken.removed) { + Slog.w(TAG, "Invalid internal atoken: " + atoken.token + " @ " + m); } + m--; } } @@ -3227,7 +3226,6 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); synchronized(mWindowMap) { - DisplayContent displayContent = null; WindowToken wtoken = mTokenMap.remove(token); if (wtoken != null) { boolean delayed = false; @@ -3237,7 +3235,6 @@ public class WindowManagerService extends IWindowManager.Stub for (int i=0; i=0; i--) { + Slog.v(TAG, " #" + i + ": " + mAppTokens.get(i).token); + } + } + + void dumpAnimatingAppTokensLocked() { + for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) { + Slog.v(TAG, " #" + i + ": " + mAnimatingAppTokens.get(i).token); } } void dumpWindowsLocked() { int i = 0; - mTmpWindowsIterator.reset(REVERSE_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - final WindowState w = mTmpWindowsIterator.next(); + final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); + while (iterator.hasNext()) { + final WindowState w = iterator.next(); Slog.v(TAG, " #" + i++ + ": " + w); } } - private int findAppWindowInsertionPointLocked(AppWindowToken target) { - final int taskId = target.groupId; - DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId); - if (displayContent == null) { - Slog.w(TAG, "findTopAppWindowLocked: no DisplayContent for " + target); - return 0; - } - final WindowList windows = displayContent.getWindowList(); + private int findWindowOffsetLocked(WindowList windows, int tokenPos) { final int NW = windows.size(); - AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR); - while (iterator.hasNext()) { - if (iterator.next() == target) { - break; + if (tokenPos >= mAnimatingAppTokens.size()) { + int i = NW; + while (i > 0) { + i--; + WindowState win = windows.get(i); + if (win.getAppToken() != null) { + return i+1; + } } } - while (iterator.hasNext()) { + while (tokenPos > 0) { // Find the first app token below the new position that has // a window displayed. - final AppWindowToken wtoken = iterator.next(); - if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows in " + wtoken.token); + final AppWindowToken wtoken = mAppTokens.get(tokenPos-1); + if (DEBUG_REORDER) Slog.v(TAG, "Looking for lower windows @ " + + tokenPos + " -- " + wtoken.token); if (wtoken.sendingToBottom) { - if (DEBUG_REORDER) Slog.v(TAG, "Skipping token -- currently sending to bottom"); + if (DEBUG_REORDER) Slog.v(TAG, + "Skipping token -- currently sending to bottom"); + tokenPos--; continue; } - for (int i = wtoken.windows.size() - 1; i >= 0; --i) { + int i = wtoken.windows.size(); + while (i > 0) { + i--; WindowState win = wtoken.windows.get(i); - for (int j = win.mChildWindows.size() - 1; j >= 0; --j) { + int j = win.mChildWindows.size(); + while (j > 0) { + j--; WindowState cwin = win.mChildWindows.get(j); if (cwin.mSubLayer >= 0) { - for (int pos = NW - 1; pos >= 0; pos--) { + for (int pos=NW-1; pos>=0; pos--) { if (windows.get(pos) == cwin) { if (DEBUG_REORDER) Slog.v(TAG, - "Found child win @" + (pos + 1)); - return pos + 1; + "Found child win @" + (pos+1)); + return pos+1; } } } } - for (int pos = NW - 1; pos >= 0; pos--) { + for (int pos=NW-1; pos>=0; pos--) { if (windows.get(pos) == win) { - if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos + 1)); - return pos + 1; + if (DEBUG_REORDER) Slog.v(TAG, "Found win @" + (pos+1)); + return pos+1; } } } + tokenPos--; } return 0; @@ -4499,104 +4505,198 @@ public class WindowManagerService extends IWindowManager.Stub return index; } - private void moveTaskWindowsLocked(int taskId) { - DisplayContent displayContent = mTaskIdToDisplayContents.get(taskId); - if (displayContent == null) { - Slog.w(TAG, "moveTaskWindowsLocked: can't find DisplayContent for taskId=" + taskId); - return; + @Override + public void moveAppToken(int index, IBinder token) { + if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, + "moveAppToken()")) { + throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } - TaskList taskList = displayContent.mTaskIdToTaskList.get(taskId); - if (taskList == null) { - Slog.w(TAG, "moveTaskWindowsLocked: can't find TaskList for taskId=" + taskId); - return; - } + synchronized(mWindowMap) { + if (DEBUG_REORDER) Slog.v(TAG, "Initial app tokens:"); + if (DEBUG_REORDER) dumpAppTokensLocked(); + final AppWindowToken wtoken = findAppWindowToken(token); + final int oldIndex = mAppTokens.indexOf(wtoken); + if (DEBUG_TOKEN_MOVEMENT || DEBUG_REORDER) Slog.v(TAG, + "Start moving token " + wtoken + " initially at " + + oldIndex); + if (oldIndex > index && mAppTransition.isTransitionSet()) { + // animation towards back has not started, copy old list for duration of animation. + mAnimatingAppTokens.clear(); + mAnimatingAppTokens.addAll(mAppTokens); + } + if (wtoken == null || !mAppTokens.remove(wtoken)) { + Slog.w(TAG, "Attempting to reorder token that doesn't exist: " + + token + " (" + wtoken + ")"); + return; + } + mAppTokens.add(index, wtoken); + if (DEBUG_REORDER) Slog.v(TAG, "Moved " + token + " to " + index + ":"); + else if (DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "Moved " + token + " to " + index); + if (DEBUG_REORDER) dumpAppTokensLocked(); + if (!mAppTransition.isTransitionSet()) { + // Not animating, bring animating app list in line with mAppTokens. + mAnimatingAppTokens.clear(); + mAnimatingAppTokens.addAll(mAppTokens); + // Bring window ordering, window focus and input window in line with new app token + final long origId = Binder.clearCallingIdentity(); + if (DEBUG_REORDER) Slog.v(TAG, "Removing windows in " + token + ":"); + if (DEBUG_REORDER) dumpWindowsLocked(); + if (tmpRemoveAppWindowsLocked(wtoken)) { + if (DEBUG_REORDER) Slog.v(TAG, "Adding windows back in:"); + if (DEBUG_REORDER) dumpWindowsLocked(); + DisplayContentsIterator iterator = new DisplayContentsIterator(); + while(iterator.hasNext()) { + final DisplayContent displayContent = iterator.next(); + final WindowList windows = displayContent.getWindowList(); + final int pos = findWindowOffsetLocked(windows, index); + final int newPos = reAddAppWindowsLocked(displayContent, pos, wtoken); + if (pos != newPos) { + displayContent.layoutNeeded = true; + } + } + if (DEBUG_REORDER) Slog.v(TAG, "Final window list:"); + if (DEBUG_REORDER) dumpWindowsLocked(); + updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, + false /*updateInputWindows*/); + mInputMonitor.setUpdateInputWindowsNeededLw(); + performLayoutAndPlaceSurfacesLocked(); + mInputMonitor.updateInputWindowsLw(false /*force*/); + } + Binder.restoreCallingIdentity(origId); + } + } + } + + private void removeAppTokensLocked(List tokens) { + // XXX This should be done more efficiently! + // (take advantage of the fact that both lists should be + // ordered in the same way.) + int N = tokens.size(); + for (int i=0; i tokens, int tokenPos) { // First remove all of the windows from the list. - for (AppWindowToken wtoken : taskList.mAppTokens) { - tmpRemoveAppWindowsLocked(wtoken); + final int N = tokens.size(); + int i; + for (i=0; i tokens) { + if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, + "moveAppTokensToTop()")) { + throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } + + final long origId = Binder.clearCallingIdentity(); + synchronized(mWindowMap) { + removeAppTokensLocked(tokens); + final int N = tokens.size(); + for (int i=0; i tokens) { + if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, + "moveAppTokensToBottom()")) { + throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } + + final long origId = Binder.clearCallingIdentity(); + synchronized(mWindowMap) { + final int N = tokens.size(); + if (N > 0) { + // animating towards back, hang onto old list for duration of animation. + mAnimatingAppTokens.clear(); + mAnimatingAppTokens.addAll(mAppTokens); + } + removeAppTokensLocked(tokens); + int pos = 0; + for (int i=0; i 0) { + i--; + AppWindowToken tok = mAppTokens.get(i); if (tok.mAppAnimator.freezingScreen) { Slog.w(TAG, "Force clearing freeze: " + tok); unsetAppFreezingScreenLocked(tok, true, true); @@ -7307,7 +7408,6 @@ public class WindowManagerService extends IWindowManager.Stub performLayoutAndPlaceSurfacesLocked(); } - @Override public void setOverscan(int displayId, int left, int top, int right, int bottom) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.WRITE_SECURE_SETTINGS) != @@ -7426,16 +7526,15 @@ public class WindowManagerService extends IWindowManager.Stub // in the main app list, but still have windows shown. We put them // in the back because now that the animation is over we no longer // will care about them. - AppTokenList exitingAppTokens = displayContent.mExitingAppTokens; - int NT = exitingAppTokens.size(); + int NT = mExitingAppTokens.size(); for (int j=0; j= 0; i--) { + mAnimatingAppTokens.get(i).sendingToBottom = false; } + mAnimatingAppTokens.clear(); + mAnimatingAppTokens.addAll(mAppTokens); rebuildAppWindowListLocked(); changes |= PhoneWindowManager.FINISH_LAYOUT_REDO_LAYOUT; @@ -8266,12 +8365,13 @@ public class WindowManagerService extends IWindowManager.Stub } } - private void updateAllDrawnLocked(DisplayContent displayContent) { + private void updateAllDrawnLocked() { // See if any windows have been drawn, so they (and others // associated with them) can now be shown. - AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR); - while (iterator.hasNext()) { - AppWindowToken wtoken = iterator.next(); + final ArrayList appTokens = mAnimatingAppTokens; + final int NT = appTokens.size(); + for (int i=0; i 0 && wtoken.numDrawnWindows >= numInteresting) { @@ -8303,17 +8403,13 @@ public class WindowManagerService extends IWindowManager.Stub } // Initialize state of exiting tokens. - DisplayContentsIterator iterator = new DisplayContentsIterator(); - while (iterator.hasNext()) { - final DisplayContent displayContent = iterator.next(); - for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) { - displayContent.mExitingTokens.get(i).hasVisible = false; - } + for (i=mExitingTokens.size()-1; i>=0; i--) { + mExitingTokens.get(i).hasVisible = false; + } - // Initialize state of exiting applications. - for (i=displayContent.mExitingAppTokens.size()-1; i>=0; i--) { - displayContent.mExitingAppTokens.get(i).hasVisible = false; - } + // Initialize state of exiting applications. + for (i=mExitingAppTokens.size()-1; i>=0; i--) { + mExitingAppTokens.get(i).hasVisible = false; } mInnerFields.mHoldScreen = null; @@ -8342,10 +8438,10 @@ public class WindowManagerService extends IWindowManager.Stub } boolean focusDisplayed = false; + boolean updateAllDrawn = false; - iterator = new DisplayContentsIterator(); + DisplayContentsIterator iterator = new DisplayContentsIterator(); while (iterator.hasNext()) { - boolean updateAllDrawn = false; final DisplayContent displayContent = iterator.next(); WindowList windows = displayContent.getWindowList(); DisplayInfo displayInfo = displayContent.getDisplayInfo(); @@ -8589,10 +8685,10 @@ public class WindowManagerService extends IWindowManager.Stub if (!mInnerFields.mDimming && mAnimator.isDimmingLocked(displayId)) { stopDimmingLocked(displayId); } + } - if (updateAllDrawn) { - updateAllDrawnLocked(displayContent); - } + if (updateAllDrawn) { + updateAllDrawnLocked(); } if (focusDisplayed) { @@ -8739,35 +8835,30 @@ public class WindowManagerService extends IWindowManager.Stub } // Time to remove any exiting tokens? - iterator = new DisplayContentsIterator(); - while (iterator.hasNext()) { - final DisplayContent displayContent = iterator.next(); - ArrayList exitingTokens = displayContent.mExitingTokens; - for (i = exitingTokens.size() - 1; i >= 0; i--) { - WindowToken token = exitingTokens.get(i); - if (!token.hasVisible) { - exitingTokens.remove(i); - if (token.windowType == TYPE_WALLPAPER) { - mWallpaperTokens.remove(token); - } + for (i=mExitingTokens.size()-1; i>=0; i--) { + WindowToken token = mExitingTokens.get(i); + if (!token.hasVisible) { + mExitingTokens.remove(i); + if (token.windowType == TYPE_WALLPAPER) { + mWallpaperTokens.remove(token); } } + } - // Time to remove any exiting applications? - AppTokenList exitingAppTokens = displayContent.mExitingAppTokens; - for (i = exitingAppTokens.size() - 1; i >= 0; i--) { - AppWindowToken token = exitingAppTokens.get(i); - if (!token.hasVisible && !mClosingApps.contains(token)) { - // Make sure there is no animation running on this token, - // so any windows associated with it will be removed as - // soon as their animations are complete - token.mAppAnimator.clearAnimation(); - token.mAppAnimator.animating = false; - if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, - "performLayout: App token exiting now removed" + token); - displayContent.removeAppToken(token); - exitingAppTokens.remove(i); - } + // Time to remove any exiting applications? + for (i=mExitingAppTokens.size()-1; i>=0; i--) { + AppWindowToken token = mExitingAppTokens.get(i); + if (!token.hasVisible && !mClosingApps.contains(token)) { + // Make sure there is no animation running on this token, + // so any windows associated with it will be removed as + // soon as their animations are complete + token.mAppAnimator.clearAnimation(); + token.mAppAnimator.animating = false; + if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, + "performLayout: App token exiting now removed" + token); + mAppTokens.remove(token); + mAnimatingAppTokens.remove(token); + mExitingAppTokens.remove(i); } } @@ -8787,7 +8878,7 @@ public class WindowManagerService extends IWindowManager.Stub defaultDisplay.layoutNeeded = true; } - iterator = new DisplayContentsIterator(); + DisplayContentsIterator iterator = new DisplayContentsIterator(); while (iterator.hasNext()) { DisplayContent displayContent = iterator.next(); if (displayContent.pendingLayoutChanges != 0) { @@ -9038,10 +9129,10 @@ public class WindowManagerService extends IWindowManager.Stub // window list to make sure we haven't left any dangling surfaces // around. - mTmpWindowsIterator.reset(FORWARD_ITERATOR); + AllWindowsIterator iterator = new AllWindowsIterator(); Slog.i(TAG, "Out of memory for surface! Looking for leaks..."); - while (mTmpWindowsIterator.hasNext()) { - WindowState ws = mTmpWindowsIterator.next(); + while (iterator.hasNext()) { + WindowState ws = iterator.next(); WindowStateAnimator wsa = ws.mWinAnimator; if (wsa.mSurfaceControl != null) { if (!mSessions.contains(wsa.mSession)) { @@ -9074,9 +9165,9 @@ public class WindowManagerService extends IWindowManager.Stub if (!leakedSurface) { Slog.w(TAG, "No leaked surfaces; killing applicatons!"); SparseIntArray pidCandidates = new SparseIntArray(); - mTmpWindowsIterator.reset(FORWARD_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - WindowState ws = mTmpWindowsIterator.next(); + iterator = new AllWindowsIterator(); + while (iterator.hasNext()) { + WindowState ws = iterator.next(); if (mForceRemoves.contains(ws)) { continue; } @@ -9202,8 +9293,8 @@ public class WindowManagerService extends IWindowManager.Stub } private WindowState findFocusedWindowLocked(DisplayContent displayContent) { - AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR); - WindowToken nextApp = iterator.hasNext() ? iterator.next() : null; + int nextAppIndex = mAppTokens.size()-1; + WindowToken nextApp = nextAppIndex >= 0 ? mAppTokens.get(nextAppIndex) : null; final WindowList windows = displayContent.getWindowList(); for (int i = windows.size() - 1; i >= 0; i--) { @@ -9229,8 +9320,8 @@ public class WindowManagerService extends IWindowManager.Stub // through the app tokens until we find its app. if (thisApp != null && nextApp != null && thisApp != nextApp && win.mAttrs.type != TYPE_APPLICATION_STARTING) { - final WindowToken origAppToken = nextApp; - while (iterator.hasNext()) { + int origAppIndex = nextAppIndex; + while (nextAppIndex > 0) { if (nextApp == mFocusedApp) { // Whoops, we are below the focused app... no focus // for you! @@ -9238,7 +9329,8 @@ public class WindowManagerService extends IWindowManager.Stub TAG, "Reached focused app: " + mFocusedApp); return null; } - nextApp = iterator.next(); + nextAppIndex--; + nextApp = mAppTokens.get(nextAppIndex); if (nextApp == thisApp) { break; } @@ -9247,14 +9339,8 @@ public class WindowManagerService extends IWindowManager.Stub // Uh oh, the app token doesn't exist! This shouldn't // happen, but if it does we can get totally hosed... // so restart at the original app. - nextApp = origAppToken; - iterator = displayContent.new AppTokenIterator(true); - while (iterator.hasNext()) { - // return iterator to same place. - if (iterator.next() == origAppToken) { - break; - } - } + nextAppIndex = origAppIndex; + nextApp = mAppTokens.get(nextAppIndex); } } @@ -9624,6 +9710,15 @@ public class WindowManagerService extends IWindowManager.Stub } } } + if (mAppTokens.size() > 0) { + pw.println(); + pw.println(" Application tokens in Z order:"); + for (int i=mAppTokens.size()-1; i>=0; i--) { + pw.print(" App #"); pw.print(i); + pw.print(' '); pw.print(mAppTokens.get(i)); pw.println(":"); + mAppTokens.get(i).dump(pw, " "); + } + } if (mFinishedStarting.size() > 0) { pw.println(); pw.println(" Finishing start of application tokens:"); @@ -9639,6 +9734,51 @@ public class WindowManagerService extends IWindowManager.Stub } } } + if (mExitingTokens.size() > 0) { + pw.println(); + pw.println(" Exiting tokens:"); + for (int i=mExitingTokens.size()-1; i>=0; i--) { + WindowToken token = mExitingTokens.get(i); + pw.print(" Exiting #"); pw.print(i); + pw.print(' '); pw.print(token); + if (dumpAll) { + pw.println(':'); + token.dump(pw, " "); + } else { + pw.println(); + } + } + } + if (mExitingAppTokens.size() > 0) { + pw.println(); + pw.println(" Exiting application tokens:"); + for (int i=mExitingAppTokens.size()-1; i>=0; i--) { + WindowToken token = mExitingAppTokens.get(i); + pw.print(" Exiting App #"); pw.print(i); + pw.print(' '); pw.print(token); + if (dumpAll) { + pw.println(':'); + token.dump(pw, " "); + } else { + pw.println(); + } + } + } + if (mAppTransition.isRunning() && mAnimatingAppTokens.size() > 0) { + pw.println(); + pw.println(" Application tokens during animation:"); + for (int i=mAnimatingAppTokens.size()-1; i>=0; i--) { + WindowToken token = mAnimatingAppTokens.get(i); + pw.print(" App moving to bottom #"); pw.print(i); + pw.print(' '); pw.print(token); + if (dumpAll) { + pw.println(':'); + token.dump(pw, " "); + } else { + pw.println(); + } + } + } if (mOpeningApps.size() > 0 || mClosingApps.size() > 0) { pw.println(); if (mOpeningApps.size() > 0) { @@ -9683,9 +9823,9 @@ public class WindowManagerService extends IWindowManager.Stub void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll, ArrayList windows) { int j = 0; - mTmpWindowsIterator.reset(REVERSE_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - final WindowState w = mTmpWindowsIterator.next(); + final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); + while (iterator.hasNext()) { + final WindowState w = iterator.next(); if (windows == null || windows.contains(w)) { pw.print(" Window #"); pw.print(j++); pw.print(' '); pw.print(w); pw.println(":"); @@ -9871,9 +10011,9 @@ public class WindowManagerService extends IWindowManager.Stub WindowList windows = new WindowList(); if ("visible".equals(name)) { synchronized(mWindowMap) { - mTmpWindowsIterator.reset(REVERSE_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - final WindowState w = mTmpWindowsIterator.next(); + final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); + while (iterator.hasNext()) { + final WindowState w = iterator.next(); if (w.mWinAnimator.mSurfaceShown) { windows.add(w); } @@ -9888,9 +10028,9 @@ public class WindowManagerService extends IWindowManager.Stub } catch (RuntimeException e) { } synchronized(mWindowMap) { - mTmpWindowsIterator.reset(REVERSE_ITERATOR); - while (mTmpWindowsIterator.hasNext()) { - final WindowState w = mTmpWindowsIterator.next(); + final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); + while (iterator.hasNext()) { + final WindowState w = iterator.next(); if (name != null) { if (w.mAttrs.getTitle().toString().contains(name)) { windows.add(w); @@ -10143,10 +10283,6 @@ public class WindowManagerService extends IWindowManager.Stub class DisplayContentsIterator implements Iterator { private int cur; - void reset() { - cur = 0; - } - @Override public boolean hasNext() { return cur < mDisplayContents.size(); @@ -10166,6 +10302,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + final static boolean REVERSE_ITERATOR = true; class AllWindowsIterator implements Iterator { private DisplayContent mDisplayContent; private DisplayContentsIterator mDisplayContentsIterator; @@ -10174,33 +10311,19 @@ public class WindowManagerService extends IWindowManager.Stub private boolean mReverse; AllWindowsIterator() { - this(false); + mDisplayContentsIterator = new DisplayContentsIterator(); + mDisplayContent = mDisplayContentsIterator.next(); + mWindowList = mDisplayContent.getWindowList(); } AllWindowsIterator(boolean reverse) { - mDisplayContentsIterator = new DisplayContentsIterator(); - reset(reverse); - } - - void reset(boolean reverse) { + this(); mReverse = reverse; - mDisplayContentsIterator.reset(); - if (mDisplayContentsIterator.hasNext()) { - mDisplayContent = mDisplayContentsIterator.next(); - mWindowList = mDisplayContent.getWindowList(); - mWindowListIndex = reverse ? mWindowList.size() - 1 : 0; - } else { - mDisplayContent = null; - mWindowList = null; - mWindowListIndex = 0; - } + mWindowListIndex = reverse ? mWindowList.size() - 1 : 0; } @Override public boolean hasNext() { - if (mDisplayContent == null) { - return false; - } if (mReverse) { return mWindowListIndex >= 0; } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 517c4e414ada3..a60062345cd9d 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -52,12 +52,6 @@ import java.io.PrintWriter; import java.util.ArrayList; class WindowList extends ArrayList { - WindowList() { - super(); - } - WindowList(WindowList windows) { - super(windows); - } } /** @@ -1092,7 +1086,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { return true; } - public void setAppOpVisibilityLw(boolean state) { + public boolean setAppOpVisibilityLw(boolean state) { if (mAppOpVisibility != state) { mAppOpVisibility = state; if (state) { @@ -1102,11 +1096,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { // ops modifies they should only be hidden by policy due to the // lock screen, and the user won't be changing this if locked. // Plus it will quickly be fixed the next time we do a layout. - showLw(true, true); + showLw(true, false); } else { - hideLw(true, true); + hideLw(true, false); } + return true; } + return false; } @Override diff --git a/services/java/com/android/server/wm/WindowToken.java b/services/java/com/android/server/wm/WindowToken.java index 22671234c5384..bd0ace89e49d1 100644 --- a/services/java/com/android/server/wm/WindowToken.java +++ b/services/java/com/android/server/wm/WindowToken.java @@ -19,6 +19,7 @@ package com.android.server.wm; import android.os.IBinder; import java.io.PrintWriter; +import java.util.ArrayList; /** * Container of a set of related windows in the window manager. Often this diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index 03871f63db201..746ac06223008 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -222,7 +222,37 @@ public class WindowManagerPermissionTests extends TestCase { } catch (RemoteException e) { fail("Unexpected remote exception"); } - } + + try { + mWm.moveAppToken(0, null); + fail("IWindowManager.moveAppToken did not throw SecurityException as" + + " expected"); + } catch (SecurityException e) { + // expected + } catch (RemoteException e) { + fail("Unexpected remote exception"); + } + + try { + mWm.moveAppTokensToTop(null); + fail("IWindowManager.moveAppTokensToTop did not throw SecurityException as" + + " expected"); + } catch (SecurityException e) { + // expected + } catch (RemoteException e) { + fail("Unexpected remote exception"); + } + + try { + mWm.moveAppTokensToBottom(null); + fail("IWindowManager.moveAppTokensToBottom did not throw SecurityException as" + + " expected"); + } catch (SecurityException e) { + // expected + } catch (RemoteException e) { + fail("Unexpected remote exception"); + } + } @SmallTest public void testDISABLE_KEYGUARD() { diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 278413e4395e6..59ae1a1d48175 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -209,6 +209,24 @@ public class IWindowManagerImpl implements IWindowManager { return false; } + @Override + public void moveAppToken(int arg0, IBinder arg1) throws RemoteException { + // TODO Auto-generated method stub + + } + + @Override + public void moveAppTokensToBottom(List arg0) throws RemoteException { + // TODO Auto-generated method stub + + } + + @Override + public void moveAppTokensToTop(List arg0) throws RemoteException { + // TODO Auto-generated method stub + + } + @Override public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1) throws RemoteException {