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
This commit is contained in:
Craig Mautner
2013-02-25 16:19:24 -08:00
parent ff4fcdb98c
commit 2ad920759b
17 changed files with 1031 additions and 1615 deletions

View File

@@ -99,6 +99,9 @@ interface IWindowManager
void startAppFreezingScreen(IBinder token, int configChanges);
void stopAppFreezingScreen(IBinder token, boolean force);
void removeAppToken(IBinder token);
void moveAppToken(int index, IBinder token);
void moveAppTokensToTop(in List<IBinder> tokens);
void moveAppTokensToBottom(in List<IBinder> tokens);
// Re-evaluate the current orientation from the caller's state.
// If there is a change, the new Configuration is returned and the

View File

@@ -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<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
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<PendingThumbnailsRecord> mPendingThumbnails =
new ArrayList<PendingThumbnailsRecord>();
final ArrayList mPendingThumbnails = new ArrayList();
/**
* List of HistoryRecord objects that have been finished and must
* still report back to a pending thumbnail receiver.
*/
final ArrayList mCancelledThumbnails = new ArrayList();
final ProviderMap mProviderMap;
@@ -2838,8 +2842,11 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<activities.size(); i++) {
ActivityRecord r = activities.get(i);
if (!r.finishing) {
mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
null, "finish-heavy", true);
int index = mMainStack.indexOfTokenLocked(r.appToken);
if (index >= 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<mMainStack.mHistory.size(); i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
final boolean samePackage = r.packageName.equals(name)
|| (name == null && r.userId == userId);
if ((userId == UserHandle.USER_ALL || r.userId == userId)
&& (samePackage || r.task == lastTask)
&& (r.app == null || evenPersistent || !r.app.persistent)) {
if (!doit) {
if (r.finishing) {
// If this activity is just finishing, then it is not
// interesting as far as something to stop.
continue;
}
return true;
}
didSomething = true;
Slog.i(TAG, " Force finishing activity " + r);
if (samePackage) {
if (r.app != null) {
r.app.removed = true;
}
r.app = null;
}
lastTask = r.task;
if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
null, "force-stop", true)) {
i--;
}
}
didSomething = true;
}
if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
@@ -5623,12 +5670,12 @@ public final class ActivityManagerService extends ActivityManagerNative
// TASK MANAGEMENT
// =========================================================
@Override
public List<RunningTaskInfo> getTasks(int maxNum, int flags,
public List getTasks(int maxNum, int flags,
IThumbnailReceiver receiver) {
ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
ArrayList list = new ArrayList();
PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver);
PendingThumbnailsRecord pending = null;
IApplicationThread topThumbnail = null;
ActivityRecord topRecord = null;
synchronized(this) {
@@ -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<N; j++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
if (r.task != jt) {
if (affinity.equals(jt.affinity)) {
return j;
}
jt = r.task;
}
}
// Might it be at the top?
if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
return N-1;
}
return -1;
}
/**
* TODO: Add mController hook
*/
@@ -5929,8 +6082,20 @@ public final class ActivityManagerService extends ActivityManagerNative
mMainStack.moveTaskToFrontLocked(tr, null, options);
return;
}
if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) {
return;
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
if (hr.task.taskId == task) {
if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
mMainStack.mUserLeaving = true;
}
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
mMainStack.moveHomeToFrontLocked();
}
mMainStack.moveTaskToFrontLocked(hr.task, null, options);
return;
}
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -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<N; i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.appToken == token) {
if (!onlyRoot || lastTask != r.task) {
return r.task.taskId;
}
return -1;
}
lastTask = r.task;
}
return -1;
}
// =========================================================
// THUMBNAILS
// =========================================================
@@ -6909,10 +7091,13 @@ public final class ActivityManagerService extends ActivityManagerNative
"unhandledBack()");
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
try {
mMainStack.unhandledBackLocked();
} finally {
int count = mMainStack.mHistory.size();
if (DEBUG_SWITCH) Slog.d(
TAG, "Performing unhandledBack(): stack size = " + count);
if (count > 1) {
final long origId = Binder.clearCallingIdentity();
mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
Binder.restoreCallingIdentity(origId);
}
}
@@ -7974,7 +8159,15 @@ public final class ActivityManagerService extends ActivityManagerNative
+ " has crashed too many times: killing!");
EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
app.userId, app.info.processName, app.uid);
mMainStack.handleAppCrashLocked(app);
for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.app == app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
null, "crashed", false);
}
}
if (!app.persistent) {
// We don't want to start this process again until the user
// explicitly does so... but for persistent process, we really
@@ -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<ActivityRecord> activities;
synchronized (this) {
activities = mMainStack.getDumpActivitiesLocked(name);
ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
if ("all".equals(name)) {
synchronized (this) {
for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
activities.add(r1);
}
}
} else if ("top".equals(name)) {
synchronized (this) {
final int N = mMainStack.mHistory.size();
if (N > 0) {
activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
}
}
} else {
ItemMatcher matcher = new ItemMatcher();
matcher.build(name);
synchronized (this) {
for (ActivityRecord r1 : (ArrayList<ActivityRecord>)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<ActivityRecord> history = srec.stack.mHistory;
final int start = history.indexOf(srec);
if (start < 0) {
// Current activity is not in history stack; do nothing.
return false;
}
int finishTo = start - 1;
ActivityRecord parent = null;
boolean foundParentInTask = false;
if (dest != null) {
TaskRecord tr = srec.task;
for (int i = start - 1; i >= 0; i--) {
ActivityRecord r = history.get(i);
if (tr != r.task) {
// Couldn't find parent in the same task; stop at the one above this.
// (Root of current task; in-app "home" behavior)
// Always at least finish the current activity.
finishTo = Math.min(start - 1, i + 1);
parent = history.get(finishTo);
break;
} else if (r.info.packageName.equals(dest.getPackageName()) &&
r.info.name.equals(dest.getClassName())) {
finishTo = i;
parent = r;
foundParentInTask = true;
break;
}
}
}
if (mController != null) {
ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
mController = null;
}
if (!resumeOK) {
return false;
}
}
}
final long origId = Binder.clearCallingIdentity();
for (int i = start; i > finishTo; i--) {
ActivityRecord r = history.get(i);
mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
"navigate-up", true);
// Only return the supplied result for the first activity finished
resultCode = Activity.RESULT_CANCELED;
resultData = null;
}
if (parent != null && foundParentInTask) {
final int parentLaunchMode = parent.info.launchMode;
final int destIntentFlags = destIntent.getFlags();
if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
(destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
destIntent.getComponent(), 0, srec.userId);
int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
null, aInfo, parent.appToken, null,
0, -1, parent.launchedFromUid, parent.launchedFromPackage,
0, null, true, null);
foundParentInTask = res == ActivityManager.START_SUCCESS;
} catch (RemoteException e) {
foundParentInTask = false;
}
mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
resultData, "navigate-up", true);
}
}
Binder.restoreCallingIdentity(origId);
return foundParentInTask;
}
}

