am be70785f
: Make activity manager more robust in the face of app activity leaks.
* commit 'be70785f9b2dbd2c52fd8676d99bc64b22784201': Make activity manager more robust in the face of app activity leaks.
This commit is contained in:
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user