From 0cd48879dca53a9f4d449126d406527bc4b94baf Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 13 Aug 2009 18:51:59 -0700 Subject: [PATCH] A little more wallpaper robustness. - Recover if a live wallpaper is crashing repeatedly. - Don't crash when someone tries to set a static wallpaper. - Make the static wallpaper update correctly when the image changes. --- .../service/wallpaper/ImageWallpaper.java | 17 +++---- .../server/WallpaperManagerService.java | 45 +++++++++++++++---- .../android/server/WindowManagerService.java | 12 +++-- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java index 7266ee3922474..bfe869669d92d 100644 --- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java +++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java @@ -59,6 +59,7 @@ public class ImageWallpaper extends WallpaperService { class WallpaperObserver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { mEngine.updateWallpaper(); + mEngine.drawFrame(); } } @@ -72,14 +73,7 @@ public class ImageWallpaper extends WallpaperService { @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); - mBackground = mWallpaperManager.getDrawable(); - mBounds.left = mBounds.top = 0; - mBounds.right = mBackground.getIntrinsicWidth(); - mBounds.bottom = mBackground.getIntrinsicHeight(); - int offx = (getDesiredMinimumWidth() - mBounds.right) / 2; - int offy = (getDesiredMinimumHeight() - mBounds.bottom) / 2; - mBounds.offset(offx, offy); - mBackground.setBounds(mBounds); + updateWallpaper(); surfaceHolder.setSizeFromLayout(); } @@ -131,6 +125,13 @@ public class ImageWallpaper extends WallpaperService { void updateWallpaper() { synchronized (mLock) { mBackground = mWallpaperManager.getDrawable(); + mBounds.left = mBounds.top = 0; + mBounds.right = mBackground.getIntrinsicWidth(); + mBounds.bottom = mBackground.getIntrinsicHeight(); + int offx = (getDesiredMinimumWidth() - mBounds.right) / 2; + int offy = (getDesiredMinimumHeight() - mBounds.bottom) / 2; + mBounds.offset(offx, offy); + mBackground.setBounds(mBounds); } } } diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index 9fe4eee053e36..0a313966859a8 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -38,6 +38,7 @@ import android.os.FileObserver; import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.ServiceManager; +import android.os.SystemClock; import android.service.wallpaper.IWallpaperConnection; import android.service.wallpaper.IWallpaperEngine; import android.service.wallpaper.IWallpaperService; @@ -68,10 +69,16 @@ class WallpaperManagerService extends IWallpaperManager.Stub { Object mLock = new Object(); - private static final File WALLPAPER_DIR = new File( + /** + * Minimum time between crashes of a wallpaper service for us to consider + * restarting it vs. just reverting to the static wallpaper. + */ + static final long MIN_WALLPAPER_CRASH_TIME = 10000; + + static final File WALLPAPER_DIR = new File( "/data/data/com.android.settings/files"); - private static final String WALLPAPER = "wallpaper"; - private static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER); + static final String WALLPAPER = "wallpaper"; + static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER); /** * List of callbacks registered they should each be notified @@ -116,6 +123,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub { String mName = ""; ComponentName mWallpaperComponent; WallpaperConnection mWallpaperConnection; + long mLastDiedTime; class WallpaperConnection extends IWallpaperConnection.Stub implements ServiceConnection { @@ -136,6 +144,14 @@ class WallpaperManagerService extends IWallpaperManager.Stub { synchronized (mLock) { mService = null; mEngine = null; + if (mWallpaperConnection == this) { + Log.w(TAG, "Wallpaper service gone: " + mWallpaperComponent); + if ((mLastDiedTime+MIN_WALLPAPER_CRASH_TIME) + < SystemClock.uptimeMillis()) { + Log.w(TAG, "Reverting to built-in wallpaper!"); + bindWallpaperComponentLocked(null); + } + } } } @@ -195,7 +211,12 @@ class WallpaperManagerService extends IWallpaperManager.Stub { if (f.exists()) { f.delete(); } - bindWallpaperComponentLocked(null); + final long ident = Binder.clearCallingIdentity(); + try { + bindWallpaperComponentLocked(null); + } finally { + Binder.restoreCallingIdentity(ident); + } } } @@ -247,12 +268,17 @@ class WallpaperManagerService extends IWallpaperManager.Stub { public ParcelFileDescriptor setWallpaper(String name) { checkPermission(android.Manifest.permission.SET_WALLPAPER); synchronized (mLock) { - ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name); - if (pfd != null) { - bindWallpaperComponentLocked(null); - saveSettingsLocked(); + final long ident = Binder.clearCallingIdentity(); + try { + ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name); + if (pfd != null) { + bindWallpaperComponentLocked(null); + saveSettingsLocked(); + } + return pfd; + } finally { + Binder.restoreCallingIdentity(ident); } - return pfd; } } @@ -341,6 +367,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub { clearWallpaperComponentLocked(); mWallpaperComponent = name; mWallpaperConnection = newConn; + mLastDiedTime = SystemClock.uptimeMillis(); try { if (DEBUG) Log.v(TAG, "Adding window token: " + newConn.mToken); mIWindowManager.addWindowToken(newConn.mToken, diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 2ff73bb8f0240..ac8007169bcc6 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -1194,6 +1194,9 @@ public class WindowManagerService extends IWindowManager.Stub } if (!visible) w = null; + //if (mWallpaperTarget != w) { + // Log.v(TAG, "New wallpaper target: " + w); + //} mWallpaperTarget = w; if (visible) { @@ -6900,10 +6903,10 @@ public class WindowManagerService extends IWindowManager.Stub if (atoken != null) { return mSurface != null && mPolicyVisibility && !mDestroying && ((!mAttachedHidden && !atoken.hiddenRequested) - || mAnimating || atoken.animating); + || mAnimation != null || atoken.animation != null); } else { return mSurface != null && mPolicyVisibility && !mDestroying - && (!mAttachedHidden || mAnimating); + && (!mAttachedHidden || mAnimation != null); } } @@ -6913,10 +6916,11 @@ public class WindowManagerService extends IWindowManager.Stub */ boolean isReadyForDisplay() { final AppWindowToken atoken = mAppToken; - final boolean animating = atoken != null ? atoken.animating : false; + final boolean animating = atoken != null + ? (atoken.animation != null) : false; return mSurface != null && mPolicyVisibility && !mDestroying && ((!mAttachedHidden && !mRootToken.hidden) - || mAnimating || animating); + || mAnimation != null || animating); } /** Is the window or its container currently animating? */