Loading core/java/android/app/ActivityThread.java +15 −0 Original line number Diff line number Diff line Loading @@ -4325,6 +4325,21 @@ public final class ActivityThread { r.activity.mChangingConfigurations = true; // If we are preserving the main window across relaunches we would also like to preserve // the children. However the client side view system does not support preserving // the child views so we notify the window manager to expect these windows to // be replaced and defer requests to destroy or hide them. This way we can achieve // visual continuity. It's important that we do this here prior to pause and destroy // as that is when we may hide or remove the child views. try { if (r.mPreserveWindow) { WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token); } } catch (RemoteException e) { // If the system process has died, it's game over for everyone. } // Need to ensure state is saved. if (!r.paused) { performPauseActivity(r.token, false, r.isPreHoneycomb()); Loading core/java/android/view/IWindowSession.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,14 @@ interface IWindowSession { void repositionChild(IWindow childWindow, int left, int top, int right, int bottom, long deferTransactionUntilFrame, out Rect outFrame); /* * Notify the window manager that an application is relaunching and * child windows should be prepared for replacement. * * @param appToken The application */ void prepareToReplaceChildren(IBinder appToken); /** * If a call to relayout() asked to have the surface destroy deferred, * it must call this once it is okay to destroy that surface. Loading services/core/java/com/android/server/wm/AppWindowToken.java +11 −0 Original line number Diff line number Diff line Loading @@ -405,6 +405,17 @@ class AppWindowToken extends WindowToken { } } void setReplacingChildren() { if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + appWindowToken + " with replacing child windows."); for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isChildWindow()) { w.setReplacing(false /* animate */); } } } void resetReplacingWindows() { if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Resetting app token " + appWindowToken + " of replacing window marks."); Loading services/core/java/com/android/server/wm/Session.java +5 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,11 @@ final class Session extends IWindowSession.Stub deferTransactionUntilFrame, outFrame); } @Override public void prepareToReplaceChildren(IBinder appToken) { mService.setReplacingChildren(appToken); } public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Loading services/core/java/com/android/server/wm/WindowManagerService.java +31 −2 Original line number Diff line number Diff line Loading @@ -2693,7 +2693,14 @@ public class WindowManagerService extends IWindowManager.Stub final boolean notExitingOrAnimating = !win.mExiting && !win.isAnimatingWithSavedSurface(); result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; if (notExitingOrAnimating) { // We don't want to animate visibility of windows which are pending // replacement. In the case of activity relaunch child windows // could request visibility changes as they are detached from the main // application window during the tear down process. If we satisfied // these visibility changes though, we would cause a visual glitch // hiding the window before it's replacement was available. // So we just do nothing on our side. if (notExitingOrAnimating && win.mWillReplaceWindow == false) { focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, focusMayChange); Loading Loading @@ -2893,9 +2900,10 @@ public class WindowManagerService extends IWindowManager.Stub try { synchronized (mWindowMap) { WindowState win = windowForClientLocked(session, client, false); if (win == null) { if (win == null || win.mWillReplaceWindow) { return; } win.mWinAnimator.destroyDeferredSurfaceLocked(); } } finally { Loading Loading @@ -10183,6 +10191,27 @@ public class WindowManagerService extends IWindowManager.Stub } } /** * Hint to a token that its children will be replaced across activity relaunch. * The children would otherwise be removed shortly following this as the * activity is torn down. * @param token Application token for which the activity will be relaunched. */ public void setReplacingChildren(IBinder token) { AppWindowToken appWindowToken = null; synchronized (mWindowMap) { appWindowToken = findAppWindowToken(token); if (appWindowToken == null || !appWindowToken.isVisible()) { Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token); return; } appWindowToken.setReplacingChildren(); scheduleClearReplacingWindowIfNeeded(token, true /* replacing */); } } /** * If we're replacing the window, schedule a timer to clear the replaced window * after a timeout, in case the replacing window is not coming. Loading Loading
core/java/android/app/ActivityThread.java +15 −0 Original line number Diff line number Diff line Loading @@ -4325,6 +4325,21 @@ public final class ActivityThread { r.activity.mChangingConfigurations = true; // If we are preserving the main window across relaunches we would also like to preserve // the children. However the client side view system does not support preserving // the child views so we notify the window manager to expect these windows to // be replaced and defer requests to destroy or hide them. This way we can achieve // visual continuity. It's important that we do this here prior to pause and destroy // as that is when we may hide or remove the child views. try { if (r.mPreserveWindow) { WindowManagerGlobal.getWindowSession().prepareToReplaceChildren(r.token); } } catch (RemoteException e) { // If the system process has died, it's game over for everyone. } // Need to ensure state is saved. if (!r.paused) { performPauseActivity(r.token, false, r.isPreHoneycomb()); Loading
core/java/android/view/IWindowSession.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -123,6 +123,14 @@ interface IWindowSession { void repositionChild(IWindow childWindow, int left, int top, int right, int bottom, long deferTransactionUntilFrame, out Rect outFrame); /* * Notify the window manager that an application is relaunching and * child windows should be prepared for replacement. * * @param appToken The application */ void prepareToReplaceChildren(IBinder appToken); /** * If a call to relayout() asked to have the surface destroy deferred, * it must call this once it is okay to destroy that surface. Loading
services/core/java/com/android/server/wm/AppWindowToken.java +11 −0 Original line number Diff line number Diff line Loading @@ -405,6 +405,17 @@ class AppWindowToken extends WindowToken { } } void setReplacingChildren() { if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + appWindowToken + " with replacing child windows."); for (int i = allAppWindows.size() - 1; i >= 0; i--) { final WindowState w = allAppWindows.get(i); if (w.isChildWindow()) { w.setReplacing(false /* animate */); } } } void resetReplacingWindows() { if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Resetting app token " + appWindowToken + " of replacing window marks."); Loading
services/core/java/com/android/server/wm/Session.java +5 −0 Original line number Diff line number Diff line Loading @@ -200,6 +200,11 @@ final class Session extends IWindowSession.Stub deferTransactionUntilFrame, outFrame); } @Override public void prepareToReplaceChildren(IBinder appToken) { mService.setReplacingChildren(appToken); } public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewFlags, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Loading
services/core/java/com/android/server/wm/WindowManagerService.java +31 −2 Original line number Diff line number Diff line Loading @@ -2693,7 +2693,14 @@ public class WindowManagerService extends IWindowManager.Stub final boolean notExitingOrAnimating = !win.mExiting && !win.isAnimatingWithSavedSurface(); result |= notExitingOrAnimating ? RELAYOUT_RES_SURFACE_CHANGED : 0; if (notExitingOrAnimating) { // We don't want to animate visibility of windows which are pending // replacement. In the case of activity relaunch child windows // could request visibility changes as they are detached from the main // application window during the tear down process. If we satisfied // these visibility changes though, we would cause a visual glitch // hiding the window before it's replacement was available. // So we just do nothing on our side. if (notExitingOrAnimating && win.mWillReplaceWindow == false) { focusMayChange = tryStartingAnimation(win, winAnimator, isDefaultDisplay, focusMayChange); Loading Loading @@ -2893,9 +2900,10 @@ public class WindowManagerService extends IWindowManager.Stub try { synchronized (mWindowMap) { WindowState win = windowForClientLocked(session, client, false); if (win == null) { if (win == null || win.mWillReplaceWindow) { return; } win.mWinAnimator.destroyDeferredSurfaceLocked(); } } finally { Loading Loading @@ -10183,6 +10191,27 @@ public class WindowManagerService extends IWindowManager.Stub } } /** * Hint to a token that its children will be replaced across activity relaunch. * The children would otherwise be removed shortly following this as the * activity is torn down. * @param token Application token for which the activity will be relaunched. */ public void setReplacingChildren(IBinder token) { AppWindowToken appWindowToken = null; synchronized (mWindowMap) { appWindowToken = findAppWindowToken(token); if (appWindowToken == null || !appWindowToken.isVisible()) { Slog.w(TAG_WM, "Attempted to set replacing window on non-existing app token " + token); return; } appWindowToken.setReplacingChildren(); scheduleClearReplacingWindowIfNeeded(token, true /* replacing */); } } /** * If we're replacing the window, schedule a timer to clear the replaced window * after a timeout, in case the replacing window is not coming. Loading