Loading core/java/android/view/IWindowManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ 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, boolean stopped); void notifyAppResumed(IBinder token, boolean wasStopped); void notifyAppStopped(IBinder token); void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); Loading services/core/java/com/android/server/am/ActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -1249,7 +1249,7 @@ final class ActivityStack { r.stopped = true; r.state = ActivityState.STOPPED; mWindowManager.notifyAppStopped(r.appToken, true); mWindowManager.notifyAppStopped(r.appToken); if (getVisibleBehindActivity() == r) { mStackSupervisor.requestVisibleBehindLocked(r, false); Loading Loading @@ -2490,7 +2490,7 @@ final class ActivityStack { // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. mWindowManager.notifyAppStopped(next.appToken, false); mWindowManager.notifyAppResumed(next.appToken, next.stopped); EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.task.taskId, next.shortComponentName); Loading services/core/java/com/android/server/wm/AppWindowToken.java +46 −15 Original line number Diff line number Diff line Loading @@ -337,21 +337,41 @@ class AppWindowToken extends WindowToken { } } // Here we destroy surfaces which have been marked as eligible by the animator, taking care // to ensure the client has finished with them. If the client could still be using them // we will skip destruction and try again when the client has stopped. void destroySurfaces() { destroySurfaces(false /*cleanupOnResume*/); } /** * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure * the client has finished with them. * * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If * set to true, destroy only surfaces of removed windows, and clear relevant flags of the * others so that they are ready to be reused. If set to false (common case), destroy all * surfaces that's eligible, if the app is already stopped. */ private void destroySurfaces(boolean cleanupOnResume) { final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) allAppWindows.clone(); final DisplayContentList displayList = new DisplayContentList(); for (int i = allWindows.size() - 1; i >= 0; i--) { final WindowState win = allWindows.get(i); if (!(mAppStopped || win.mWindowRemovalAllowed)) { if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) { continue; } win.mWinAnimator.destroyPreservedSurfaceLocked(); if (cleanupOnResume) { // If the window has an unfinished exit animation, consider that animation // done and mark the window destroying so that it goes through the cleanup. if (win.mAnimatingExit) { win.mDestroying = true; win.mAnimatingExit = false; } } if (!win.mDestroying) { continue; } Loading @@ -361,7 +381,9 @@ class AppWindowToken extends WindowToken { + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed + " win.mRemoveOnExit=" + win.mRemoveOnExit); if (!cleanupOnResume || win.mRemoveOnExit) { win.destroyOrSaveSurface(); } if (win.mRemoveOnExit) { service.removeWindowInnerLocked(win); } Loading @@ -379,19 +401,28 @@ class AppWindowToken extends WindowToken { } /** * If the application has stopped it is okay to destroy any surfaces which were keeping alive * in case they were still being used. * Notify that the app is now resumed, and it was not stopped before, perform a clean * up of the surfaces */ void notifyAppStopped(boolean stopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: stopped=" + stopped + " " + this); mAppStopped = stopped; void notifyAppResumed(boolean wasStopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this); mAppStopped = false; if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } } if (stopped) { /** * Notify that the app has stopped, and it is okay to 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(); // Remove any starting window that was added for this app if they are still around. mTask.mService.scheduleRemoveStartingWindowLocked(this); } } /** * Checks whether we should save surfaces for this app. Loading services/core/java/com/android/server/wm/WindowManagerService.java +21 −3 Original line number Diff line number Diff line Loading @@ -4476,7 +4476,25 @@ public class WindowManagerService extends IWindowManager.Stub } @Override public void notifyAppStopped(IBinder token, boolean stopped) { public void notifyAppResumed(IBinder token, boolean wasStopped) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "notifyAppResumed()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized(mWindowMap) { final AppWindowToken wtoken; wtoken = findAppWindowToken(token); if (wtoken == null) { Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token); return; } wtoken.notifyAppResumed(wasStopped); } } @Override public void notifyAppStopped(IBinder token) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "notifyAppStopped()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); Loading @@ -4486,10 +4504,10 @@ public class WindowManagerService extends IWindowManager.Stub final AppWindowToken wtoken; wtoken = findAppWindowToken(token); if (wtoken == null) { Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token); Slog.w(TAG_WM, "Attempted to notify stopped of non-existing app token: " + token); return; } wtoken.notifyAppStopped(stopped); wtoken.notifyAppStopped(); } } Loading tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +6 −1 Original line number Diff line number Diff line Loading @@ -351,7 +351,12 @@ public class IWindowManagerImpl implements IWindowManager { } @Override public void notifyAppStopped(IBinder token, boolean stopped) throws RemoteException { public void notifyAppResumed(IBinder token, boolean wasStopped) throws RemoteException { // TODO Auto-generated method stub } @Override public void notifyAppStopped(IBinder token) throws RemoteException { // TODO Auto-generated method stub } Loading Loading
core/java/android/view/IWindowManager.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -173,7 +173,8 @@ 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, boolean stopped); void notifyAppResumed(IBinder token, boolean wasStopped); void notifyAppStopped(IBinder token); void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); void removeAppToken(IBinder token); Loading
services/core/java/com/android/server/am/ActivityStack.java +2 −2 Original line number Diff line number Diff line Loading @@ -1249,7 +1249,7 @@ final class ActivityStack { r.stopped = true; r.state = ActivityState.STOPPED; mWindowManager.notifyAppStopped(r.appToken, true); mWindowManager.notifyAppStopped(r.appToken); if (getVisibleBehindActivity() == r) { mStackSupervisor.requestVisibleBehindLocked(r, false); Loading Loading @@ -2490,7 +2490,7 @@ final class ActivityStack { // Well the app will no longer be stopped. // Clear app token stopped state in window manager if needed. mWindowManager.notifyAppStopped(next.appToken, false); mWindowManager.notifyAppResumed(next.appToken, next.stopped); EventLog.writeEvent(EventLogTags.AM_RESUME_ACTIVITY, next.userId, System.identityHashCode(next), next.task.taskId, next.shortComponentName); Loading
services/core/java/com/android/server/wm/AppWindowToken.java +46 −15 Original line number Diff line number Diff line Loading @@ -337,21 +337,41 @@ class AppWindowToken extends WindowToken { } } // Here we destroy surfaces which have been marked as eligible by the animator, taking care // to ensure the client has finished with them. If the client could still be using them // we will skip destruction and try again when the client has stopped. void destroySurfaces() { destroySurfaces(false /*cleanupOnResume*/); } /** * Destroy surfaces which have been marked as eligible by the animator, taking care to ensure * the client has finished with them. * * @param cleanupOnResume whether this is done when app is resumed without fully stopped. If * set to true, destroy only surfaces of removed windows, and clear relevant flags of the * others so that they are ready to be reused. If set to false (common case), destroy all * surfaces that's eligible, if the app is already stopped. */ private void destroySurfaces(boolean cleanupOnResume) { final ArrayList<WindowState> allWindows = (ArrayList<WindowState>) allAppWindows.clone(); final DisplayContentList displayList = new DisplayContentList(); for (int i = allWindows.size() - 1; i >= 0; i--) { final WindowState win = allWindows.get(i); if (!(mAppStopped || win.mWindowRemovalAllowed)) { if (!(mAppStopped || win.mWindowRemovalAllowed || cleanupOnResume)) { continue; } win.mWinAnimator.destroyPreservedSurfaceLocked(); if (cleanupOnResume) { // If the window has an unfinished exit animation, consider that animation // done and mark the window destroying so that it goes through the cleanup. if (win.mAnimatingExit) { win.mDestroying = true; win.mAnimatingExit = false; } } if (!win.mDestroying) { continue; } Loading @@ -361,7 +381,9 @@ class AppWindowToken extends WindowToken { + " win.mWindowRemovalAllowed=" + win.mWindowRemovalAllowed + " win.mRemoveOnExit=" + win.mRemoveOnExit); if (!cleanupOnResume || win.mRemoveOnExit) { win.destroyOrSaveSurface(); } if (win.mRemoveOnExit) { service.removeWindowInnerLocked(win); } Loading @@ -379,19 +401,28 @@ class AppWindowToken extends WindowToken { } /** * If the application has stopped it is okay to destroy any surfaces which were keeping alive * in case they were still being used. * Notify that the app is now resumed, and it was not stopped before, perform a clean * up of the surfaces */ void notifyAppStopped(boolean stopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: stopped=" + stopped + " " + this); mAppStopped = stopped; void notifyAppResumed(boolean wasStopped) { if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppResumed: wasStopped=" + wasStopped + " " + this); mAppStopped = false; if (!wasStopped) { destroySurfaces(true /*cleanupOnResume*/); } } if (stopped) { /** * Notify that the app has stopped, and it is okay to 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(); // Remove any starting window that was added for this app if they are still around. mTask.mService.scheduleRemoveStartingWindowLocked(this); } } /** * Checks whether we should save surfaces for this app. Loading
services/core/java/com/android/server/wm/WindowManagerService.java +21 −3 Original line number Diff line number Diff line Loading @@ -4476,7 +4476,25 @@ public class WindowManagerService extends IWindowManager.Stub } @Override public void notifyAppStopped(IBinder token, boolean stopped) { public void notifyAppResumed(IBinder token, boolean wasStopped) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "notifyAppResumed()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized(mWindowMap) { final AppWindowToken wtoken; wtoken = findAppWindowToken(token); if (wtoken == null) { Slog.w(TAG_WM, "Attempted to notify resumed of non-existing app token: " + token); return; } wtoken.notifyAppResumed(wasStopped); } } @Override public void notifyAppStopped(IBinder token) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "notifyAppStopped()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); Loading @@ -4486,10 +4504,10 @@ public class WindowManagerService extends IWindowManager.Stub final AppWindowToken wtoken; wtoken = findAppWindowToken(token); if (wtoken == null) { Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token); Slog.w(TAG_WM, "Attempted to notify stopped of non-existing app token: " + token); return; } wtoken.notifyAppStopped(stopped); wtoken.notifyAppStopped(); } } Loading
tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +6 −1 Original line number Diff line number Diff line Loading @@ -351,7 +351,12 @@ public class IWindowManagerImpl implements IWindowManager { } @Override public void notifyAppStopped(IBinder token, boolean stopped) throws RemoteException { public void notifyAppResumed(IBinder token, boolean wasStopped) throws RemoteException { // TODO Auto-generated method stub } @Override public void notifyAppStopped(IBinder token) throws RemoteException { // TODO Auto-generated method stub } Loading