Merge "Prevent exception when stack being removed on crash" into pi-dev am: 6acf543681
am: 756a886015
Change-Id: Ife9d23460a925b466d8f243bd51819d77f2f7e47
This commit is contained in:
@@ -3544,7 +3544,15 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
|
||||
mService.updateOomAdjLocked();
|
||||
}
|
||||
|
||||
final TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
|
||||
/**
|
||||
* Finish the topmost activity that belongs to the crashed app. We may also finish the activity
|
||||
* that requested launch of the crashed one to prevent launch-crash loop.
|
||||
* @param app The app that crashed.
|
||||
* @param reason Reason to perform this action.
|
||||
* @return The task that was finished in this stack, {@code null} if top running activity does
|
||||
* not belong to the crashed app.
|
||||
*/
|
||||
final TaskRecord finishTopCrashedActivityLocked(ProcessRecord app, String reason) {
|
||||
ActivityRecord r = topRunningActivityLocked();
|
||||
TaskRecord finishedTask = null;
|
||||
if (r == null || r.app != app) {
|
||||
|
||||
@@ -2126,15 +2126,22 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
|
||||
}
|
||||
}
|
||||
|
||||
TaskRecord finishTopRunningActivityLocked(ProcessRecord app, String reason) {
|
||||
/**
|
||||
* Finish the topmost activities in all stacks that belong to the crashed app.
|
||||
* @param app The app that crashed.
|
||||
* @param reason Reason to perform this action.
|
||||
* @return The task that was finished in this stack, {@code null} if haven't found any.
|
||||
*/
|
||||
TaskRecord finishTopCrashedActivitiesLocked(ProcessRecord app, String reason) {
|
||||
TaskRecord finishedTask = null;
|
||||
ActivityStack focusedStack = getFocusedStack();
|
||||
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
|
||||
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
|
||||
final int numStacks = display.getChildCount();
|
||||
for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
|
||||
// It is possible that request to finish activity might also remove its task and stack,
|
||||
// so we need to be careful with indexes in the loop and check child count every time.
|
||||
for (int stackNdx = 0; stackNdx < display.getChildCount(); ++stackNdx) {
|
||||
final ActivityStack stack = display.getChildAt(stackNdx);
|
||||
TaskRecord t = stack.finishTopRunningActivityLocked(app, reason);
|
||||
final TaskRecord t = stack.finishTopCrashedActivityLocked(app, reason);
|
||||
if (stack == focusedStack || finishedTask == null) {
|
||||
finishedTask = t;
|
||||
}
|
||||
|
||||
@@ -742,8 +742,8 @@ class AppErrors {
|
||||
}
|
||||
mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
|
||||
} else {
|
||||
TaskRecord affectedTask =
|
||||
mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason);
|
||||
final TaskRecord affectedTask =
|
||||
mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app, reason);
|
||||
if (data != null) {
|
||||
data.task = affectedTask;
|
||||
}
|
||||
|
||||
@@ -265,4 +265,26 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
|
||||
// Supervisor should skip over the non-existent display.
|
||||
assertEquals(null, mSupervisor.topRunningActivityLocked());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that removal of activity with task and stack is done correctly.
|
||||
*/
|
||||
@Test
|
||||
public void testRemovingStackOnAppCrash() throws Exception {
|
||||
final ActivityDisplay defaultDisplay = mService.mStackSupervisor.getDefaultDisplay();
|
||||
final int originalStackCount = defaultDisplay.getChildCount();
|
||||
final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
|
||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
|
||||
final ActivityRecord firstActivity = new ActivityBuilder(mService).setCreateTask(true)
|
||||
.setStack(stack).build();
|
||||
|
||||
assertEquals(originalStackCount + 1, defaultDisplay.getChildCount());
|
||||
|
||||
// Let's pretend that the app has crashed.
|
||||
firstActivity.app.thread = null;
|
||||
mService.mStackSupervisor.finishTopCrashedActivitiesLocked(firstActivity.app, "test");
|
||||
|
||||
// Verify that the stack was removed.
|
||||
assertEquals(originalStackCount, defaultDisplay.getChildCount());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user