Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3f915e4 authored by Adrian Roos's avatar Adrian Roos
Browse files

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
parent a2153e62
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -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);
                        }
                    }
                }
            }