Reset deferred task removal when app token added.
A task is scheduled for deletion after the final activity has
been removed and has animated away. But if another activity is then
added to the task the deletion flag must be reset.
Also added improved debugging.
Fixes bug 12987986.
Change-Id: I207ea6e9592a9e036d67aa5d1465b4acc5bdd120
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 76f29cd..e38db58 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1672,7 +1672,8 @@
return view.getParent() != null ? view : null;
} catch (WindowManager.BadTokenException e) {
// ignore
- Log.w(TAG, appToken + " already running, starting window not displayed");
+ Log.w(TAG, appToken + " already running, starting window not displayed. " +
+ e.getMessage());
} catch (RuntimeException e) {
// don't crash if something else bad happens, for example a
// failure loading resources because we are loading from an app
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 036804c..09c4e20 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,11 +16,12 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowManagerService.TAG;
+
import android.util.EventLog;
-import com.android.server.EventLogTags;
+import android.util.Slog;
class Task {
-// private final String TAG = "TaskGroup";
TaskStack mStack;
final AppTokenList mAppTokens = new AppTokenList();
final int taskId;
@@ -39,17 +40,24 @@
}
void addAppToken(int addPos, AppWindowToken wtoken) {
+ final int lastPos = mAppTokens.size();
+ if (addPos > lastPos) {
+ // We lost an app token. Don't crash though.
+ Slog.e(TAG, "Task.addAppToken: Out of bounds attempt token=" + wtoken + " addPos="
+ + addPos + " lastPos=" + lastPos);
+ addPos = lastPos;
+ }
mAppTokens.add(addPos, wtoken);
+ mDeferRemoval = false;
}
boolean removeAppToken(AppWindowToken wtoken) {
- mAppTokens.remove(wtoken);
+ boolean removed = mAppTokens.remove(wtoken);
if (mAppTokens.size() == 0) {
EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId,
"removeAppToken: last token");
- return true;
}
- return false;
+ return removed;
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ebabcef..9557b1b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3486,7 +3486,7 @@
Task task = mTaskIdToTask.get(taskId);
if (task == null) {
- task = createTask(taskId, stackId, userId, atoken);
+ createTask(taskId, stackId, userId, atoken);
} else {
task.addAppToken(addPos, atoken);
}
@@ -3839,27 +3839,23 @@
}
synchronized(mWindowMap) {
- boolean changed = false;
+ final AppWindowToken newFocus;
if (token == null) {
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Clearing focused app, was " + mFocusedApp);
- changed = mFocusedApp != null;
- mFocusedApp = null;
- if (changed) {
- mInputMonitor.setFocusedAppLw(null);
- }
+ newFocus = null;
} else {
- AppWindowToken newFocus = findAppWindowToken(token);
+ newFocus = findAppWindowToken(token);
if (newFocus == null) {
Slog.w(TAG, "Attempted to set focus to non-existing app token: " + token);
- return;
}
- changed = mFocusedApp != newFocus;
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG, "Set focused app to: " + newFocus
+ " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
+ }
+
+ final boolean changed = mFocusedApp != newFocus;
+ if (changed) {
mFocusedApp = newFocus;
- if (changed) {
- mInputMonitor.setFocusedAppLw(newFocus);
- }
+ mInputMonitor.setFocusedAppLw(null);
}
if (moveFocusNow && changed) {
@@ -4543,11 +4539,9 @@
void removeAppFromTaskLocked(AppWindowToken wtoken) {
final Task task = mTaskIdToTask.get(wtoken.groupId);
if (task != null) {
- task.removeAppToken(wtoken);
- // Remove after bug resolved.
- Slog.d(TAG, "removeAppFromTaskLocked: wtoken=" + wtoken
- + " numTokens left=" + task.mAppTokens.size()
- + " Callers=" + Debug.getCallers(5));
+ if (!task.removeAppToken(wtoken)) {
+ Slog.e(TAG, "removeAppFromTaskLocked: token=" + wtoken + " not found.");
+ }
}
}
@@ -4583,6 +4577,8 @@
TAG, "Removing app " + wtoken + " delayed=" + delayed
+ " animation=" + wtoken.mAppAnimator.animation
+ " animating=" + wtoken.mAppAnimator.animating);
+ if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: "
+ + wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
final TaskStack stack = mTaskIdToTask.get(wtoken.groupId).mStack;
if (delayed) {
// set the token aside because it has an active animation to be finished
@@ -4598,9 +4594,6 @@
wtoken.mAppAnimator.animating = false;
removeAppFromTaskLocked(wtoken);
}
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
- "removeAppToken: " + wtoken);
-
wtoken.removed = true;
if (wtoken.startingData != null) {