diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/IWallpaperManager.aidl | 14 | ||||
| -rw-r--r-- | core/java/android/app/WallpaperManager.java | 46 |
2 files changed, 53 insertions, 7 deletions
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 7a0e7f616295..fa0fbd1cb8fa 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -35,10 +35,16 @@ interface IWallpaperManager { * 'which' is some combination of: * FLAG_SET_SYSTEM * FLAG_SET_LOCK + * + * A 'null' cropHint rectangle is explicitly permitted as a sentinel for "whatever + * the source image's bounding rect is." + * + * The completion callback's "onWallpaperChanged()" method is invoked when the + * new wallpaper content is ready to display. */ ParcelFileDescriptor setWallpaper(String name, in String callingPackage, - out Bundle extras, int which); - + in Rect cropHint, out Bundle extras, int which, IWallpaperManagerCallback completion); + /** * Set the live wallpaper. This only affects the system wallpaper. */ @@ -54,14 +60,14 @@ interface IWallpaperManager { */ ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, out Bundle outParams); - + /** * If the current system wallpaper is a live wallpaper component, return the * information about that wallpaper. Otherwise, if it is a static image, * simply return null. */ WallpaperInfo getWallpaperInfo(); - + /** * Clear the system wallpaper. */ diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index f1035767ad7b..b0ffd21b2c98 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -64,6 +64,8 @@ import java.io.InputStream; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Provides access to the system wallpaper. With WallpaperManager, you can @@ -770,18 +772,26 @@ public class WallpaperManager { return 0; } final Bundle result = new Bundle(); + final WallpaperSetCompletion completion = new WallpaperSetCompletion(); try { Resources resources = mContext.getResources(); /* Set the wallpaper to the default values */ ParcelFileDescriptor fd = sGlobals.mService.setWallpaper( "res:" + resources.getResourceName(resid), - mContext.getOpPackageName(), result, which); + mContext.getOpPackageName(), null, result, which, completion); if (fd != null) { FileOutputStream fos = null; + boolean ok = false; try { fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd); copyStreamToWallpaperFile(resources.openRawResource(resid), fos); + // The 'close()' is the trigger for any server-side image manipulation, + // so we must do that before waiting for completion. + fos.close(); + completion.waitForCompletion(); } finally { + // Might be redundant but completion shouldn't wait unless the write + // succeeded; this is a fallback if it threw past the close+wait. IoUtils.closeQuietly(fos); } } @@ -876,14 +886,17 @@ public class WallpaperManager { return 0; } final Bundle result = new Bundle(); + final WallpaperSetCompletion completion = new WallpaperSetCompletion(); try { ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null, - mContext.getOpPackageName(), result, which); + mContext.getOpPackageName(), visibleCropHint, result, which, completion); if (fd != null) { FileOutputStream fos = null; try { fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd); fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos); + fos.close(); + completion.waitForCompletion(); } finally { IoUtils.closeQuietly(fos); } @@ -990,14 +1003,17 @@ public class WallpaperManager { return 0; } final Bundle result = new Bundle(); + final WallpaperSetCompletion completion = new WallpaperSetCompletion(); try { ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null, - mContext.getOpPackageName(), result, which); + mContext.getOpPackageName(), visibleCropHint, result, which, completion); if (fd != null) { FileOutputStream fos = null; try { fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd); copyStreamToWallpaperFile(bitmapData, fos); + fos.close(); + completion.waitForCompletion(); } finally { IoUtils.closeQuietly(fos); } @@ -1385,4 +1401,28 @@ public class WallpaperManager { return null; } + + // Private completion callback for setWallpaper() synchronization + private class WallpaperSetCompletion extends IWallpaperManagerCallback.Stub { + final CountDownLatch mLatch; + + public WallpaperSetCompletion() { + mLatch = new CountDownLatch(1); + } + + public void waitForCompletion() { + try { + mLatch.await(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + // This might be legit: the crop may take a very long time. Don't sweat + // it in that case; we are okay with display lagging behind in order to + // keep the caller from locking up indeterminately. + } + } + + @Override + public void onWallpaperChanged() throws RemoteException { + mLatch.countDown(); + } + } } |
