Extract crop hint rect from source wallpaper image

Setting the wallpaper is still synchronous: the caller blocks until any
backend cropping/manipulation has completed.  There is a timeout (currently
30 seconds) on that to avoid wedging the caller arbitrarily.

Bug 25454501

Change-Id: Idca2fe1b10e4fa34d6d54865903d9a1b9e305e3c
This commit is contained in:
Christopher Tate
2016-01-25 15:34:36 -08:00
parent d1e2332ea3
commit 1e1e2e013f
3 changed files with 234 additions and 24 deletions

View File

@@ -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.
*/

View File

@@ -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();
}
}
}