View File

@@ -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<ResultInfo> results; // pending ActivityResult objs we have received
ArrayList results; // pending ActivityResult objs we have received
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
ArrayList<Intent> 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<ConnectionRecord> 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<ResultInfo>();
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(' ');

File diff suppressed because it is too large Load Diff

View File

@@ -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--) {

View File

@@ -27,13 +27,13 @@ import java.util.HashSet;
class PendingThumbnailsRecord
{
final IThumbnailReceiver receiver; // who is waiting.
final HashSet<ActivityRecord> 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<ActivityRecord>();
pendingRecords = new HashSet();
finished = false;
}
}

View File

@@ -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<ActivityRecord> mActivities = new ArrayList<ActivityRecord>();
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();
}

View File

@@ -30,10 +30,6 @@ import android.view.View;
import android.view.WindowManager;
import java.io.PrintWriter;
import java.util.ArrayList;
class AppTokenList extends ArrayList<AppWindowToken> {
}
/**
* Version of WindowToken that is specifically for a particular application (or

View File

@@ -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<DisplayContent> {
}
@@ -39,7 +33,6 @@ class DisplayContentList extends ArrayList<DisplayContent> {
* 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<WindowToken> mExitingTokens = new ArrayList<WindowToken>();
/**
* 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<TaskList> mTaskLists = new ArrayList<TaskList>();
SparseArray<TaskList> mTaskIdToTaskList = new SparseArray<TaskList>();
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<AppWindowToken> {
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();
}
}

View File

@@ -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<IApplicationToken> tokens = new ArrayList<IApplicationToken>();
@Override
public String toString() {
return "id=" + taskId + " tokens=" + tokens;
}
}

View File

@@ -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;
}
}

View File

@@ -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<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
final int NAT = appTokens.size();
for (i=0; i<NAT; i++) {
final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != AppWindowAnimator.sDummyAnimation;
if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -194,10 +191,9 @@ public class WindowAnimator {
}
}
final AppTokenList exitingAppTokens = displayContent.mExitingAppTokens;
final int NEAT = exitingAppTokens.size();
final int NEAT = mService.mExitingAppTokens.size();
for (i=0; i<NEAT; i++) {
final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
final AppWindowAnimator appAnimator = mService.mExitingAppTokens.get(i).mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
&& appAnimator.animation != AppWindowAnimator.sDummyAnimation;
if (appAnimator.stepAnimationLocked(mCurrentTime)) {
@@ -458,13 +454,13 @@ public class WindowAnimator {
/** See if any windows have been drawn, so they (and others associated with them) can now be
* shown. */
private void testTokenMayBeDrawnLocked(int displayId) {
private void testTokenMayBeDrawnLocked() {
// See if any windows have been drawn, so they (and others
// associated with them) can now be shown.
AppTokenIterator iterator =
mService.getDisplayContentLocked(displayId).getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken wtoken = iterator.next();
final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens;
final int NT = appTokens.size();
for (int i=0; i<NT; i++) {
AppWindowToken wtoken = appTokens.get(i);
AppWindowAnimator appAnimator = wtoken.mAppAnimator;
final boolean allDrawn = wtoken.allDrawn;
if (allDrawn != appAnimator.allDrawn) {
@@ -534,10 +530,11 @@ public class WindowAnimator {
SurfaceControl.openTransaction();
SurfaceControl.setAnimationTransaction();
try {
updateAppWindowsLocked();
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
updateAppWindowsLocked(displayId);
DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
final ScreenRotationAnimation screenRotationAnimation =
@@ -563,11 +560,10 @@ public class WindowAnimator {
}
}
testTokenMayBeDrawnLocked();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
testTokenMayBeDrawnLocked(displayId);
DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
final ScreenRotationAnimation screenRotationAnimation =

File diff suppressed because it is too large Load Diff

View File

@@ -52,12 +52,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
class WindowList extends ArrayList<WindowState> {
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

View File

@@ -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

View File

@@ -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() {

View File

@@ -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<IBinder> arg0) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public void moveAppTokensToTop(List<IBinder> arg0) throws RemoteException {
// TODO Auto-generated method stub
}
@Override
public IWindowSession openSession(IInputMethodClient arg0, IInputContext arg1)
throws RemoteException {