Optimizations for current wallpaper preview
Cache bitmaps more aggressively in BitmapCachingAsset, and
CurrentWallpaperAsset.
Also make WallpaperConnection and WallpaperSurfaceCallback not depend
on Activity
Bug: 184111918
Test: manual
Change-Id: I077f98e9a65759e32fd1896c67fe241ee8f68d1a
diff --git a/src/com/android/wallpaper/asset/BitmapCachingAsset.java b/src/com/android/wallpaper/asset/BitmapCachingAsset.java
index 62222f4..7674d4c 100644
--- a/src/com/android/wallpaper/asset/BitmapCachingAsset.java
+++ b/src/com/android/wallpaper/asset/BitmapCachingAsset.java
@@ -37,27 +37,37 @@
public class BitmapCachingAsset extends Asset {
private static class CacheKey {
- final Asset asset;
- final int width;
- final int height;
+ final Asset mAsset;
+ final int mWidth;
+ final int mHeight;
+ final boolean mRtl;
+ final Rect mRect;
CacheKey(Asset asset, int width, int height) {
- this.asset = asset;
- this.width = width;
- this.height = height;
+ this(asset, width, height, false, null);
+ }
+
+ CacheKey(Asset asset, int width, int height, boolean rtl, Rect rect) {
+ mAsset = asset;
+ mWidth = width;
+ mHeight = height;
+ mRtl = rtl;
+ mRect = rect;
}
@Override
public int hashCode() {
- return Objects.hash(asset, width, height);
+ return Objects.hash(mAsset, mWidth, mHeight);
}
@Override
public boolean equals(Object obj) {
return obj instanceof CacheKey
- && ((CacheKey)obj).asset == this.asset
- && ((CacheKey)obj).width == this.width
- && ((CacheKey)obj).height == this.height;
+ && (Objects.equals(this.mAsset, ((CacheKey) obj).mAsset))
+ && ((CacheKey) obj).mWidth == this.mWidth
+ && ((CacheKey) obj).mHeight == this.mHeight
+ && ((CacheKey) obj).mRtl == this.mRtl
+ && (Objects.equals(this.mRect, ((CacheKey) obj).mRect));
}
}
@@ -72,7 +82,8 @@
private final Asset mOriginalAsset;
public BitmapCachingAsset(Context context, Asset originalAsset) {
- mOriginalAsset = originalAsset;
+ mOriginalAsset = originalAsset instanceof BitmapCachingAsset
+ ? ((BitmapCachingAsset) originalAsset).mOriginalAsset : originalAsset;
mIsLowRam = ActivityManagerCompat.isLowRamDevice(
(ActivityManager) context.getApplicationContext().getSystemService(
Context.ACTIVITY_SERVICE));
@@ -102,8 +113,26 @@
@Override
public void decodeBitmapRegion(Rect rect, int targetWidth, int targetHeight,
boolean shouldAdjustForRtl, BitmapReceiver receiver) {
- mOriginalAsset.decodeBitmapRegion(rect, targetWidth, targetHeight, shouldAdjustForRtl,
- receiver);
+ // Skip the cache in low ram devices
+ if (mIsLowRam) {
+ mOriginalAsset.decodeBitmapRegion(rect, targetWidth, targetHeight, shouldAdjustForRtl,
+ receiver);
+ return;
+ }
+ CacheKey key = new CacheKey(mOriginalAsset, targetWidth, targetHeight, shouldAdjustForRtl,
+ rect);
+ Bitmap cached = sCache.get(key);
+ if (cached != null) {
+ receiver.onBitmapDecoded(cached);
+ } else {
+ mOriginalAsset.decodeBitmapRegion(rect, targetWidth, targetHeight, shouldAdjustForRtl,
+ bitmap -> {
+ if (bitmap != null) {
+ sCache.put(key, bitmap);
+ }
+ receiver.onBitmapDecoded(bitmap);
+ });
+ }
}
@Override
diff --git a/src/com/android/wallpaper/asset/CurrentWallpaperAssetV16.java b/src/com/android/wallpaper/asset/CurrentWallpaperAssetV16.java
index 86b88a5..530c3a7 100755
--- a/src/com/android/wallpaper/asset/CurrentWallpaperAssetV16.java
+++ b/src/com/android/wallpaper/asset/CurrentWallpaperAssetV16.java
@@ -33,6 +33,7 @@
private static final boolean FILTER_SCALED_BITMAP = true;
private Context mApplicationContext;
+ private Drawable mCurrentWallpaperDrawable;
public CurrentWallpaperAssetV16(Context context) {
mApplicationContext = context.getApplicationContext();
@@ -62,17 +63,19 @@
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
- private Drawable getCurrentWallpaperDrawable() {
- WallpaperManager wallpaperManager = WallpaperManager.getInstance(mApplicationContext);
- Drawable drawable;
- try {
- drawable = wallpaperManager.getDrawable();
- } catch (java.lang.SecurityException e) {
- // Work around Samsung bug where SecurityException is thrown if device is still using its
- // default wallpaper.
- drawable = wallpaperManager.getBuiltInDrawable();
+ private synchronized Drawable getCurrentWallpaperDrawable() {
+ if (mCurrentWallpaperDrawable != null) {
+ return mCurrentWallpaperDrawable;
}
- return drawable;
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(mApplicationContext);
+ try {
+ mCurrentWallpaperDrawable = wallpaperManager.getDrawable();
+ } catch (java.lang.SecurityException e) {
+ // Work around Samsung bug where SecurityException is thrown if device is still using
+ // its default wallpaper.
+ mCurrentWallpaperDrawable = wallpaperManager.getBuiltInDrawable();
+ }
+ return mCurrentWallpaperDrawable;
}
/**
diff --git a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
index dbe3722..9e2787f 100755
--- a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
+++ b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java
@@ -51,7 +51,8 @@
@Override
public synchronized void createCurrentWallpaperInfos(final WallpaperInfoCallback callback,
boolean forceRefresh) {
- if (!forceRefresh && mHomeWallpaper != null) {
+ if (!forceRefresh && mHomeWallpaper != null
+ && mPresentationMode != WallpaperPreferences.PRESENTATION_MODE_ROTATING) {
callback.onWallpaperInfoCreated(mHomeWallpaper, mLockWallpaper, mPresentationMode);
return;
}
diff --git a/src/com/android/wallpaper/util/WallpaperConnection.java b/src/com/android/wallpaper/util/WallpaperConnection.java
index a31cfad..b161db7 100644
--- a/src/com/android/wallpaper/util/WallpaperConnection.java
+++ b/src/com/android/wallpaper/util/WallpaperConnection.java
@@ -20,7 +20,6 @@
import static android.graphics.Matrix.MSKEW_X;
import static android.graphics.Matrix.MSKEW_Y;
-import android.app.Activity;
import android.app.WallpaperColors;
import android.content.ComponentName;
import android.content.Context;
@@ -35,10 +34,10 @@
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceControl;
import android.view.SurfaceView;
-import android.view.View;
import android.view.WindowManager.LayoutParams;
import androidx.annotation.Nullable;
@@ -61,7 +60,7 @@
}
private static final String TAG = "WallpaperConnection";
- private final Activity mActivity;
+ private final Context mContext;
private final Intent mIntent;
private final WallpaperConnectionListener mListener;
private final SurfaceView mContainerView;
@@ -75,27 +74,27 @@
/**
* @param intent used to bind the wallpaper service
- * @param activity Activity that owns the window where the wallpaper is rendered
+ * @param context Context used to start and bind the live wallpaper service
* @param listener if provided, it'll be notified of connection/disconnection events
* @param containerView SurfaceView that will display the wallpaper
*/
- public WallpaperConnection(Intent intent, Activity activity,
+ public WallpaperConnection(Intent intent, Context context,
@Nullable WallpaperConnectionListener listener, SurfaceView containerView) {
- this(intent, activity, listener, containerView, null);
+ this(intent, context, listener, containerView, null);
}
/**
* @param intent used to bind the wallpaper service
- * @param activity Activity that owns the window where the wallpaper is rendered
+ * @param context Context used to start and bind the live wallpaper service
* @param listener if provided, it'll be notified of connection/disconnection events
* @param containerView SurfaceView that will display the wallpaper
* @param secondaryContainerView optional SurfaceView that will display a second, mirrored
* version of the wallpaper
*/
- public WallpaperConnection(Intent intent, Activity activity,
+ public WallpaperConnection(Intent intent, Context context,
@Nullable WallpaperConnectionListener listener, SurfaceView containerView,
@Nullable SurfaceView secondaryContainerView) {
- mActivity = activity;
+ mContext = context.getApplicationContext();
mIntent = intent;
mListener = listener;
mContainerView = containerView;
@@ -110,7 +109,7 @@
if (mConnected) {
return true;
}
- if (!mActivity.bindService(mIntent, this,
+ if (!mContext.bindService(mIntent, this,
Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
return false;
}
@@ -140,7 +139,7 @@
mEngine = null;
}
try {
- mActivity.unbindService(this);
+ mContext.unbindService(this);
} catch (IllegalArgumentException e) {
Log.i(TAG, "Can't unbind wallpaper service. "
+ "It might have crashed, just ignoring.");
@@ -158,10 +157,9 @@
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IWallpaperService.Stub.asInterface(service);
try {
- View root = mActivity.getWindow().getDecorView();
- int displayId = root.getDisplay().getDisplayId();
+ int displayId = mContainerView.getDisplay().getDisplayId();
- mService.attach(this, root.getWindowToken(),
+ mService.attach(this, mContainerView.getWindowToken(),
LayoutParams.TYPE_APPLICATION_MEDIA,
true, mContainerView.getWidth(), mContainerView.getHeight(),
new Rect(0, 0, 0, 0), displayId);
@@ -229,7 +227,7 @@
@Override
public void onWallpaperColorsChanged(WallpaperColors colors, int displayId) {
- mActivity.runOnUiThread(() -> {
+ mContainerView.post(() -> {
if (mListener != null) {
mListener.onWallpaperColorsChanged(colors, displayId);
}
@@ -246,7 +244,7 @@
reparentWallpaperSurface(mSecondContainerView);
}
- mActivity.runOnUiThread(() -> {
+ mContainerView.post(() -> {
if (mListener != null) {
mListener.onEngineShown();
}
@@ -299,9 +297,10 @@
Matrix m = new Matrix();
float[] values = new float[9];
Rect surfacePosition = parentSurface.getHolder().getSurfaceFrame();
- View decorView = mActivity.getWindow().getDecorView();
- m.postScale(((float) surfacePosition.width()) / decorView.getWidth(),
- ((float) surfacePosition.height()) / decorView.getHeight());
+ DisplayMetrics metrics = DisplayMetricsRetriever.getInstance().getDisplayMetrics(
+ mContainerView.getResources(), mContainerView.getDisplay());
+ m.postScale(((float) surfacePosition.width()) / metrics.widthPixels,
+ ((float) surfacePosition.height()) / metrics.heightPixels);
m.getValues(values);
return values;
}
diff --git a/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java b/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
index 7984f21..9855b21 100644
--- a/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
+++ b/src/com/android/wallpaper/util/WallpaperSurfaceCallback.java
@@ -65,8 +65,8 @@
private PackageStatusNotifier mPackageStatusNotifier;
public WallpaperSurfaceCallback(Context context, View containerView,
- SurfaceView wallpaperSurface, @Nullable SurfaceListener listener) {
- mContext = context;
+ SurfaceView wallpaperSurface, @Nullable SurfaceListener listener) {
+ mContext = context.getApplicationContext();
mContainerView = containerView;
mWallpaperSurface = wallpaperSurface;
mListener = listener;
@@ -152,7 +152,7 @@
if (forceClean) {
releaseHost();
mHost = new SurfaceControlViewHost(mContext,
- mContext.getDisplay(), mWallpaperSurface.getHostToken());
+ mContainerView.getDisplay(), mWallpaperSurface.getHostToken());
}
mHost.setView(mHomeImageWallpaper, mHomeImageWallpaper.getWidth(),
mHomeImageWallpaper.getHeight());