diff options
6 files changed, 215 insertions, 166 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3f8d9970723a..7f44f4eb5889 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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; } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 09dc42681269..ca2721c561ff 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -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; } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 9db9f85eab95..8a7e3d3c2c5e 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -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; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 65d2426d61d2..cbbb11a8dfb3 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -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); } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 432abd22aa52..7f2cae49f35b 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -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 { diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 398f0b328f1d..d8d361b0d045 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -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; } } |