summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-11-11 16:16:31 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-11-11 16:16:31 -0800
commit1093c9acc57af7d9805ddcd50f6f3da024b4ed3a (patch)
tree02654af15d9d27132df40eba1147feade86a5c95 /services
parent5043441c4f3f0bd28834796838011eb48ccaec96 (diff)
parent7ddf38a5bf833f90057b0795dd9af6c61d3cf2d5 (diff)
downloadframeworks_base-1093c9acc57af7d9805ddcd50f6f3da024b4ed3a.zip
frameworks_base-1093c9acc57af7d9805ddcd50f6f3da024b4ed3a.tar.gz
frameworks_base-1093c9acc57af7d9805ddcd50f6f3da024b4ed3a.tar.bz2
am 7ddf38a5: am be70785f: Make activity manager more robust in the face of app activity leaks.
* commit '7ddf38a5bf833f90057b0795dd9af6c61d3cf2d5': Make activity manager more robust in the face of app activity leaks.
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java37
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java81
-rw-r--r--services/java/com/android/server/am/ActivityStack.java197
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java2
4 files changed, 198 insertions, 119 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 05d42ad..cd63090 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1669,7 +1669,7 @@ public final class ActivityManagerService extends ActivityManagerNative
final void setFocusedActivityLocked(ActivityRecord r) {
if (mFocusedActivity != r) {
mFocusedActivity = r;
- mWindowManager.setFocusedApp(r, true);
+ mWindowManager.setFocusedApp(r.appToken, true);
}
}
@@ -2346,7 +2346,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// XXX we are not dealing with propagating grantedUriPermissions...
// those are not yet exposed to user code, so there is no need.
int res = mMainStack.startActivityLocked(r.app.thread, intent,
- r.resolvedType, null, 0, aInfo, resultTo, resultWho,
+ r.resolvedType, null, 0, aInfo,
+ resultTo != null ? resultTo.appToken : null, resultWho,
requestCode, -1, r.launchedFromUid, false, false, null);
Binder.restoreCallingIdentity(origId);
@@ -2429,10 +2430,10 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
final long origId = Binder.clearCallingIdentity();
- mWindowManager.setAppOrientation(r, requestedOrientation);
+ mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mConfiguration,
- r.mayFreezeScreenLocked(r.app) ? r : null);
+ r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
if (config != null) {
r.frozenBeforeDestroy = true;
if (!updateConfigurationLocked(config, r, false)) {
@@ -2449,7 +2450,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (r == null) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
- return mWindowManager.getAppOrientation(r);
+ return mWindowManager.getAppOrientation(r.appToken);
}
}
@@ -2515,7 +2516,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<activities.size(); i++) {
ActivityRecord r = activities.get(i);
if (!r.finishing) {
- int index = mMainStack.indexOfTokenLocked(r);
+ int index = mMainStack.indexOfTokenLocked(r.appToken);
if (index >= 0) {
mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
null, "finish-heavy");
@@ -2617,7 +2618,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int i;
for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
- if (r == token) {
+ if (r.appToken == token) {
return true;
}
if (r.fullscreen && !r.finishing) {
@@ -2705,9 +2706,9 @@ public final class ActivityManagerService extends ActivityManagerNative
r.makeFinishing();
mMainStack.mHistory.remove(i);
r.takeFromHistory();
- mWindowManager.removeAppToken(r);
+ mWindowManager.removeAppToken(r.appToken);
if (VALIDATE_TOKENS) {
- mWindowManager.validateAppTokens(mMainStack.mHistory);
+ mMainStack.validateAppTokensLocked();
}
r.removeUriPermissionsLocked();
@@ -5173,10 +5174,10 @@ public final class ActivityManagerService extends ActivityManagerNative
if (topThumbnail != null) {
if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
try {
- topThumbnail.requestThumbnail(topRecord);
+ topThumbnail.requestThumbnail(topRecord.appToken);
} catch (Exception e) {
Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
- sendPendingThumbnail(null, topRecord, null, null, true);
+ sendPendingThumbnail(null, topRecord.appToken, null, null, true);
}
}
@@ -5547,7 +5548,7 @@ public final class ActivityManagerService extends ActivityManagerNative
TaskRecord lastTask = null;
for (int i=0; i<N; i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
- if (r == token) {
+ if (r.appToken == token) {
if (!onlyRoot || lastTask != r.task) {
return r.task.taskId;
}
@@ -5568,7 +5569,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<N; i++) {
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
if (r.realActivity.equals(className)
- && r != token && lastTask != r.task) {
+ && r.appToken != token && lastTask != r.task) {
if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
null, "others")) {
i--;
@@ -7112,7 +7113,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// process, then terminate it to avoid getting in a loop.
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
- int index = mMainStack.indexOfTokenLocked(r);
+ int index = mMainStack.indexOfActivityLocked(r);
r.stack.finishActivityLocked(r, index,
Activity.RESULT_CANCELED, null, "crashed");
// Also terminate any activities below it that aren't yet
@@ -8631,8 +8632,8 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
TransferPipe tp = new TransferPipe();
try {
- r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
- innerPrefix, args);
+ r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
+ r.appToken, innerPrefix, args);
tp.go(fd);
} finally {
tp.kill();
@@ -9048,8 +9049,8 @@ public final class ActivityManagerService extends ActivityManagerNative
try {
TransferPipe tp = new TransferPipe();
try {
- r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
- innerPrefix, args);
+ r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
+ r.appToken, innerPrefix, args);
// Short timeout, since blocking here can
// deadlock with the application.
tp.go(fd, 2000);
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 00e6cb2..951a946 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -29,6 +29,7 @@ import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -48,9 +49,10 @@ import java.util.HashSet;
/**
* An entry in the history stack, representing an activity.
*/
-final class ActivityRecord extends IApplicationToken.Stub {
+final class ActivityRecord {
final ActivityManagerService service; // owner
final ActivityStack stack; // owner
+ final IApplicationToken.Stub appToken; // window manager token
final ActivityInfo info; // all about me
final int launchedFromUid; // always the uid who started the activity.
final Intent intent; // the original intent that generated us
@@ -200,6 +202,70 @@ final class ActivityRecord extends IApplicationToken.Stub {
}
}
+ static class Token extends IApplicationToken.Stub {
+ final WeakReference<ActivityRecord> weakActivity;
+
+ Token(ActivityRecord activity) {
+ weakActivity = new WeakReference<ActivityRecord>(activity);
+ }
+
+ @Override public void windowsDrawn() throws RemoteException {
+ ActivityRecord activity = weakActivity.get();
+ if (activity != null) {
+ activity.windowsDrawn();
+ }
+ }
+
+ @Override public void windowsVisible() throws RemoteException {
+ ActivityRecord activity = weakActivity.get();
+ if (activity != null) {
+ activity.windowsVisible();
+ }
+ }
+
+ @Override public void windowsGone() throws RemoteException {
+ ActivityRecord activity = weakActivity.get();
+ if (activity != null) {
+ activity.windowsGone();
+ }
+ }
+
+ @Override public boolean keyDispatchingTimedOut() throws RemoteException {
+ ActivityRecord activity = weakActivity.get();
+ if (activity != null) {
+ return activity.keyDispatchingTimedOut();
+ }
+ return false;
+ }
+
+ @Override public long getKeyDispatchingTimeout() throws RemoteException {
+ ActivityRecord activity = weakActivity.get();
+ if (activity != null) {
+ return activity.getKeyDispatchingTimeout();
+ }
+ return 0;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("Token{");
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
+ sb.append(' ');
+ sb.append(weakActivity.get());
+ sb.append('}');
+ return sb.toString();
+ }
+ }
+
+ static ActivityRecord forToken(IBinder token) {
+ try {
+ return token != null ? ((Token)token).weakActivity.get() : null;
+ } catch (ClassCastException e) {
+ Slog.w(ActivityManagerService.TAG, "Bad activity token: " + token, e);
+ return null;
+ }
+ }
+
ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
int _launchedFromUid, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration,
@@ -207,6 +273,7 @@ final class ActivityRecord extends IApplicationToken.Stub {
boolean _componentSpecified) {
service = _service;
stack = _stack;
+ appToken = new Token(this);
info = aInfo;
launchedFromUid = _launchedFromUid;
intent = _intent;
@@ -445,7 +512,7 @@ final class ActivityRecord extends IApplicationToken.Stub {
ar.add(intent);
service.grantUriPermissionFromIntentLocked(callingUid, packageName,
intent, getUriPermissionsLocked());
- app.thread.scheduleNewIntent(ar, this);
+ app.thread.scheduleNewIntent(ar, appToken);
sent = true;
} catch (RemoteException e) {
Slog.w(ActivityManagerService.TAG,
@@ -470,14 +537,14 @@ final class ActivityRecord extends IApplicationToken.Stub {
void pauseKeyDispatchingLocked() {
if (!keysPaused) {
keysPaused = true;
- service.mWindowManager.pauseKeyDispatching(this);
+ service.mWindowManager.pauseKeyDispatching(appToken);
}
}
void resumeKeyDispatchingLocked() {
if (keysPaused) {
keysPaused = false;
- service.mWindowManager.resumeKeyDispatching(this);
+ service.mWindowManager.resumeKeyDispatching(appToken);
}
}
@@ -512,14 +579,14 @@ final class ActivityRecord extends IApplicationToken.Stub {
public void startFreezingScreenLocked(ProcessRecord app, int configChanges) {
if (mayFreezeScreenLocked(app)) {
- service.mWindowManager.startAppFreezingScreen(this, configChanges);
+ service.mWindowManager.startAppFreezingScreen(appToken, configChanges);
}
}
public void stopFreezingScreenLocked(boolean force) {
if (force || frozenBeforeDestroy) {
frozenBeforeDestroy = false;
- service.mWindowManager.stopAppFreezingScreen(this, force);
+ service.mWindowManager.stopAppFreezingScreen(appToken, force);
}
}
@@ -687,7 +754,7 @@ final class ActivityRecord extends IApplicationToken.Stub {
}
if (app != null && app.thread != null) {
try {
- app.thread.scheduleSleeping(this, _sleeping);
+ app.thread.scheduleSleeping(appToken, _sleeping);
if (sleeping && !stack.mGoingToSleepActivities.contains(this)) {
stack.mGoingToSleepActivities.add(this);
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 8435eaa..c892cb1 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -145,7 +145,12 @@ final class ActivityStack {
* running) activities. It contains HistoryRecord objects.
*/
final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();
-
+
+ /**
+ * Used for validating app tokens with window manager.
+ */
+ final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>();
+
/**
* List of running activities, sorted by recent usage.
* The first entry in the list is the least recently used.
@@ -294,11 +299,11 @@ final class ActivityStack {
}
} break;
case PAUSE_TIMEOUT_MSG: {
- IBinder token = (IBinder)msg.obj;
+ ActivityRecord r = (ActivityRecord)msg.obj;
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
- Slog.w(TAG, "Activity pause timeout for " + token);
- activityPaused(token, true);
+ Slog.w(TAG, "Activity pause timeout for " + r);
+ activityPaused(r != null ? r.appToken : null, true);
} break;
case IDLE_TIMEOUT_MSG: {
if (mService.mDidDexOpt) {
@@ -310,20 +315,20 @@ final class ActivityStack {
}
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
- IBinder token = (IBinder)msg.obj;
- Slog.w(TAG, "Activity idle timeout for " + token);
- activityIdleInternal(token, true, null);
+ ActivityRecord r = (ActivityRecord)msg.obj;
+ Slog.w(TAG, "Activity idle timeout for " + r);
+ activityIdleInternal(r != null ? r.appToken : null, true, null);
} break;
case DESTROY_TIMEOUT_MSG: {
- IBinder token = (IBinder)msg.obj;
+ ActivityRecord r = (ActivityRecord)msg.obj;
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
- Slog.w(TAG, "Activity destroy timeout for " + token);
- activityDestroyed(token);
+ Slog.w(TAG, "Activity destroy timeout for " + r);
+ activityDestroyed(r != null ? r.appToken : null);
} break;
case IDLE_NOW_MSG: {
- IBinder token = (IBinder)msg.obj;
- activityIdleInternal(token, false, null);
+ ActivityRecord r = (ActivityRecord)msg.obj;
+ activityIdleInternal(r != null ? r.appToken : null, false, null);
} break;
case LAUNCH_TIMEOUT_MSG: {
if (mService.mDidDexOpt) {
@@ -397,7 +402,7 @@ final class ActivityStack {
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) && (taskId != r.task.taskId)) {
+ if (!r.finishing && (token != r.appToken) && (taskId != r.task.taskId)) {
return r;
}
i--;
@@ -406,23 +411,17 @@ final class ActivityStack {
}
final int indexOfTokenLocked(IBinder token) {
- try {
- ActivityRecord r = (ActivityRecord)token;
- return mHistory.indexOf(r);
- } catch (ClassCastException e) {
- Slog.w(TAG, "Bad activity token: " + token, e);
- return -1;
- }
+ return mHistory.indexOf(ActivityRecord.forToken(token));
+ }
+
+ final int indexOfActivityLocked(ActivityRecord r) {
+ return mHistory.indexOf(r);
}
final ActivityRecord isInStackLocked(IBinder token) {
- try {
- ActivityRecord r = (ActivityRecord)token;
- if (mHistory.contains(r)) {
- return r;
- }
- } catch (ClassCastException e) {
- Slog.w(TAG, "Bad activity token: " + token, e);
+ ActivityRecord r = ActivityRecord.forToken(token);
+ if (mHistory.contains(r)) {
+ return r;
}
return null;
}
@@ -517,7 +516,7 @@ final class ActivityStack {
throws RemoteException {
r.startFreezingScreenLocked(app, 0);
- mService.mWindowManager.setAppVisibility(r, true);
+ mService.mWindowManager.setAppVisibility(r.appToken, true);
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order. Note that
@@ -528,7 +527,7 @@ final class ActivityStack {
if (checkConfig) {
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
- r.mayFreezeScreenLocked(app) ? r : null);
+ r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false);
}
@@ -590,7 +589,7 @@ final class ActivityStack {
profileFd = null;
}
}
- app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
+ app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, mService.mConfiguration,
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
@@ -624,7 +623,7 @@ final class ActivityStack {
+ r.intent.getComponent().flattenToShortString()
+ ", giving up", e);
mService.appDiedLocked(app, app.pid, app.thread);
- requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
+ requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"2nd-crash");
return false;
}
@@ -821,7 +820,7 @@ final class ActivityStack {
}
if (w > 0) {
- return mService.mWindowManager.screenshotApplications(who, w, h);
+ return mService.mWindowManager.screenshotApplications(who.appToken, w, h);
}
return null;
}
@@ -856,8 +855,8 @@ final class ActivityStack {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
System.identityHashCode(prev),
prev.shortComponentName);
- prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,
- prev.configChangeFlags);
+ prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
+ userLeaving, prev.configChangeFlags);
if (mMainStack) {
mService.updateUsageStats(prev, false);
}
@@ -1129,7 +1128,7 @@ final class ActivityStack {
if (!r.visible) {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Starting and making visible: " + r);
- mService.mWindowManager.setAppVisibility(r, true);
+ mService.mWindowManager.setAppVisibility(r.appToken, true);
}
if (r != starting) {
startSpecificActivityLocked(r, false, false);
@@ -1153,10 +1152,10 @@ final class ActivityStack {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Making visible and scheduling visibility: " + r);
try {
- mService.mWindowManager.setAppVisibility(r, true);
+ mService.mWindowManager.setAppVisibility(r.appToken, true);
r.sleeping = false;
r.app.pendingUiClean = true;
- r.app.thread.scheduleWindowVisibility(r, true);
+ r.app.thread.scheduleWindowVisibility(r.appToken, true);
r.stopFreezingScreenLocked(false);
} catch (Exception e) {
// Just skip on any failure; we'll make it
@@ -1195,13 +1194,13 @@ final class ActivityStack {
TAG, "Making invisible: " + r);
r.visible = false;
try {
- mService.mWindowManager.setAppVisibility(r, false);
+ mService.mWindowManager.setAppVisibility(r.appToken, false);
if ((r.state == ActivityState.STOPPING
|| r.state == ActivityState.STOPPED)
&& r.app != null && r.app.thread != null) {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Scheduling invisibility: " + r);
- r.app.thread.scheduleWindowVisibility(r, false);
+ r.app.thread.scheduleWindowVisibility(r.appToken, false);
}
} catch (Exception e) {
// Just skip on any failure; we'll make it
@@ -1351,7 +1350,7 @@ final class ActivityStack {
// previous should actually be hidden depending on whether the
// new one is found to be full-screen or not.
if (prev.finishing) {
- mService.mWindowManager.setAppVisibility(prev, false);
+ mService.mWindowManager.setAppVisibility(prev.appToken, false);
if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
+ prev + ", waitingVisible="
+ (prev != null ? prev.waitingVisible : null)
@@ -1399,8 +1398,8 @@ final class ActivityStack {
? WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE
: WindowManagerPolicy.TRANSIT_TASK_CLOSE, false);
}
- mService.mWindowManager.setAppWillBeHidden(prev);
- mService.mWindowManager.setAppVisibility(prev, false);
+ mService.mWindowManager.setAppWillBeHidden(prev.appToken);
+ mService.mWindowManager.setAppVisibility(prev.appToken, false);
} else {
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: prev=" + prev);
@@ -1414,8 +1413,8 @@ final class ActivityStack {
}
}
if (false) {
- mService.mWindowManager.setAppWillBeHidden(prev);
- mService.mWindowManager.setAppVisibility(prev, false);
+ mService.mWindowManager.setAppWillBeHidden(prev.appToken);
+ mService.mWindowManager.setAppVisibility(prev.appToken, false);
}
} else if (mHistory.size() > 1) {
if (DEBUG_TRANSITION) Slog.v(TAG,
@@ -1433,7 +1432,7 @@ final class ActivityStack {
if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
// This activity is now becoming visible.
- mService.mWindowManager.setAppVisibility(next, true);
+ mService.mWindowManager.setAppVisibility(next.appToken, true);
ActivityRecord lastResumedActivity = mResumedActivity;
ActivityState lastState = next.state;
@@ -1457,7 +1456,7 @@ final class ActivityStack {
synchronized (mService) {
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
- next.mayFreezeScreenLocked(next.app) ? next : null);
+ next.mayFreezeScreenLocked(next.app) ? next.appToken : null);
if (config != null) {
next.frozenBeforeDestroy = true;
}
@@ -1496,12 +1495,12 @@ final class ActivityStack {
if (DEBUG_RESULTS) Slog.v(
TAG, "Delivering results to " + next
+ ": " + a);
- next.app.thread.scheduleSendResult(next, a);
+ next.app.thread.scheduleSendResult(next.appToken, a);
}
}
if (next.newIntents != null) {
- next.app.thread.scheduleNewIntent(next.newIntents, next);
+ next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
}
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY,
@@ -1511,7 +1510,7 @@ final class ActivityStack {
next.sleeping = false;
showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
- next.app.thread.scheduleResumeActivity(next,
+ next.app.thread.scheduleResumeActivity(next.appToken,
mService.isNextTransitionForward());
checkReadyForSleepLocked();
@@ -1528,7 +1527,7 @@ final class ActivityStack {
} else {
if (SHOW_APP_STARTING_PREVIEW && mMainStack) {
mService.mWindowManager.setAppStartingWindow(
- next, next.packageName, next.theme,
+ next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(
next.info.applicationInfo),
next.nonLocalizedLabel,
@@ -1549,7 +1548,7 @@ final class ActivityStack {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
- requestFinishActivityLocked(next, Activity.RESULT_CANCELED, null,
+ requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
"resume-exception");
return true;
}
@@ -1567,7 +1566,7 @@ final class ActivityStack {
} else {
if (SHOW_APP_STARTING_PREVIEW) {
mService.mWindowManager.setAppStartingWindow(
- next, next.packageName, next.theme,
+ next.appToken, next.packageName, next.theme,
mService.compatibilityInfoForPackageLocked(
next.info.applicationInfo),
next.nonLocalizedLabel,
@@ -1610,10 +1609,10 @@ final class ActivityStack {
}
mHistory.add(addPos, r);
r.putInHistory();
- mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,
+ mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
r.info.screenOrientation, r.fullscreen);
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
return;
}
@@ -1677,7 +1676,7 @@ final class ActivityStack {
mNoAnimActivities.remove(r);
}
mService.mWindowManager.addAppToken(
- addPos, r, r.task.taskId, r.info.screenOrientation, r.fullscreen);
+ addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen);
boolean doShow = true;
if (newTask) {
// Even though this activity is starting fresh, we still need
@@ -1705,19 +1704,20 @@ final class ActivityStack {
else if (prev.nowVisible) prev = null;
}
mService.mWindowManager.setAppStartingWindow(
- r, r.packageName, r.theme,
+ r.appToken, r.packageName, r.theme,
mService.compatibilityInfoForPackageLocked(
r.info.applicationInfo), r.nonLocalizedLabel,
- r.labelRes, r.icon, r.windowFlags, prev, showStartingIcon);
+ r.labelRes, r.icon, r.windowFlags,
+ prev != null ? prev.appToken : null, showStartingIcon);
}
} 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(addPos, r, r.task.taskId,
+ mService.mWindowManager.addAppToken(addPos, r.appToken, r.task.taskId,
r.info.screenOrientation, r.fullscreen);
}
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
if (doResume) {
@@ -1725,6 +1725,15 @@ final class ActivityStack {
}
}
+ final void validateAppTokensLocked() {
+ mValidateAppTokens.clear();
+ mValidateAppTokens.ensureCapacity(mHistory.size());
+ for (int i=0; i<mHistory.size(); i++) {
+ mValidateAppTokens.add(mHistory.get(i).appToken);
+ }
+ mService.mWindowManager.validateAppTokens(mValidateAppTokens);
+ }
+
/**
* Perform a reset of the given task, if needed as part of launching it.
* Returns the new HistoryRecord at the top of the task.
@@ -1826,7 +1835,7 @@ final class ActivityStack {
if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
+ " out to new task " + target.task);
}
- mService.mWindowManager.setAppGroupId(target, task.taskId);
+ mService.mWindowManager.setAppGroupId(target.appToken, task.taskId);
if (replyChainEnd < 0) {
replyChainEnd = targetI;
}
@@ -1849,11 +1858,11 @@ final class ActivityStack {
}
mHistory.remove(srcPos);
mHistory.add(dstPos, p);
- mService.mWindowManager.moveAppToken(dstPos, p);
- mService.mWindowManager.setAppGroupId(p, p.task.taskId);
+ mService.mWindowManager.moveAppToken(dstPos, p.appToken);
+ mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
dstPos++;
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
i++;
}
@@ -1985,10 +1994,10 @@ final class ActivityStack {
mHistory.add(lastReparentPos, p);
if (DEBUG_TASKS) Slog.v(TAG, "Pulling activity " + p
+ " in to resetting task " + task);
- mService.mWindowManager.moveAppToken(lastReparentPos, p);
- mService.mWindowManager.setAppGroupId(p, p.task.taskId);
+ mService.mWindowManager.moveAppToken(lastReparentPos, p.appToken);
+ mService.mWindowManager.setAppGroupId(p.appToken, p.task.taskId);
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
}
replyChainEnd = -1;
@@ -2081,7 +2090,7 @@ final class ActivityStack {
if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
&& (launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
if (!ret.finishing) {
- int index = indexOfTokenLocked(ret);
+ int index = indexOfTokenLocked(ret.appToken);
if (index >= 0) {
finishActivityLocked(ret, index, Activity.RESULT_CANCELED,
null, "clear");
@@ -3007,7 +3016,7 @@ final class ActivityStack {
return res;
}
- resultTo = outActivity[0];
+ resultTo = outActivity[0] != null ? outActivity[0].appToken : null;
}
}
} finally {
@@ -3065,7 +3074,7 @@ final class ActivityStack {
ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
list.add(new ResultInfo(resultWho, requestCode,
resultCode, data));
- r.app.thread.scheduleSendResult(r, list);
+ r.app.thread.scheduleSendResult(r.appToken, list);
return;
} catch (Exception e) {
Slog.w(TAG, "Exception thrown sending result to " + r, e);
@@ -3080,7 +3089,7 @@ final class ActivityStack {
if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
if (!r.finishing) {
- requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null,
+ requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"no-history");
}
} else if (r.app != null && r.app.thread != null) {
@@ -3098,9 +3107,9 @@ final class ActivityStack {
if (DEBUG_VISBILITY) Slog.v(
TAG, "Stopping visible=" + r.visible + " for " + r);
if (!r.visible) {
- mService.mWindowManager.setAppVisibility(r, false);
+ mService.mWindowManager.setAppVisibility(r.appToken, false);
}
- r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags);
+ r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
if (mService.isSleeping()) {
r.setSleeping(true);
}
@@ -3145,7 +3154,7 @@ final class ActivityStack {
// normal flow and hide it once we determine that it is
// hidden by the activities in front of it.
if (localLOGV) Slog.v(TAG, "Before stopping, can hide: " + s);
- mService.mWindowManager.setAppVisibility(s, false);
+ mService.mWindowManager.setAppVisibility(s.appToken, false);
}
}
if ((!s.waitingVisible || mService.isSleeping()) && remove) {
@@ -3186,14 +3195,14 @@ final class ActivityStack {
boolean enableScreen = false;
synchronized (mService) {
- if (token != null) {
- mHandler.removeMessages(IDLE_TIMEOUT_MSG, token);
+ ActivityRecord r = ActivityRecord.forToken(token);
+ if (r != null) {
+ mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
}
// Get the activity record.
- int index = indexOfTokenLocked(token);
+ int index = indexOfActivityLocked(r);
if (index >= 0) {
- ActivityRecord r = mHistory.get(index);
res = r;
if (fromTimeout) {
@@ -3413,7 +3422,7 @@ final class ActivityStack {
: WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE, false);
// Tell window manager to prepare for this one to be removed.
- mService.mWindowManager.setAppVisibility(r, false);
+ mService.mWindowManager.setAppVisibility(r.appToken, false);
if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
@@ -3440,7 +3449,7 @@ final class ActivityStack {
private final ActivityRecord finishCurrentActivityLocked(ActivityRecord r,
int mode) {
- final int index = indexOfTokenLocked(r);
+ final int index = indexOfActivityLocked(r);
if (index < 0) {
return null;
}
@@ -3570,9 +3579,9 @@ final class ActivityStack {
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
+ " (removed from history)");
r.state = ActivityState.DESTROYED;
- mService.mWindowManager.removeAppToken(r);
+ mService.mWindowManager.removeAppToken(r.appToken);
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
cleanUpActivityServicesLocked(r);
r.removeUriPermissionsLocked();
@@ -3653,7 +3662,7 @@ final class ActivityStack {
try {
if (DEBUG_SWITCH) Slog.i(TAG, "Destroying: " + r);
- r.app.thread.scheduleDestroyActivity(r, r.finishing,
+ r.app.thread.scheduleDestroyActivity(r.appToken, r.finishing,
r.configChangeFlags);
} catch (Exception e) {
// We can just ignore exceptions here... if the process
@@ -3712,11 +3721,13 @@ final class ActivityStack {
final void activityDestroyed(IBinder token) {
synchronized (mService) {
- mHandler.removeMessages(DESTROY_TIMEOUT_MSG, token);
+ ActivityRecord r = ActivityRecord.forToken(token);
+ if (r != null) {
+ mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
+ }
- int index = indexOfTokenLocked(token);
+ int index = indexOfActivityLocked(r);
if (index >= 0) {
- ActivityRecord r = mHistory.get(index);
if (r.state == ActivityState.DESTROYING) {
final long origId = Binder.clearCallingIdentity();
removeActivityFromHistoryLocked(r);
@@ -3781,7 +3792,7 @@ final class ActivityStack {
return;
}
- ArrayList moved = new ArrayList();
+ ArrayList<IBinder> moved = new ArrayList<IBinder>();
// Applying the affinities may have removed entries from the history,
// so get the size again.
@@ -3803,7 +3814,7 @@ final class ActivityStack {
}
mHistory.remove(pos);
mHistory.add(top, r);
- moved.add(0, r);
+ moved.add(0, r.appToken);
top--;
}
pos--;
@@ -3826,7 +3837,7 @@ final class ActivityStack {
mService.mWindowManager.moveAppTokensToTop(moved);
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
finishTaskMoveLocked(task);
@@ -3873,7 +3884,7 @@ final class ActivityStack {
}
}
- ArrayList moved = new ArrayList();
+ ArrayList<IBinder> moved = new ArrayList<IBinder>();
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare to back transition: task=" + task);
@@ -3898,7 +3909,7 @@ final class ActivityStack {
}
mHistory.remove(pos);
mHistory.add(bottom, r);
- moved.add(r);
+ moved.add(r.appToken);
bottom++;
}
pos++;
@@ -3918,7 +3929,7 @@ final class ActivityStack {
}
mService.mWindowManager.moveAppTokensToBottom(moved);
if (VALIDATE_TOKENS) {
- mService.mWindowManager.validateAppTokens(mHistory);
+ validateAppTokensLocked();
}
finishTaskMoveLocked(task);
@@ -4148,7 +4159,7 @@ final class ActivityStack {
if (r.app != null && r.app.thread != null) {
try {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending new config to " + r);
- r.app.thread.scheduleActivityConfigurationChanged(r);
+ r.app.thread.scheduleActivityConfigurationChanged(r.appToken);
} catch (RemoteException e) {
// If process died, whatever.
}
@@ -4178,7 +4189,7 @@ final class ActivityStack {
try {
if (DEBUG_SWITCH) Slog.i(TAG, "Switch is restarting resumed " + r);
r.forceNewConfig = false;
- r.app.thread.scheduleRelaunchActivity(r, results, newIntents,
+ r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents,
changes, !andResume, mService.mConfiguration);
// Note: don't need to call pauseIfSleepingLocked() here, because
// the caller will only pass in 'andResume' if this activity is
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4ffc201..50321b3 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3070,7 +3070,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Application Window Tokens
// -------------------------------------------------------------
- public void validateAppTokens(List tokens) {
+ public void validateAppTokens(List<IBinder> tokens) {
int v = tokens.size()-1;
int m = mAppTokens.size()-1;
while (v >= 0 && m >= 0) {