}
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);
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);
}
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);
}
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");
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))) {
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;
}
long ident = Binder.clearCallingIdentity();
try {
synchronized (this) {
- final ActivityRecord r = ActivityRecord.forToken(token);
+ final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r == null) {
return;
}
@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);
}
}
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;
}
}
public String getLaunchedFromPackage(IBinder activityToken) {
- ActivityRecord srec = ActivityRecord.forToken(activityToken);
+ ActivityRecord srec;
+ synchronized (this) {
+ srec = ActivityRecord.forTokenLocked(activityToken);
+ }
if (srec == null) {
return null;
}
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;
}
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
}
}
- 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;
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;
}
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);
return inHistory;
}
+ boolean isInStackLocked() {
+ return task != null && task.stack != null && task.stack.isInStackLocked(this) != null;
+ }
+
boolean isHomeActivity() {
return mActivityType == HOME_ACTIVITY_TYPE;
}
(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);
}
// 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);
}
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
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;
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;
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.
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.
}
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;
}
}
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;
}
* 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;
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;
ActivityStack stack;
- if (task != null) {
+ if (task != null && task.stack != null) {
stack = task.stack;
if (stack.isOnHomeDisplay()) {
if (mFocusedStack != stack) {
&& !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
}
} 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);
}
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));
// 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();
}
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);
+ }
}
}
// 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) {
// 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);
} 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);
}