Clear app token mAppStopped when app resumes.
It is possible for an activity to be in the stopped state without setting it's visiblility to false in window manager. For example, the home acitivty behind the lock screen. Since the lock screen isn't an activity it doesn't affect the visiblity set of the home activity, so AM doesn't tell WM to hide the app token. However, AM uses another channel to detect that the device is locked and moves the activity into stopped state. WM on the other hand also detects that the device is locked and hides the window surfaces of all windows behind the lock screen. So, at this point AM has also told WM that the activity is stopped. Once you unlock the screen AM resumes the activity but doesn't report any visiblility changes to WM since it's internal state didn't change. So, if you go from the home activity to another app the home activity window will be destroyed before the activity is stopped because mAppStopped is set to true. We now set mAppStopped to false when the activity is resumed. Bug: 27286867 Change-Id: Ic75456d30abd582fa44f932f5aeeb449950157ee
This commit is contained in:
@@ -167,7 +167,7 @@ interface IWindowManager
|
||||
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,
|
||||
int icon, int logo, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
|
||||
void setAppVisibility(IBinder token, boolean visible);
|
||||
void notifyAppStopped(IBinder token);
|
||||
void notifyAppStopped(IBinder token, boolean stopped);
|
||||
void startAppFreezingScreen(IBinder token, int configChanges);
|
||||
void stopAppFreezingScreen(IBinder token, boolean force);
|
||||
void removeAppToken(IBinder token);
|
||||
|
||||
@@ -1115,7 +1115,7 @@ final class ActivityStack {
|
||||
r.stopped = true;
|
||||
r.state = ActivityState.STOPPED;
|
||||
|
||||
mWindowManager.notifyAppStopped(r.appToken);
|
||||
mWindowManager.notifyAppStopped(r.appToken, true);
|
||||
|
||||
if (getVisibleBehindActivity() == r) {
|
||||
mStackSupervisor.requestVisibleBehindLocked(r, false);
|
||||
@@ -2247,6 +2247,10 @@ final class ActivityStack {
|
||||
next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
|
||||
}
|
||||
|
||||
// Well the app will no longer be stopped.
|
||||
// Clear app token stopped state in window manager if needed.
|
||||
mWindowManager.notifyAppStopped(next.appToken, false);
|
||||
|
||||
EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId,
|
||||
System.identityHashCode(next), next.task.taskId, next.shortComponentName);
|
||||
|
||||
|
||||
@@ -354,6 +354,11 @@ class AppWindowToken extends WindowToken {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + win
|
||||
+ " destroySurfaces: mAppStopped=" + mAppStopped
|
||||
+ " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed
|
||||
+ " win.mRemoveOnExit=" + win.mRemoveOnExit);
|
||||
|
||||
win.destroyOrSaveSurface();
|
||||
if (win.mRemoveOnExit) {
|
||||
win.mAnimatingExit = false;
|
||||
@@ -372,15 +377,19 @@ class AppWindowToken extends WindowToken {
|
||||
}
|
||||
}
|
||||
|
||||
// The application has stopped, so destroy any surfaces which were keeping alive
|
||||
// in case they were still being used.
|
||||
void notifyAppStopped() {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
|
||||
mAppStopped = true;
|
||||
destroySurfaces();
|
||||
/**
|
||||
* If the application has stopped it is okay to destroy any surfaces which were keeping alive
|
||||
* in case they were still being used.
|
||||
*/
|
||||
void notifyAppStopped(boolean stopped) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: stopped=" + stopped + " " + this);
|
||||
mAppStopped = stopped;
|
||||
|
||||
// Remove any starting window that was added for this app if they are still around.
|
||||
mTask.mService.scheduleRemoveStartingWindowLocked(this);
|
||||
if (stopped) {
|
||||
destroySurfaces();
|
||||
// Remove any starting window that was added for this app if they are still around.
|
||||
mTask.mService.scheduleRemoveStartingWindowLocked(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4197,7 +4197,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAppStopped(IBinder token) {
|
||||
public void notifyAppStopped(IBinder token, boolean stopped) {
|
||||
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
|
||||
"notifyAppStopped()")) {
|
||||
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
|
||||
@@ -4210,7 +4210,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
|
||||
return;
|
||||
}
|
||||
wtoken.notifyAppStopped();
|
||||
wtoken.notifyAppStopped(stopped);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4247,6 +4247,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
wtoken.appDied = false;
|
||||
wtoken.removeAllWindows();
|
||||
} else if (visible) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(
|
||||
TAG_WM, "No longer Stopped: " + wtoken);
|
||||
wtoken.mAppStopped = false;
|
||||
wtoken.setWindowsExiting(false);
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ public class IWindowManagerImpl implements IWindowManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyAppStopped(IBinder token) throws RemoteException {
|
||||
public void notifyAppStopped(IBinder token, boolean stopped) throws RemoteException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user