From e09fc6b8d6b20cdb23d79b18d7daad5923019b3d Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Thu, 19 Jan 2017 15:33:36 +0100 Subject: [PATCH] Fix transferring of starting windows Since we may transfer starting data we can not store AppWindowToken in that class. Additionally, remove starting window directly if it was transferred. The normal removing path doesn't really work as the fields aren't set. Also fixes a monkey crash in the same code region. Test: Open a notification that creates multiple activities with using TaskStackBuilder, verify no windows leaking. Test: (For monkey crash) Boot device, pray to the monkey god Change-Id: I64fb176b579535adea1916d1623ad03ab06ca67e Fixes: 34364463 Fixes: 34361417 Fixes: 34349533 --- .../wm/AppWindowContainerController.java | 38 +++++++++---------- .../server/wm/SnapshotStartingData.java | 10 ++--- .../server/wm/SplashScreenStartingData.java | 13 +++---- .../com/android/server/wm/StartingData.java | 7 ++-- 4 files changed, 31 insertions(+), 37 deletions(-) diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index a9007029d929d..34f675226a3b1 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -87,7 +87,6 @@ public class AppWindowContainerController private final Runnable mRemoveStartingWindow = () -> { StartingSurface surface = null; - StartingData data = null; synchronized (mWindowMap) { if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Remove starting " + mContainer + ": startingWindow=" + mContainer.startingWindow @@ -97,14 +96,13 @@ public class AppWindowContainerController } if (mContainer.startingWindow != null) { surface = mContainer.startingSurface; - data = mContainer.startingData; mContainer.startingData = null; mContainer.startingSurface = null; mContainer.startingWindow = null; mContainer.startingDisplayed = false; } } - if (data != null && surface != null) { + if (surface != null) { try { surface.remove(); } catch (Exception e) { @@ -115,12 +113,14 @@ public class AppWindowContainerController private final Runnable mAddStartingWindow = () -> { final StartingData startingData; + final AppWindowToken container; synchronized (mWindowMap) { if (mContainer == null) { return; } startingData = mContainer.startingData; + container = mContainer; } if (startingData == null) { @@ -129,41 +129,40 @@ public class AppWindowContainerController } if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting " - + this + ": startingData=" + mContainer.startingData); + + this + ": startingData=" + container.startingData); StartingSurface surface = null; try { - surface = startingData.createStartingSurface(); + surface = startingData.createStartingSurface(container); } catch (Exception e) { Slog.w(TAG_WM, "Exception when adding starting window", e); } if (surface != null) { boolean abort = false; synchronized(mWindowMap) { - if (mContainer.removed || mContainer.startingData == null) { + if (container.removed || container.startingData == null) { // If the window was successfully added, then // we need to remove it. - if (mContainer.startingWindow != null) { + if (container.startingWindow != null) { if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, - "Aborted starting " + mContainer - + ": removed=" + mContainer.removed - + " startingData=" + mContainer.startingData); + "Aborted starting " + container + + ": removed=" + container.removed + + " startingData=" + container.startingData); + container.startingWindow = null; + container.startingData = null; abort = true; } } else { - mContainer.startingSurface = surface; + container.startingSurface = surface; } if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM, "Added starting " + mContainer + ": startingWindow=" - + mContainer.startingWindow + " startingView=" - + mContainer.startingSurface); + + container.startingWindow + " startingView=" + + container.startingSurface); } if (abort) { - mRemoveStartingWindow.run(); - if (mContainer == null) { - return; - } + surface.remove(); } } }; @@ -465,7 +464,7 @@ public class AppWindowContainerController } if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Creating StartingData"); - mContainer.startingData = new SplashScreenStartingData(mService, mContainer, pkg, theme, + mContainer.startingData = new SplashScreenStartingData(mService, pkg, theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags, mContainer.getMergedOverrideConfiguration()); scheduleAddStartingWindow(); @@ -499,8 +498,7 @@ public class AppWindowContainerController return false; } - mContainer.startingData = new SnapshotStartingData(mService, mContainer, - snapshot.getSnapshot()); + mContainer.startingData = new SnapshotStartingData(mService, snapshot.getSnapshot()); scheduleAddStartingWindow(); return true; } diff --git a/services/core/java/com/android/server/wm/SnapshotStartingData.java b/services/core/java/com/android/server/wm/SnapshotStartingData.java index 9d97a0c3f45e0..e73d4d2559fba 100644 --- a/services/core/java/com/android/server/wm/SnapshotStartingData.java +++ b/services/core/java/com/android/server/wm/SnapshotStartingData.java @@ -27,16 +27,14 @@ class SnapshotStartingData extends StartingData { private final WindowManagerService mService; private final GraphicBuffer mSnapshot; - SnapshotStartingData(WindowManagerService service, AppWindowToken appWindowToken, - GraphicBuffer snapshot) { - super(service, appWindowToken); + SnapshotStartingData(WindowManagerService service, GraphicBuffer snapshot) { + super(service); mService = service; mSnapshot = snapshot; } @Override - StartingSurface createStartingSurface() { - return mService.mTaskSnapshotController.createStartingSurface( - mAppWindowToken, mSnapshot); + StartingSurface createStartingSurface(AppWindowToken atoken) { + return mService.mTaskSnapshotController.createStartingSurface(atoken, mSnapshot); } } diff --git a/services/core/java/com/android/server/wm/SplashScreenStartingData.java b/services/core/java/com/android/server/wm/SplashScreenStartingData.java index 664e600faaf9a..ee4209f4a6a81 100644 --- a/services/core/java/com/android/server/wm/SplashScreenStartingData.java +++ b/services/core/java/com/android/server/wm/SplashScreenStartingData.java @@ -35,11 +35,10 @@ class SplashScreenStartingData extends StartingData { private final int mWindowFlags; private final Configuration mMergedOverrideConfiguration; - SplashScreenStartingData(WindowManagerService service, AppWindowToken appWindowToken, - String pkg, int theme, CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, - int labelRes, int icon, int logo, int windowFlags, - Configuration mergedOverrideConfiguration) { - super(service, appWindowToken); + SplashScreenStartingData(WindowManagerService service, String pkg, int theme, + CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, int icon, + int logo, int windowFlags, Configuration mergedOverrideConfiguration) { + super(service); mPkg = pkg; mTheme = theme; mCompatInfo = compatInfo; @@ -52,8 +51,8 @@ class SplashScreenStartingData extends StartingData { } @Override - StartingSurface createStartingSurface() { - return mService.mPolicy.addSplashScreen(mAppWindowToken.token, mPkg, mTheme, mCompatInfo, + StartingSurface createStartingSurface(AppWindowToken atoken) { + return mService.mPolicy.addSplashScreen(atoken.token, mPkg, mTheme, mCompatInfo, mNonLocalizedLabel, mLabelRes, mIcon, mLogo, mWindowFlags, mMergedOverrideConfiguration); } diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java index fcc4c3c8302df..8c564bb541149 100644 --- a/services/core/java/com/android/server/wm/StartingData.java +++ b/services/core/java/com/android/server/wm/StartingData.java @@ -24,19 +24,18 @@ import android.view.WindowManagerPolicy.StartingSurface; public abstract class StartingData { protected final WindowManagerService mService; - protected final AppWindowToken mAppWindowToken; - protected StartingData(WindowManagerService service, AppWindowToken appWindowToken) { + protected StartingData(WindowManagerService service) { mService = service; - mAppWindowToken = appWindowToken; } /** * Creates the actual starting window surface. DO NOT HOLD THE WINDOW MANAGER LOCK WHEN CALLING * THIS METHOD. * + * @param atoken the app to add the starting window to * @return a class implementing {@link StartingSurface} for easy removal with * {@link StartingSurface#remove} */ - abstract StartingSurface createStartingSurface(); + abstract StartingSurface createStartingSurface(AppWindowToken atoken); } \ No newline at end of file