Loading packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +91 −51 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region.Op; import android.opengl.GLUtils; import android.os.AsyncTask; import android.os.SystemProperties; import android.renderscript.Matrix4f; import android.service.wallpaper.WallpaperService; Loading Loading @@ -155,6 +156,8 @@ public class ImageWallpaper extends WallpaperService { private int mLastRequestedWidth = -1; private int mLastRequestedHeight = -1; private AsyncTask<Void, Void, Bitmap> mLoader; private boolean mNeedsDrawAfterLoadingWallpaper; public DrawableEngine() { super(); Loading Loading @@ -184,10 +187,9 @@ public class ImageWallpaper extends WallpaperService { super.onCreate(surfaceHolder); mDefaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay(); updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo()); setOffsetNotificationsEnabled(false); updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo(), false /* forDraw */); } @Override Loading @@ -197,17 +199,19 @@ public class ImageWallpaper extends WallpaperService { mWallpaperManager.forgetLoadedWallpaper(); } void updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo) { boolean updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo, boolean forDraw) { boolean hasWallpaper = true; // Load background image dimensions, if we haven't saved them yet if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { // Need to load the image to get dimensions mWallpaperManager.forgetLoadedWallpaper(); updateWallpaperLocked(); if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { // Default to the display size if we can't find the dimensions mBackgroundWidth = displayInfo.logicalWidth; mBackgroundHeight = displayInfo.logicalHeight; loadWallpaper(forDraw); if (DEBUG) { Log.d(TAG, "Reloading, redoing updateSurfaceSize later."); } hasWallpaper = false; } // Force the wallpaper to cover the screen in both dimensions Loading @@ -224,6 +228,7 @@ public class ImageWallpaper extends WallpaperService { } else { surfaceHolder.setSizeFromLayout(); } return hasWallpaper; } @Override Loading Loading @@ -299,6 +304,7 @@ public class ImageWallpaper extends WallpaperService { } super.onSurfaceRedrawNeeded(holder); mLastSurfaceHeight = mLastSurfaceWidth = -1; drawFrame(); } Loading @@ -317,7 +323,9 @@ public class ImageWallpaper extends WallpaperService { // should change if (newRotation != mLastRotation) { // Update surface size (if necessary) updateSurfaceSize(getSurfaceHolder(), displayInfo); if (!updateSurfaceSize(getSurfaceHolder(), displayInfo, true /* forDraw */)) { return; // had to reload wallpaper, will retry later } mRotationAtLastSurfaceSizeUpdate = newRotation; mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth; mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight; Loading @@ -339,8 +347,8 @@ public class ImageWallpaper extends WallpaperService { } mLastRotation = newRotation; // Load bitmap if it is not yet loaded or if it was loaded at a different size if (mBackground == null || surfaceDimensionsChanged) { // Load bitmap if it is not yet loaded if (mBackground == null) { if (DEBUG) { Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " + mBackground + ", " + Loading @@ -349,21 +357,12 @@ public class ImageWallpaper extends WallpaperService { dw + ", " + dh); } mWallpaperManager.forgetLoadedWallpaper(); updateWallpaperLocked(); if (mBackground == null) { loadWallpaper(true /* needDraw */); if (DEBUG) { Log.d(TAG, "Unable to load bitmap"); Log.d(TAG, "Reloading, resuming draw later"); } return; } if (DEBUG) { if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) { Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + dw + ", " + dh + ", " + mBackground.getWidth() + ", " + mBackground.getHeight()); } } } // Center the scaled image mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(), Loading Loading @@ -422,25 +421,32 @@ public class ImageWallpaper extends WallpaperService { } } private void updateWallpaperLocked() { Throwable exception = null; /** * Loads the wallpaper on background thread and schedules updating the surface frame, * and if {@param needsDraw} is set also draws a frame. * * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to * the active request). */ private void loadWallpaper(boolean needsDraw) { mNeedsDrawAfterLoadingWallpaper |= needsDraw; if (mLoader != null) { if (DEBUG) { Log.d(TAG, "Skipping loadWallpaper, already in flight "); } return; } mLoader = new AsyncTask<Void, Void, Bitmap>() { @Override protected Bitmap doInBackground(Void... params) { Throwable exception; try { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; mBackground = mWallpaperManager.getBitmap(); mBackgroundWidth = mBackground.getWidth(); mBackgroundHeight = mBackground.getHeight(); } catch (RuntimeException e) { exception = e; } catch (OutOfMemoryError e) { return mWallpaperManager.getBitmap(); } catch (RuntimeException | OutOfMemoryError e) { exception = e; } if (exception != null) { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; // Note that if we do fail at this, and the default wallpaper can't // be loaded, we will go into a cycle. Don't do a build where the // default wallpaper can't be loaded. Loading @@ -451,7 +457,41 @@ public class ImageWallpaper extends WallpaperService { // now we're really screwed. Log.w(TAG, "Unable reset to default wallpaper!", ex); } try { return mWallpaperManager.getBitmap(); } catch (RuntimeException | OutOfMemoryError e) { Log.w(TAG, "Unable to load default wallpaper!", e); } } return null; } @Override protected void onPostExecute(Bitmap b) { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; if (b != null) { mBackground = b; mBackgroundWidth = mBackground.getWidth(); mBackgroundHeight = mBackground.getHeight(); } if (DEBUG) { Log.d(TAG, "Wallpaper loaded: " + mBackground); } updateSurfaceSize(getSurfaceHolder(), getDefaultDisplayInfo(), false /* forDraw */); if (mNeedsDrawAfterLoadingWallpaper) { drawFrame(); } mLoader = null; mNeedsDrawAfterLoadingWallpaper = false; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +103 −55 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import android.graphics.BitmapFactory; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.DrawableWrapper; import android.os.Bundle; import android.os.AsyncTask; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.RemoteException; Loading @@ -46,9 +46,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private static final String TAG = "LockscreenWallpaper"; private final Context mContext; private final PhoneStatusBar mBar; private final IWallpaperManager mService; private final WallpaperManager mWallpaperManager; private final Handler mH; Loading @@ -58,68 +56,74 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen // The user selected in the UI, or null if no user is selected or UI doesn't support selecting // users. private UserHandle mSelectedUser; private AsyncTask<Void, Void, LoaderResult> mLoader; public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) { mContext = ctx; mBar = bar; mH = h; mService = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); mWallpaperManager = (WallpaperManager) ctx.getSystemService(Context.WALLPAPER_SERVICE); mCurrentUserId = ActivityManager.getCurrentUser(); IWallpaperManager service = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); try { mService.setLockWallpaperCallback(this); service.setLockWallpaperCallback(this); } catch (RemoteException e) { Log.e(TAG, "System dead?" + e); } } public Bitmap getBitmap() { try { if (mCached) { return mCache; } if (!mService.isWallpaperSupported(mContext.getOpPackageName())) { if (!mWallpaperManager.isWallpaperSupported()) { mCached = true; mCache = null; return null; } LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser); if (result.success) { mCached = true; mCache = result.bitmap; } return mCache; } public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) { // May be called on any thread - only use thread safe operations. // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK // wallpaper. final int lockWallpaperUserId = mSelectedUser != null ? mSelectedUser.getIdentifier() : mCurrentUserId; ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_LOCK, new Bundle(), lockWallpaperUserId); selectedUser != null ? selectedUser.getIdentifier() : currentUserId; ParcelFileDescriptor fd = mWallpaperManager.getWallpaperFile( WallpaperManager.FLAG_LOCK, lockWallpaperUserId); if (fd != null) { try { BitmapFactory.Options options = new BitmapFactory.Options(); mCache = BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, options); mCached = true; return mCache; return LoaderResult.success(BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, options)); } catch (OutOfMemoryError e) { Log.w(TAG, "Can't decode file", e); return null; return LoaderResult.fail(); } finally { IoUtils.closeQuietly(fd); } } else { mCached = true; if (mSelectedUser != null && mSelectedUser.getIdentifier() != mCurrentUserId) { if (selectedUser != null && selectedUser.getIdentifier() != currentUserId) { // When selected user is different from the current user, show the selected // user's static wallpaper. mCache = mWallpaperManager.getBitmapAsUser(mSelectedUser.getIdentifier()); return LoaderResult.success( mWallpaperManager.getBitmapAsUser(selectedUser.getIdentifier())); } else { // When there is no selected user, or it's same as the current user, show the // system (possibly dynamic) wallpaper for the selected user. mCache = null; } return mCache; return LoaderResult.success(null); } } catch (RemoteException e) { Log.e(TAG, "System dead?" + e); return null; } } Loading @@ -135,14 +139,16 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen return; } mSelectedUser = selectedUser; mH.removeCallbacks(this); mH.post(this); postUpdateWallpaper(); } @Override public void onWallpaperChanged() { // Called on Binder thread. postUpdateWallpaper(); } private void postUpdateWallpaper() { mH.removeCallbacks(this); mH.post(this); } Loading @@ -150,10 +156,52 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen @Override public void run() { // Called in response to onWallpaperChanged on the main thread. mCached = false; mCache = null; getBitmap(); mBar.updateMediaMetaData(true /* metaDataChanged */, true /* allowEnterAnimation */); if (mLoader != null) { mLoader.cancel(false /* interrupt */); } final int currentUser = mCurrentUserId; final UserHandle selectedUser = mSelectedUser; mLoader = new AsyncTask<Void, Void, LoaderResult>() { @Override protected LoaderResult doInBackground(Void... params) { return loadBitmap(currentUser, selectedUser); } @Override protected void onPostExecute(LoaderResult result) { super.onPostExecute(result); if (isCancelled()) { return; } if (result.success) { mCached = true; mCache = result.bitmap; mBar.updateMediaMetaData( true /* metaDataChanged */, true /* allowEnterAnimation */); } mLoader = null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private static class LoaderResult { public final boolean success; public final Bitmap bitmap; LoaderResult(boolean success, Bitmap bitmap) { this.success = success; this.bitmap = bitmap; } static LoaderResult success(Bitmap b) { return new LoaderResult(true, b); } static LoaderResult fail() { return new LoaderResult(false, null); } } /** Loading Loading
packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +91 −51 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Region.Op; import android.opengl.GLUtils; import android.os.AsyncTask; import android.os.SystemProperties; import android.renderscript.Matrix4f; import android.service.wallpaper.WallpaperService; Loading Loading @@ -155,6 +156,8 @@ public class ImageWallpaper extends WallpaperService { private int mLastRequestedWidth = -1; private int mLastRequestedHeight = -1; private AsyncTask<Void, Void, Bitmap> mLoader; private boolean mNeedsDrawAfterLoadingWallpaper; public DrawableEngine() { super(); Loading Loading @@ -184,10 +187,9 @@ public class ImageWallpaper extends WallpaperService { super.onCreate(surfaceHolder); mDefaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay(); updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo()); setOffsetNotificationsEnabled(false); updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo(), false /* forDraw */); } @Override Loading @@ -197,17 +199,19 @@ public class ImageWallpaper extends WallpaperService { mWallpaperManager.forgetLoadedWallpaper(); } void updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo) { boolean updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo, boolean forDraw) { boolean hasWallpaper = true; // Load background image dimensions, if we haven't saved them yet if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { // Need to load the image to get dimensions mWallpaperManager.forgetLoadedWallpaper(); updateWallpaperLocked(); if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { // Default to the display size if we can't find the dimensions mBackgroundWidth = displayInfo.logicalWidth; mBackgroundHeight = displayInfo.logicalHeight; loadWallpaper(forDraw); if (DEBUG) { Log.d(TAG, "Reloading, redoing updateSurfaceSize later."); } hasWallpaper = false; } // Force the wallpaper to cover the screen in both dimensions Loading @@ -224,6 +228,7 @@ public class ImageWallpaper extends WallpaperService { } else { surfaceHolder.setSizeFromLayout(); } return hasWallpaper; } @Override Loading Loading @@ -299,6 +304,7 @@ public class ImageWallpaper extends WallpaperService { } super.onSurfaceRedrawNeeded(holder); mLastSurfaceHeight = mLastSurfaceWidth = -1; drawFrame(); } Loading @@ -317,7 +323,9 @@ public class ImageWallpaper extends WallpaperService { // should change if (newRotation != mLastRotation) { // Update surface size (if necessary) updateSurfaceSize(getSurfaceHolder(), displayInfo); if (!updateSurfaceSize(getSurfaceHolder(), displayInfo, true /* forDraw */)) { return; // had to reload wallpaper, will retry later } mRotationAtLastSurfaceSizeUpdate = newRotation; mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth; mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight; Loading @@ -339,8 +347,8 @@ public class ImageWallpaper extends WallpaperService { } mLastRotation = newRotation; // Load bitmap if it is not yet loaded or if it was loaded at a different size if (mBackground == null || surfaceDimensionsChanged) { // Load bitmap if it is not yet loaded if (mBackground == null) { if (DEBUG) { Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " + mBackground + ", " + Loading @@ -349,21 +357,12 @@ public class ImageWallpaper extends WallpaperService { dw + ", " + dh); } mWallpaperManager.forgetLoadedWallpaper(); updateWallpaperLocked(); if (mBackground == null) { loadWallpaper(true /* needDraw */); if (DEBUG) { Log.d(TAG, "Unable to load bitmap"); Log.d(TAG, "Reloading, resuming draw later"); } return; } if (DEBUG) { if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) { Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " + dw + ", " + dh + ", " + mBackground.getWidth() + ", " + mBackground.getHeight()); } } } // Center the scaled image mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(), Loading Loading @@ -422,25 +421,32 @@ public class ImageWallpaper extends WallpaperService { } } private void updateWallpaperLocked() { Throwable exception = null; /** * Loads the wallpaper on background thread and schedules updating the surface frame, * and if {@param needsDraw} is set also draws a frame. * * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to * the active request). */ private void loadWallpaper(boolean needsDraw) { mNeedsDrawAfterLoadingWallpaper |= needsDraw; if (mLoader != null) { if (DEBUG) { Log.d(TAG, "Skipping loadWallpaper, already in flight "); } return; } mLoader = new AsyncTask<Void, Void, Bitmap>() { @Override protected Bitmap doInBackground(Void... params) { Throwable exception; try { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; mBackground = mWallpaperManager.getBitmap(); mBackgroundWidth = mBackground.getWidth(); mBackgroundHeight = mBackground.getHeight(); } catch (RuntimeException e) { exception = e; } catch (OutOfMemoryError e) { return mWallpaperManager.getBitmap(); } catch (RuntimeException | OutOfMemoryError e) { exception = e; } if (exception != null) { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; // Note that if we do fail at this, and the default wallpaper can't // be loaded, we will go into a cycle. Don't do a build where the // default wallpaper can't be loaded. Loading @@ -451,7 +457,41 @@ public class ImageWallpaper extends WallpaperService { // now we're really screwed. Log.w(TAG, "Unable reset to default wallpaper!", ex); } try { return mWallpaperManager.getBitmap(); } catch (RuntimeException | OutOfMemoryError e) { Log.w(TAG, "Unable to load default wallpaper!", e); } } return null; } @Override protected void onPostExecute(Bitmap b) { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; if (b != null) { mBackground = b; mBackgroundWidth = mBackground.getWidth(); mBackgroundHeight = mBackground.getHeight(); } if (DEBUG) { Log.d(TAG, "Wallpaper loaded: " + mBackground); } updateSurfaceSize(getSurfaceHolder(), getDefaultDisplayInfo(), false /* forDraw */); if (mNeedsDrawAfterLoadingWallpaper) { drawFrame(); } mLoader = null; mNeedsDrawAfterLoadingWallpaper = false; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +103 −55 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import android.graphics.BitmapFactory; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.DrawableWrapper; import android.os.Bundle; import android.os.AsyncTask; import android.os.Handler; import android.os.ParcelFileDescriptor; import android.os.RemoteException; Loading @@ -46,9 +46,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen private static final String TAG = "LockscreenWallpaper"; private final Context mContext; private final PhoneStatusBar mBar; private final IWallpaperManager mService; private final WallpaperManager mWallpaperManager; private final Handler mH; Loading @@ -58,68 +56,74 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen // The user selected in the UI, or null if no user is selected or UI doesn't support selecting // users. private UserHandle mSelectedUser; private AsyncTask<Void, Void, LoaderResult> mLoader; public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) { mContext = ctx; mBar = bar; mH = h; mService = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); mWallpaperManager = (WallpaperManager) ctx.getSystemService(Context.WALLPAPER_SERVICE); mCurrentUserId = ActivityManager.getCurrentUser(); IWallpaperManager service = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); try { mService.setLockWallpaperCallback(this); service.setLockWallpaperCallback(this); } catch (RemoteException e) { Log.e(TAG, "System dead?" + e); } } public Bitmap getBitmap() { try { if (mCached) { return mCache; } if (!mService.isWallpaperSupported(mContext.getOpPackageName())) { if (!mWallpaperManager.isWallpaperSupported()) { mCached = true; mCache = null; return null; } LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser); if (result.success) { mCached = true; mCache = result.bitmap; } return mCache; } public LoaderResult loadBitmap(int currentUserId, UserHandle selectedUser) { // May be called on any thread - only use thread safe operations. // Prefer the selected user (when specified) over the current user for the FLAG_SET_LOCK // wallpaper. final int lockWallpaperUserId = mSelectedUser != null ? mSelectedUser.getIdentifier() : mCurrentUserId; ParcelFileDescriptor fd = mService.getWallpaper(null, WallpaperManager.FLAG_LOCK, new Bundle(), lockWallpaperUserId); selectedUser != null ? selectedUser.getIdentifier() : currentUserId; ParcelFileDescriptor fd = mWallpaperManager.getWallpaperFile( WallpaperManager.FLAG_LOCK, lockWallpaperUserId); if (fd != null) { try { BitmapFactory.Options options = new BitmapFactory.Options(); mCache = BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, options); mCached = true; return mCache; return LoaderResult.success(BitmapFactory.decodeFileDescriptor( fd.getFileDescriptor(), null, options)); } catch (OutOfMemoryError e) { Log.w(TAG, "Can't decode file", e); return null; return LoaderResult.fail(); } finally { IoUtils.closeQuietly(fd); } } else { mCached = true; if (mSelectedUser != null && mSelectedUser.getIdentifier() != mCurrentUserId) { if (selectedUser != null && selectedUser.getIdentifier() != currentUserId) { // When selected user is different from the current user, show the selected // user's static wallpaper. mCache = mWallpaperManager.getBitmapAsUser(mSelectedUser.getIdentifier()); return LoaderResult.success( mWallpaperManager.getBitmapAsUser(selectedUser.getIdentifier())); } else { // When there is no selected user, or it's same as the current user, show the // system (possibly dynamic) wallpaper for the selected user. mCache = null; } return mCache; return LoaderResult.success(null); } } catch (RemoteException e) { Log.e(TAG, "System dead?" + e); return null; } } Loading @@ -135,14 +139,16 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen return; } mSelectedUser = selectedUser; mH.removeCallbacks(this); mH.post(this); postUpdateWallpaper(); } @Override public void onWallpaperChanged() { // Called on Binder thread. postUpdateWallpaper(); } private void postUpdateWallpaper() { mH.removeCallbacks(this); mH.post(this); } Loading @@ -150,10 +156,52 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen @Override public void run() { // Called in response to onWallpaperChanged on the main thread. mCached = false; mCache = null; getBitmap(); mBar.updateMediaMetaData(true /* metaDataChanged */, true /* allowEnterAnimation */); if (mLoader != null) { mLoader.cancel(false /* interrupt */); } final int currentUser = mCurrentUserId; final UserHandle selectedUser = mSelectedUser; mLoader = new AsyncTask<Void, Void, LoaderResult>() { @Override protected LoaderResult doInBackground(Void... params) { return loadBitmap(currentUser, selectedUser); } @Override protected void onPostExecute(LoaderResult result) { super.onPostExecute(result); if (isCancelled()) { return; } if (result.success) { mCached = true; mCache = result.bitmap; mBar.updateMediaMetaData( true /* metaDataChanged */, true /* allowEnterAnimation */); } mLoader = null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private static class LoaderResult { public final boolean success; public final Bitmap bitmap; LoaderResult(boolean success, Bitmap bitmap) { this.success = success; this.bitmap = bitmap; } static LoaderResult success(Bitmap b) { return new LoaderResult(true, b); } static LoaderResult fail() { return new LoaderResult(false, null); } } /** Loading