Merge "Protect against NPE for ActivityRecords without a stack."
This commit is contained in:
committed by
Android (Google) Code Review
commit
d58617b4f5
@@ -1757,7 +1757,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
case ENTER_ANIMATION_COMPLETE_MSG: {
|
||||
synchronized (ActivityManagerService.this) {
|
||||
ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
|
||||
ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
|
||||
if (r != null && r.app != null && r.app.thread != null) {
|
||||
try {
|
||||
r.app.thread.scheduleEnterAnimationComplete(r.appToken);
|
||||
@@ -2520,7 +2520,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
public void notifyActivityDrawn(IBinder token) {
|
||||
if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
|
||||
synchronized (this) {
|
||||
ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
|
||||
ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
|
||||
if (r != null) {
|
||||
r.task.stack.notifyActivityDrawnLocked(r);
|
||||
}
|
||||
@@ -3955,11 +3955,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
|
||||
mHeavyWeightProcess.activities);
|
||||
for (int i=0; i<activities.size(); i++) {
|
||||
ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
|
||||
for (int i = 0; i < activities.size(); i++) {
|
||||
ActivityRecord r = activities.get(i);
|
||||
if (!r.finishing) {
|
||||
if (!r.finishing && r.isInStackLocked()) {
|
||||
r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
|
||||
null, "finish-heavy", true);
|
||||
}
|
||||
@@ -4086,7 +4085,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ActivityRecord r = ActivityRecord.isInStackLocked(token);
|
||||
if (r.task == null || r.task.stack == null) {
|
||||
if (r == null) {
|
||||
return false;
|
||||
}
|
||||
return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
|
||||
@@ -7797,20 +7796,19 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
android.Manifest.permission.GET_DETAILED_TASKS)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
final int N = mRecentTasks.size();
|
||||
ArrayList<ActivityManager.RecentTaskInfo> res
|
||||
= new ArrayList<ActivityManager.RecentTaskInfo>(
|
||||
maxNum < N ? maxNum : N);
|
||||
final int recentsCount = mRecentTasks.size();
|
||||
ArrayList<ActivityManager.RecentTaskInfo> res =
|
||||
new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
|
||||
|
||||
final Set<Integer> includedUsers;
|
||||
if (includeProfiles) {
|
||||
includedUsers = getProfileIdsLocked(userId);
|
||||
} else {
|
||||
includedUsers = new HashSet<Integer>();
|
||||
includedUsers = new HashSet<>();
|
||||
}
|
||||
includedUsers.add(Integer.valueOf(userId));
|
||||
|
||||
for (int i=0; i<N && maxNum > 0; i++) {
|
||||
for (int i = 0; i < recentsCount && maxNum > 0; i++) {
|
||||
TaskRecord tr = mRecentTasks.get(i);
|
||||
// Only add calling user or related users recent tasks
|
||||
if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
|
||||
@@ -8292,7 +8290,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (parentActivityToken == null) {
|
||||
throw new IllegalArgumentException("parent token must not be null");
|
||||
}
|
||||
ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
|
||||
ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
|
||||
if (r == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -8494,7 +8492,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
synchronized (this) {
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
@@ -16573,8 +16571,8 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
@Override
|
||||
public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
|
||||
synchronized (this) {
|
||||
ActivityRecord srec = ActivityRecord.forToken(token);
|
||||
if (srec.task != null && srec.task.stack != null) {
|
||||
ActivityRecord srec = ActivityRecord.forTokenLocked(token);
|
||||
if (srec != null) {
|
||||
return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
|
||||
}
|
||||
}
|
||||
@@ -16585,16 +16583,19 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
Intent resultData) {
|
||||
|
||||
synchronized (this) {
|
||||
final ActivityStack stack = ActivityRecord.getStackLocked(token);
|
||||
if (stack != null) {
|
||||
return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r != null) {
|
||||
return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLaunchedFromUid(IBinder activityToken) {
|
||||
ActivityRecord srec = ActivityRecord.forToken(activityToken);
|
||||
ActivityRecord srec;
|
||||
synchronized (this) {
|
||||
srec = ActivityRecord.forTokenLocked(activityToken);
|
||||
}
|
||||
if (srec == null) {
|
||||
return -1;
|
||||
}
|
||||
@@ -16602,7 +16603,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
public String getLaunchedFromPackage(IBinder activityToken) {
|
||||
ActivityRecord srec = ActivityRecord.forToken(activityToken);
|
||||
ActivityRecord srec;
|
||||
synchronized (this) {
|
||||
srec = ActivityRecord.forTokenLocked(activityToken);
|
||||
}
|
||||
if (srec == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.am;
|
||||
|
||||
import static com.android.server.am.ActivityManagerDebugConfig.*;
|
||||
import static com.android.server.am.ActivityManagerService.DEBUG_SWITCH;
|
||||
import static com.android.server.am.ActivityManagerService.DEBUG_THUMBNAILS;
|
||||
import static com.android.server.am.TaskPersister.DEBUG_PERSISTER;
|
||||
import static com.android.server.am.TaskPersister.DEBUG_RESTORER;
|
||||
@@ -319,44 +320,83 @@ final class ActivityRecord {
|
||||
}
|
||||
|
||||
static class Token extends IApplicationToken.Stub {
|
||||
final WeakReference<ActivityRecord> weakActivity;
|
||||
private final WeakReference<ActivityRecord> weakActivity;
|
||||
private final ActivityManagerService mService;
|
||||
|
||||
Token(ActivityRecord activity) {
|
||||
Token(ActivityRecord activity, ActivityManagerService service) {
|
||||
weakActivity = new WeakReference<>(activity);
|
||||
mService = service;
|
||||
}
|
||||
|
||||
@Override public void windowsDrawn() {
|
||||
ActivityRecord activity = weakActivity.get();
|
||||
if (activity != null) {
|
||||
activity.windowsDrawn();
|
||||
@Override
|
||||
public void windowsDrawn() {
|
||||
synchronized (mService) {
|
||||
ActivityRecord r = tokenToActivityRecordLocked(this);
|
||||
if (r != null) {
|
||||
r.windowsDrawnLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void windowsVisible() {
|
||||
ActivityRecord activity = weakActivity.get();
|
||||
if (activity != null) {
|
||||
activity.windowsVisible();
|
||||
@Override
|
||||
public void windowsVisible() {
|
||||
synchronized (mService) {
|
||||
ActivityRecord r = tokenToActivityRecordLocked(this);
|
||||
if (r != null) {
|
||||
r.windowsVisibleLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void windowsGone() {
|
||||
ActivityRecord activity = weakActivity.get();
|
||||
if (activity != null) {
|
||||
activity.windowsGone();
|
||||
@Override
|
||||
public void windowsGone() {
|
||||
synchronized (mService) {
|
||||
ActivityRecord r = tokenToActivityRecordLocked(this);
|
||||
if (r != null) {
|
||||
if (DEBUG_SWITCH) Log.v(TAG, "windowsGone(): " + r);
|
||||
r.nowVisible = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean keyDispatchingTimedOut(String reason) {
|
||||
ActivityRecord activity = weakActivity.get();
|
||||
return activity != null && activity.keyDispatchingTimedOut(reason);
|
||||
@Override
|
||||
public boolean keyDispatchingTimedOut(String reason) {
|
||||
ActivityRecord r;
|
||||
ActivityRecord anrActivity;
|
||||
ProcessRecord anrApp;
|
||||
synchronized (mService) {
|
||||
r = tokenToActivityRecordLocked(this);
|
||||
if (r == null) {
|
||||
return false;
|
||||
}
|
||||
anrActivity = r.getWaitingHistoryRecordLocked();
|
||||
anrApp = r != null ? r.app : null;
|
||||
}
|
||||
return mService.inputDispatchingTimedOut(anrApp, anrActivity, r, false, reason);
|
||||
}
|
||||
|
||||
@Override public long getKeyDispatchingTimeout() {
|
||||
ActivityRecord activity = weakActivity.get();
|
||||
if (activity != null) {
|
||||
return activity.getKeyDispatchingTimeout();
|
||||
@Override
|
||||
public long getKeyDispatchingTimeout() {
|
||||
synchronized (mService) {
|
||||
ActivityRecord r = tokenToActivityRecordLocked(this);
|
||||
if (r == null) {
|
||||
return 0;
|
||||
}
|
||||
r = r.getWaitingHistoryRecordLocked();
|
||||
return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static final ActivityRecord tokenToActivityRecordLocked(Token token) {
|
||||
if (token == null) {
|
||||
return null;
|
||||
}
|
||||
ActivityRecord r = token.weakActivity.get();
|
||||
if (r == null || r.task == null || r.task.stack == null) {
|
||||
return null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -371,9 +411,9 @@ final class ActivityRecord {
|
||||
}
|
||||
}
|
||||
|
||||
static ActivityRecord forToken(IBinder token) {
|
||||
static ActivityRecord forTokenLocked(IBinder token) {
|
||||
try {
|
||||
return token != null ? ((Token)token).weakActivity.get() : null;
|
||||
return Token.tokenToActivityRecordLocked((Token)token);
|
||||
} catch (ClassCastException e) {
|
||||
Slog.w(TAG, "Bad activity token: " + token, e);
|
||||
return null;
|
||||
@@ -391,7 +431,7 @@ final class ActivityRecord {
|
||||
boolean _componentSpecified, ActivityStackSupervisor supervisor,
|
||||
ActivityContainer container, Bundle options) {
|
||||
service = _service;
|
||||
appToken = new Token(this);
|
||||
appToken = new Token(this, service);
|
||||
info = aInfo;
|
||||
launchedFromUid = _launchedFromUid;
|
||||
launchedFromPackage = _launchedFromPackage;
|
||||
@@ -528,13 +568,8 @@ final class ActivityRecord {
|
||||
}
|
||||
|
||||
void setTask(TaskRecord newTask, TaskRecord taskToAffiliateWith) {
|
||||
if (task != null && task.removeActivity(this)) {
|
||||
if (task != newTask) {
|
||||
task.stack.removeTask(task, "setTask");
|
||||
} else {
|
||||
Slog.d(TAG, "!!! REMOVE THIS LOG !!! setTask: nearly removed stack=" +
|
||||
(newTask == null ? null : newTask.stack));
|
||||
}
|
||||
if (task != null && task.removeActivity(this) && task != newTask && task.stack != null) {
|
||||
task.stack.removeTask(task, "setTask");
|
||||
}
|
||||
task = newTask;
|
||||
setTaskToAffiliateWith(taskToAffiliateWith);
|
||||
@@ -580,6 +615,10 @@ final class ActivityRecord {
|
||||
return inHistory;
|
||||
}
|
||||
|
||||
boolean isInStackLocked() {
|
||||
return task != null && task.stack != null && task.stack.isInStackLocked(this) != null;
|
||||
}
|
||||
|
||||
boolean isHomeActivity() {
|
||||
return mActivityType == HOME_ACTIVITY_TYPE;
|
||||
}
|
||||
@@ -599,9 +638,10 @@ final class ActivityRecord {
|
||||
(intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
|
||||
}
|
||||
|
||||
void makeFinishing() {
|
||||
void makeFinishingLocked() {
|
||||
if (!finishing) {
|
||||
if (this == task.stack.getVisibleBehindActivity()) {
|
||||
if (task != null && task.stack != null
|
||||
&& this == task.stack.getVisibleBehindActivity()) {
|
||||
// A finishing activity should not remain as visible in the background
|
||||
mStackSupervisor.requestVisibleBehindLocked(this, false);
|
||||
}
|
||||
@@ -670,8 +710,9 @@ final class ActivityRecord {
|
||||
// stack.
|
||||
final ReferrerIntent rintent = new ReferrerIntent(intent, referrer);
|
||||
boolean unsent = true;
|
||||
if ((state == ActivityState.RESUMED || (service.isSleeping()
|
||||
&& task.stack.topRunningActivityLocked(null) == this))
|
||||
if ((state == ActivityState.RESUMED
|
||||
|| (service.isSleeping() && task.stack != null
|
||||
&& task.stack.topRunningActivityLocked(null) == this))
|
||||
&& app != null && app.thread != null) {
|
||||
try {
|
||||
ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
|
||||
@@ -842,19 +883,27 @@ final class ActivityRecord {
|
||||
}
|
||||
|
||||
boolean continueLaunchTickingLocked() {
|
||||
if (launchTickTime != 0) {
|
||||
final ActivityStack stack = task.stack;
|
||||
Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG, this);
|
||||
stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
|
||||
stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
|
||||
return true;
|
||||
if (launchTickTime == 0) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
final ActivityStack stack = task.stack;
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG, this);
|
||||
stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
|
||||
stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
|
||||
return true;
|
||||
}
|
||||
|
||||
void finishLaunchTickingLocked() {
|
||||
launchTickTime = 0;
|
||||
task.stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
|
||||
final ActivityStack stack = task.stack;
|
||||
if (stack != null) {
|
||||
stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
|
||||
}
|
||||
}
|
||||
|
||||
// IApplicationToken
|
||||
@@ -885,8 +934,8 @@ final class ActivityRecord {
|
||||
if (displayStartTime != 0) {
|
||||
reportLaunchTimeLocked(curTime);
|
||||
}
|
||||
if (fullyDrawnStartTime != 0) {
|
||||
final ActivityStack stack = task.stack;
|
||||
final ActivityStack stack = task.stack;
|
||||
if (fullyDrawnStartTime != 0 && stack != null) {
|
||||
final long thisTime = curTime - fullyDrawnStartTime;
|
||||
final long totalTime = stack.mFullyDrawnStartTime != 0
|
||||
? (curTime - stack.mFullyDrawnStartTime) : thisTime;
|
||||
@@ -911,13 +960,16 @@ final class ActivityRecord {
|
||||
if (totalTime > 0) {
|
||||
//service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
|
||||
}
|
||||
fullyDrawnStartTime = 0;
|
||||
stack.mFullyDrawnStartTime = 0;
|
||||
}
|
||||
fullyDrawnStartTime = 0;
|
||||
}
|
||||
|
||||
private void reportLaunchTimeLocked(final long curTime) {
|
||||
final ActivityStack stack = task.stack;
|
||||
if (stack == null) {
|
||||
return;
|
||||
}
|
||||
final long thisTime = curTime - displayStartTime;
|
||||
final long totalTime = stack.mLaunchStartTime != 0
|
||||
? (curTime - stack.mLaunchStartTime) : thisTime;
|
||||
@@ -947,60 +999,47 @@ final class ActivityRecord {
|
||||
stack.mLaunchStartTime = 0;
|
||||
}
|
||||
|
||||
public void windowsDrawn() {
|
||||
synchronized(service) {
|
||||
if (displayStartTime != 0) {
|
||||
reportLaunchTimeLocked(SystemClock.uptimeMillis());
|
||||
}
|
||||
mStackSupervisor.sendWaitingVisibleReportLocked(this);
|
||||
startTime = 0;
|
||||
finishLaunchTickingLocked();
|
||||
if (task != null) {
|
||||
task.hasBeenVisible = true;
|
||||
}
|
||||
void windowsDrawnLocked() {
|
||||
if (displayStartTime != 0) {
|
||||
reportLaunchTimeLocked(SystemClock.uptimeMillis());
|
||||
}
|
||||
mStackSupervisor.sendWaitingVisibleReportLocked(this);
|
||||
startTime = 0;
|
||||
finishLaunchTickingLocked();
|
||||
if (task != null) {
|
||||
task.hasBeenVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void windowsVisible() {
|
||||
synchronized(service) {
|
||||
mStackSupervisor.reportActivityVisibleLocked(this);
|
||||
if (ActivityManagerService.DEBUG_SWITCH) Log.v(TAG, "windowsVisible(): " + this);
|
||||
if (!nowVisible) {
|
||||
nowVisible = true;
|
||||
lastVisibleTime = SystemClock.uptimeMillis();
|
||||
if (!idle) {
|
||||
// Instead of doing the full stop routine here, let's just
|
||||
// hide any activities we now can, and let them stop when
|
||||
// the normal idle happens.
|
||||
mStackSupervisor.processStoppingActivitiesLocked(false);
|
||||
} else {
|
||||
// If this activity was already idle, then we now need to
|
||||
// make sure we perform the full stop of any activities
|
||||
// that are waiting to do so. This is because we won't
|
||||
// do that while they are still waiting for this one to
|
||||
// become visible.
|
||||
final int N = mStackSupervisor.mWaitingVisibleActivities.size();
|
||||
if (N > 0) {
|
||||
for (int i=0; i<N; i++) {
|
||||
ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
|
||||
if (ActivityManagerService.DEBUG_SWITCH) Log.v(TAG,
|
||||
"Was waiting for visible: " + r);
|
||||
}
|
||||
mStackSupervisor.mWaitingVisibleActivities.clear();
|
||||
mStackSupervisor.scheduleIdleLocked();
|
||||
void windowsVisibleLocked() {
|
||||
mStackSupervisor.reportActivityVisibleLocked(this);
|
||||
if (DEBUG_SWITCH) Log.v(TAG, "windowsVisibleLocked(): " + this);
|
||||
if (!nowVisible) {
|
||||
nowVisible = true;
|
||||
lastVisibleTime = SystemClock.uptimeMillis();
|
||||
if (!idle) {
|
||||
// Instead of doing the full stop routine here, let's just hide any activities
|
||||
// we now can, and let them stop when the normal idle happens.
|
||||
mStackSupervisor.processStoppingActivitiesLocked(false);
|
||||
} else {
|
||||
// If this activity was already idle, then we now need to make sure we perform
|
||||
// the full stop of any activities that are waiting to do so. This is because
|
||||
// we won't do that while they are still waiting for this one to become visible.
|
||||
final int size = mStackSupervisor.mWaitingVisibleActivities.size();
|
||||
if (size > 0) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
ActivityRecord r = mStackSupervisor.mWaitingVisibleActivities.get(i);
|
||||
if (DEBUG_SWITCH) Log.v(TAG, "Was waiting for visible: " + r);
|
||||
}
|
||||
mStackSupervisor.mWaitingVisibleActivities.clear();
|
||||
mStackSupervisor.scheduleIdleLocked();
|
||||
}
|
||||
service.scheduleAppGcsLocked();
|
||||
}
|
||||
service.scheduleAppGcsLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public void windowsGone() {
|
||||
if (ActivityManagerService.DEBUG_SWITCH) Log.v(TAG, "windowsGone(): " + this);
|
||||
nowVisible = false;
|
||||
}
|
||||
|
||||
private ActivityRecord getWaitingHistoryRecordLocked() {
|
||||
ActivityRecord getWaitingHistoryRecordLocked() {
|
||||
// First find the real culprit... if we are waiting
|
||||
// for another app to start, then we have paused dispatching
|
||||
// for this activity.
|
||||
@@ -1021,24 +1060,6 @@ final class ActivityRecord {
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean keyDispatchingTimedOut(String reason) {
|
||||
ActivityRecord r;
|
||||
ProcessRecord anrApp;
|
||||
synchronized(service) {
|
||||
r = getWaitingHistoryRecordLocked();
|
||||
anrApp = r != null ? r.app : null;
|
||||
}
|
||||
return service.inputDispatchingTimedOut(anrApp, r, this, false, reason);
|
||||
}
|
||||
|
||||
/** Returns the key dispatching timeout for this application token. */
|
||||
public long getKeyDispatchingTimeout() {
|
||||
synchronized(service) {
|
||||
ActivityRecord r = getWaitingHistoryRecordLocked();
|
||||
return ActivityManagerService.getInputDispatchingTimeoutLocked(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return true if the activity is either visible, is becoming visible, is
|
||||
* currently pausing, or is resumed.
|
||||
@@ -1066,14 +1087,14 @@ final class ActivityRecord {
|
||||
}
|
||||
|
||||
static void activityResumedLocked(IBinder token) {
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
|
||||
r.icicle = null;
|
||||
r.haveState = false;
|
||||
}
|
||||
|
||||
static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r == null) {
|
||||
return INVALID_TASK_ID;
|
||||
}
|
||||
@@ -1086,7 +1107,7 @@ final class ActivityRecord {
|
||||
}
|
||||
|
||||
static ActivityRecord isInStackLocked(IBinder token) {
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
return (r != null) ? r.task.stack.isInStackLocked(r) : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -461,7 +461,7 @@ final class ActivityStack {
|
||||
}
|
||||
|
||||
ActivityRecord isInStackLocked(IBinder token) {
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
return isInStackLocked(r);
|
||||
}
|
||||
|
||||
@@ -470,7 +470,8 @@ final class ActivityStack {
|
||||
return null;
|
||||
}
|
||||
final TaskRecord task = r.task;
|
||||
if (task != null && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
|
||||
if (task != null && task.stack != null
|
||||
&& task.mActivities.contains(r) && mTaskHistory.contains(task)) {
|
||||
if (task.stack != this) Slog.w(TAG,
|
||||
"Illegal state! task does not point to stack it is in.");
|
||||
return r;
|
||||
@@ -2797,7 +2798,7 @@ final class ActivityStack {
|
||||
return false;
|
||||
}
|
||||
|
||||
r.makeFinishing();
|
||||
r.makeFinishingLocked();
|
||||
final TaskRecord task = r.task;
|
||||
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
|
||||
r.userId, System.identityHashCode(r),
|
||||
@@ -2900,7 +2901,7 @@ final class ActivityStack {
|
||||
|| prevState == ActivityState.INITIALIZING) {
|
||||
// If this activity is already stopped, we can just finish
|
||||
// it right now.
|
||||
r.makeFinishing();
|
||||
r.makeFinishingLocked();
|
||||
boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm");
|
||||
if (activityRemoved) {
|
||||
mStackSupervisor.resumeTopActivitiesLocked();
|
||||
@@ -2976,9 +2977,8 @@ final class ActivityStack {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode,
|
||||
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
|
||||
Intent resultData) {
|
||||
final ActivityRecord srec = ActivityRecord.forToken(token);
|
||||
final TaskRecord task = srec.task;
|
||||
final ArrayList<ActivityRecord> activities = task.mActivities;
|
||||
final int start = activities.indexOf(srec);
|
||||
@@ -3125,7 +3125,7 @@ final class ActivityStack {
|
||||
private void removeActivityFromHistoryLocked(ActivityRecord r, String reason) {
|
||||
mStackSupervisor.removeChildActivityContainers(r);
|
||||
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
|
||||
r.makeFinishing();
|
||||
r.makeFinishingLocked();
|
||||
if (DEBUG_ADD_REMOVE) {
|
||||
RuntimeException here = new RuntimeException("here");
|
||||
here.fillInStackTrace();
|
||||
@@ -3366,7 +3366,7 @@ final class ActivityStack {
|
||||
final void activityDestroyedLocked(IBinder token, String reason) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
ActivityRecord r = ActivityRecord.forToken(token);
|
||||
ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r != null) {
|
||||
mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
|
||||
}
|
||||
@@ -3947,7 +3947,7 @@ final class ActivityStack {
|
||||
}
|
||||
}
|
||||
}
|
||||
final ActivityRecord r = ActivityRecord.forToken(token);
|
||||
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -394,6 +394,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
* Use {@link ActivityStack#isStackVisibleLocked} to determine if a specific
|
||||
* stack is visible or not. */
|
||||
boolean isFrontStack(ActivityStack stack) {
|
||||
if (stack == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final ActivityRecord parent = stack.mActivityContainer.mParentActivity;
|
||||
if (parent != null) {
|
||||
stack = parent.task.stack;
|
||||
@@ -1380,6 +1384,9 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
|
||||
}
|
||||
resultRecord = sourceRecord.resultTo;
|
||||
if (resultRecord != null && !resultRecord.isInStackLocked()) {
|
||||
resultRecord = null;
|
||||
}
|
||||
resultWho = sourceRecord.resultWho;
|
||||
requestCode = sourceRecord.requestCode;
|
||||
sourceRecord.resultTo = null;
|
||||
@@ -1564,7 +1571,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
|
||||
ActivityStack stack;
|
||||
|
||||
if (task != null) {
|
||||
if (task != null && task.stack != null) {
|
||||
stack = task.stack;
|
||||
if (stack.isOnHomeDisplay()) {
|
||||
if (mFocusedStack != stack) {
|
||||
@@ -1672,7 +1679,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
&& !launchSingleTask && !launchSingleInstance
|
||||
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0;
|
||||
|
||||
if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
|
||||
if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
|
||||
&& r.resultTo.task.stack != null) {
|
||||
// For whatever reason this activity is being launched into a new
|
||||
// task... yet the caller has requested a result back. Well, that
|
||||
// is pretty messed up, so instead immediately send back a cancel
|
||||
@@ -2074,7 +2082,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
}
|
||||
|
||||
} else {
|
||||
if (r.resultTo != null) {
|
||||
if (r.resultTo != null && r.resultTo.task.stack != null) {
|
||||
r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho,
|
||||
r.requestCode, Activity.RESULT_CANCELED, null);
|
||||
}
|
||||
@@ -2307,7 +2315,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
boolean booting = false;
|
||||
boolean activityRemoved = false;
|
||||
|
||||
ActivityRecord r = ActivityRecord.forToken(token);
|
||||
ActivityRecord r = ActivityRecord.forTokenLocked(token);
|
||||
if (r != null) {
|
||||
if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
|
||||
Debug.getCallers(4));
|
||||
@@ -2355,13 +2363,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
// Atomically retrieve all of the other things to do.
|
||||
stops = processStoppingActivitiesLocked(true);
|
||||
NS = stops != null ? stops.size() : 0;
|
||||
if ((NF=mFinishingActivities.size()) > 0) {
|
||||
finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
|
||||
if ((NF = mFinishingActivities.size()) > 0) {
|
||||
finishes = new ArrayList<>(mFinishingActivities);
|
||||
mFinishingActivities.clear();
|
||||
}
|
||||
|
||||
if (mStartingUsers.size() > 0) {
|
||||
startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
|
||||
startingUsers = new ArrayList<>(mStartingUsers);
|
||||
mStartingUsers.clear();
|
||||
}
|
||||
|
||||
@@ -2370,10 +2378,12 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
for (int i = 0; i < NS; i++) {
|
||||
r = stops.get(i);
|
||||
final ActivityStack stack = r.task.stack;
|
||||
if (r.finishing) {
|
||||
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
|
||||
} else {
|
||||
stack.stopActivityLocked(r);
|
||||
if (stack != null) {
|
||||
if (r.finishing) {
|
||||
stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
|
||||
} else {
|
||||
stack.stopActivityLocked(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2381,7 +2391,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
// waiting for the next one to start.
|
||||
for (int i = 0; i < NF; i++) {
|
||||
r = finishes.get(i);
|
||||
activityRemoved |= r.task.stack.destroyActivityLocked(r, true, "finish-idle");
|
||||
final ActivityStack stack = r.task.stack;
|
||||
if (stack != null) {
|
||||
activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
|
||||
}
|
||||
}
|
||||
|
||||
if (!booting) {
|
||||
@@ -2550,6 +2563,11 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
// we'll just indicate that this task returns to the home task.
|
||||
task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
|
||||
}
|
||||
if (task.stack == null) {
|
||||
Slog.e(TAG, "findTaskToMoveToFrontLocked: can't move task="
|
||||
+ task + " to front. Stack is null");
|
||||
return;
|
||||
}
|
||||
task.stack.moveTaskToFrontLocked(task, false /* noAnimation */, options, reason);
|
||||
if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
|
||||
+ task.stack);
|
||||
@@ -3769,7 +3787,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
|
||||
} break;
|
||||
case LAUNCH_TASK_BEHIND_COMPLETE: {
|
||||
synchronized (mService) {
|
||||
ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
|
||||
ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
|
||||
if (r != null) {
|
||||
handleLaunchTaskBehindCompleteLocked(r);
|
||||
}
|
||||
|
||||
@@ -275,8 +275,10 @@ final class PendingIntentRecord extends IIntentSender.Stub {
|
||||
}
|
||||
break;
|
||||
case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
|
||||
key.activity.task.stack.sendActivityResultLocked(-1, key.activity,
|
||||
key.who, key.requestCode, code, finalIntent);
|
||||
if (key.activity.task.stack != null) {
|
||||
key.activity.task.stack.sendActivityResultLocked(-1, key.activity,
|
||||
key.who, key.requestCode, code, finalIntent);
|
||||
}
|
||||
break;
|
||||
case ActivityManager.INTENT_SENDER_BROADCAST:
|
||||
try {
|
||||
|
||||
@@ -500,10 +500,12 @@ final class TaskRecord {
|
||||
}
|
||||
|
||||
ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
|
||||
for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
ActivityRecord r = mActivities.get(activityNdx);
|
||||
if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
|
||||
return r;
|
||||
if (stack != null) {
|
||||
for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
ActivityRecord r = mActivities.get(activityNdx);
|
||||
if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -666,7 +668,7 @@ final class TaskRecord {
|
||||
if (opts != null) {
|
||||
ret.updateOptionsLocked(opts);
|
||||
}
|
||||
if (stack.finishActivityLocked(
|
||||
if (stack != null && stack.finishActivityLocked(
|
||||
r, Activity.RESULT_CANCELED, null, "clear-task-stack", false)) {
|
||||
--activityNdx;
|
||||
--numActivities;
|
||||
@@ -679,8 +681,10 @@ final class TaskRecord {
|
||||
if (ret.launchMode == ActivityInfo.LAUNCH_MULTIPLE
|
||||
&& (launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) == 0) {
|
||||
if (!ret.finishing) {
|
||||
stack.finishActivityLocked(
|
||||
ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
|
||||
if (stack != null) {
|
||||
stack.finishActivityLocked(
|
||||
ret, Activity.RESULT_CANCELED, null, "clear-task-top", false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user