From 739e1941217b0882560f78169e1456b1909a2d10 Mon Sep 17 00:00:00 2001 From: riddle_hsu Date: Wed, 26 Mar 2014 20:43:17 +0800 Subject: DO NOT MERGE - [ActivityManager] Ensure consistency behavior when a background activity brings another existed activity to front. Symptom: ANR occurs on previous activity. Root Cause: In KK, when a background activity starts another existed background activity (bring to front), if current focused stack is not the same as the stack of target starting activity, it will still resume the top of target stack, even the top activity on the target stack may not the same as target activity. And it will result incorrect focus, press back key will send to previous stack's top then popup ANR on previous activity: "Reason: Waiting because no window has focus but there is a focused application". By original code comment, it looks 'bring to front' should not happen in this issue case. // If the target task is not in the front, then we need // to bring it to the front... except... well, with // SINGLE_TASK_LAUNCH it's not entirely clear. We'd like // to have the same behavior as if a new instance was // being started, which means not bringing it to the front // if the caller is not itself in the front. If the caller and target are in the same stask, it will just deliver new intent without changing task order (the same behavior as JellyBean). So the patch concept is just to avoid to use target stack to resume top when caller and target are in different stack. Solution: Do not allow to resume another stack top if non-top activity try to bring existed activity to front. It may not be a good solution, just a reminder for the issue case. Reproduce steps: Assume A, B, C are different app tasks. When the application stack is like: Top C B A #Case 1: Home is foreground A starts B with NEW_TASK, C will resume, focus still stays at Home, and window order does not update. Then press back key or volumn key will result ANR on Home. #Case 2: App is foreground (Resumed activity is C) A starts Home, Home will resume, focus still stays at C, and window order does did not update. Then press back key or volumn key will result ANR on C. Change-Id: If05070123b248e2335791e43a4d4ddee6db11d84 --- .../java/com/android/server/am/ActivityStackSupervisor.java | 10 ++++++++++ 1 file changed, 10 insertions(+) mode change 100644 => 100755 services/java/com/android/server/am/ActivityStackSupervisor.java (limited to 'services') diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java old mode 100644 new mode 100755 index 483b4a0..93de0a6 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -1425,6 +1425,7 @@ public final class ActivityStackSupervisor { r.resultTo = null; } + boolean switchStackFromBg = false; boolean addingToTask = false; boolean movedHome = false; TaskRecord reuseTask = null; @@ -1486,6 +1487,11 @@ public final class ActivityStackSupervisor { } options = null; } + } else { + switchStackFromBg = lastStack != targetStack; + if (DEBUG_TASKS) Slog.d(TAG, "Caller " + sourceRecord + + " is not top task, it may not move " + r + + " to front, switchStack=" + switchStackFromBg); } // If the caller has requested that the target task be // reset, then do so. @@ -1593,6 +1599,10 @@ public final class ActivityStackSupervisor { // don't use that intent!) And for paranoia, make // sure we have correctly resumed the top activity. if (doResume) { + if (switchStackFromBg) { + moveHomeStack(lastStack.isHomeStack()); + targetStack = lastStack; + } targetStack.resumeTopActivityLocked(null, options); } else { ActivityOptions.abort(options); -- cgit v1.1