summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-11-11 14:32:10 -0800
committerDianne Hackborn <hackbod@google.com>2011-11-11 15:05:59 -0800
commitbe70785f9b2dbd2c52fd8676d99bc64b22784201 (patch)
tree8c73c7f75259deb7a76bf26bb50e795763b9c39a /services
parent24597eb77e1a88994b83c5b1f45d5b72383943b8 (diff)
downloadframeworks_base-be70785f9b2dbd2c52fd8676d99bc64b22784201.zip
frameworks_base-be70785f9b2dbd2c52fd8676d99bc64b22784201.tar.gz
frameworks_base-be70785f9b2dbd2c52fd8676d99bc64b22784201.tar.bz2
Make activity manager more robust in the face of app activity leaks.
This came up from bug #5601885: Memory increase (leak?) in system_server Stingray MR1 This isn't *really* a leak in the system process -- it is a leak in an application process that is causing the system process to keep around a bunch of ActivityRecord objects longer than it should, until that app process is ultimately killed. Unfortunately these days leaking an ActivityRecord also often means leaking a thumbnail, which is a big slab of memory. So make the activity manager better about this, using a weak reference from the handle the object has so we can still clean away most of the state associated with the ActivityRecord even if the client side leaks its own reference. Change-Id: Idbab45e09749cdfb54899203da7981e7b3576e25
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) {