From c3f915e4824d24b653098ac4410e488e2f646ed9 Mon Sep 17 00:00:00 2001 From: Adrian Roos Date: Tue, 6 Sep 2016 11:40:53 -0700 Subject: [PATCH] Fix black wallpaper after repeated crashes Adds logic to recover from a repeatedly crashing wallpaper. Before, a wallpaper that crashed twice but not within 10s would not trigger the recovery logic in WallpaperManagerService, but would also not be restarted by ActivityManager (because two crashes will effectively disable a service connection), thus resulting in a black wallpaper. Change-Id: Ie4f7862dc07a89d13f5e2b56c825a3371ea21114 Fixes: 30250003 --- .../wallpaper/WallpaperManagerService.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 536e646368d03..5f6800a8d0f2f 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -89,6 +89,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; import com.android.server.EventLogTags; +import com.android.server.FgThread; import com.android.server.SystemService; import libcore.io.IoUtils; @@ -589,6 +590,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { + + /** Time in milliseconds until we expect the wallpaper to reconnect (unless we're in the + * middle of an update). If exceeded, the wallpaper gets reset to the system default. */ + private static final long WALLPAPER_RECONNECT_TIMEOUT_MS = 5000; + final WallpaperInfo mInfo; final Binder mToken = new Binder(); IWallpaperService mService; @@ -599,6 +605,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { boolean mDimensionsChanged = false; boolean mPaddingChanged = false; + private Runnable mResetRunnable = () -> { + synchronized (mLock) { + if (!mWallpaper.wallpaperUpdating + && mWallpaper.userId == mCurrentUserId) { + Slog.w(TAG, "Wallpaper reconnect timed out, " + + "reverting to built-in wallpaper!"); + clearWallpaperLocked(true, FLAG_SYSTEM, mWallpaper.userId, + null); + } + } + }; + public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) { mInfo = info; mWallpaper = wallpaper; @@ -615,6 +633,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { // locking there and anyway we always need to be able to // recover if there is something wrong. saveSettingsLocked(mWallpaper.userId); + FgThread.getHandler().removeCallbacks(mResetRunnable); } } } @@ -641,6 +660,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { clearWallpaperLocked(true, FLAG_SYSTEM, mWallpaper.userId, null); } else { mWallpaper.lastDiedTime = SystemClock.uptimeMillis(); + + // If we didn't reset it right away, do so after we couldn't connect to + // it for an extended amount of time to avoid having a black wallpaper. + FgThread.getHandler().removeCallbacks(mResetRunnable); + FgThread.getHandler().postDelayed(mResetRunnable, + WALLPAPER_RECONNECT_TIMEOUT_MS); } final String flattened = name.flattenToString(); EventLog.writeEvent(EventLogTags.WP_WALLPAPER_CRASHED, @@ -752,6 +777,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { if (wallpaper.wallpaperComponent != null && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) { wallpaper.wallpaperUpdating = true; + if (wallpaper.connection != null) { + FgThread.getHandler().removeCallbacks( + wallpaper.connection.mResetRunnable); + } } } }