Loading iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +7 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.os.UserHandle; import androidx.annotation.NonNull; import com.android.launcher3.icons.BitmapInfo.Extender; /** * This class will be moved to androidx library. There shouldn't be any dependency outside * this package. Loading Loading @@ -342,7 +344,11 @@ public class BaseIconFactory implements AutoCloseable { int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size), Math.round(size * (1 - scale) / 2 )); icon.setBounds(offset, offset, size - offset, size - offset); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).drawForPersistence(mCanvas); } else { icon.draw(mCanvas); } } else { if (icon instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; Loading iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +31 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,12 @@ package com.android.launcher3.icons; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class BitmapInfo { Loading @@ -45,6 +49,14 @@ public class BitmapInfo { return LOW_RES_ICON == icon; } /** * Returns a serialized version of BitmapInfo */ @Nullable public byte[] toByteArray() { return isNullOrLowRes() ? null : GraphicsUtils.flattenBitmap(icon); } /** * Creates a drawable for the provided BitmapInfo */ Loading @@ -56,6 +68,23 @@ public class BitmapInfo { return drawable; } /** * Returns a BitmapInfo previously serialized using {@link #toByteArray()}; */ @NonNull public static BitmapInfo fromByteArray(byte[] data, int color) { BitmapFactory.Options decodeOptions; if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { decodeOptions = new BitmapFactory.Options(); decodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; } else { decodeOptions = null; } return BitmapInfo.of( BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions), color); } public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap) { return of(bitmap, 0); } Loading @@ -77,8 +106,8 @@ public class BitmapInfo { } /** * Notifies the drawable that it will be drawn directly in the UI, without any preprocessing * Called to draw the UI independent of any runtime configurations like time or theme */ default void prepareToDrawOnUi() { } default void drawForPersistence(Canvas canvas) { } } } iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java +13 −1 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap foreground.setDrawable(info.secondLayerIndex, null); info.secondLayerIndex = INVALID_VALUE; } info.applyTime(Calendar.getInstance(), foreground); return wrapper; } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); Loading @@ -149,10 +150,21 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } @Override public void prepareToDrawOnUi() { public void drawForPersistence(Canvas canvas) { LayerDrawable foreground = (LayerDrawable) getForeground(); resetLevel(foreground, mAnimationInfo.hourLayerIndex); resetLevel(foreground, mAnimationInfo.minuteLayerIndex); resetLevel(foreground, mAnimationInfo.secondLayerIndex); draw(canvas); mAnimationInfo.applyTime(Calendar.getInstance(), (LayerDrawable) getForeground()); } private void resetLevel(LayerDrawable drawable, int index) { if (index != INVALID_VALUE) { drawable.getDrawable(index).setLevel(0); } } private static class AnimationInfo { public ConstantState baseDrawableState; Loading iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +39 −37 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; Loading @@ -34,13 +35,12 @@ import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.SafeCloseable; import java.util.Calendar; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Supplier; /** * Class to handle icon loading from different packages Loading @@ -57,13 +57,6 @@ public class IconProvider { // Default value returned if there are problems getting resources. private static final int NO_ID = 0; private static final BiFunction<LauncherActivityInfo, Integer, Drawable> LAI_LOADER = LauncherActivityInfo::getIcon; private static final BiFunction<ActivityInfo, PackageManager, Drawable> AI_LOADER = ActivityInfo::loadUnbadgedIcon; private final Context mContext; private final ComponentName mCalendar; private final ComponentName mClock; Loading @@ -86,59 +79,69 @@ public class IconProvider { } } /** * Loads the icon for the provided LauncherActivityInfo such that it can be drawn directly * on the UI */ public Drawable getIconForUI(LauncherActivityInfo info, int iconDpi) { Drawable icon = getIcon(info, iconDpi); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).prepareToDrawOnUi(); } return icon; } /** * Loads the icon for the provided ActivityInfo such that it can be drawn directly * on the UI * @deprecated Use {@link #getIcon} */ public Drawable getIconForUI(ActivityInfo info, UserHandle user) { Drawable icon = getIcon(info); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).prepareToDrawOnUi(); } return icon; return getIcon(info); } /** * Loads the icon for the provided LauncherActivityInfo */ public Drawable getIcon(LauncherActivityInfo info, int iconDpi) { return getIcon(info.getApplicationInfo().packageName, info.getUser(), info, iconDpi, LAI_LOADER); return getIconWithOverrides(info.getApplicationInfo().packageName, info.getUser(), iconDpi, () -> info.getIcon(iconDpi)); } /** * Loads the icon for the provided activity info */ public Drawable getIcon(ActivityInfo info) { return getIcon(info.applicationInfo.packageName, return getIcon(info, mContext.getResources().getConfiguration().densityDpi); } /** * Loads the icon for the provided activity info */ public Drawable getIcon(ActivityInfo info, int iconDpi) { return getIconWithOverrides(info.applicationInfo.packageName, UserHandle.getUserHandleForUid(info.applicationInfo.uid), info, mContext.getPackageManager(), AI_LOADER); iconDpi, () -> loadActivityInfoIcon(info, iconDpi)); } private <T, P> Drawable getIcon(String packageName, UserHandle user, T obj, P param, BiFunction<T, P, Drawable> loader) { private Drawable getIconWithOverrides(String packageName, UserHandle user, int iconDpi, Supplier<Drawable> fallback) { Drawable icon = null; if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { icon = loadCalendarDrawable(0); icon = loadCalendarDrawable(iconDpi); } else if (mClock != null && mClock.getPackageName().equals(packageName) && Process.myUserHandle().equals(user)) { icon = loadClockDrawable(0); icon = loadClockDrawable(iconDpi); } return icon == null ? loader.apply(obj, param) : icon; return icon == null ? fallback.get() : icon; } private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { final int iconRes = ai.getIconResource(); Drawable icon = null; // Get the preferred density icon from the app's resources if (density != 0 && iconRes != 0) { try { final Resources resources = mContext.getPackageManager() .getResourcesForApplication(ai.applicationInfo); icon = resources.getDrawableForDensity(iconRes, density); } catch (NameNotFoundException | Resources.NotFoundException exc) { } } // Get the default density icon if (icon == null) { icon = ai.loadIcon(mContext.getPackageManager()); } return icon; } private Drawable loadCalendarDrawable(int iconDpi) { Loading Loading @@ -203,7 +206,6 @@ public class IconProvider { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } /** * Registers a callback to listen for calendar icon changes. * The callback receives the packageName for the calendar icon Loading iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +5 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; Loading @@ -49,8 +48,6 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.SQLiteCacheHelper; Loading Loading @@ -94,7 +91,6 @@ public abstract class BaseIconCache { protected String mSystemState = ""; private final String mDbFileName; private final BitmapFactory.Options mDecodeOptions; private final Looper mBgLooper; public BaseIconCache(Context context, String dbFileName, Looper bgLooper, Loading Loading @@ -122,13 +118,6 @@ public abstract class BaseIconCache { }; } if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mDecodeOptions = new BitmapFactory.Options(); mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; } else { mDecodeOptions = null; } updateSystemState(); mIconDpi = iconDpi; mIconDb = new IconDB(context, dbFileName, iconPixelSize); Loading Loading @@ -492,10 +481,10 @@ public abstract class BaseIconCache { if (!lowRes) { byte[] data = c.getBlob(2); try { entry.bitmap = BitmapInfo.of( BitmapFactory.decodeByteArray(data, 0, data.length, mDecodeOptions), entry.bitmap.color); } catch (Exception e) { } entry.bitmap = BitmapInfo.fromByteArray(data, entry.bitmap.color); } catch (Exception e) { return false; } } return true; } Loading Loading @@ -564,8 +553,7 @@ public abstract class BaseIconCache { private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName, @Nullable String keywords) { ContentValues values = new ContentValues(); values.put(IconDB.COLUMN_ICON, bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon)); values.put(IconDB.COLUMN_ICON, bitmapInfo.toByteArray()); values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color); values.put(IconDB.COLUMN_LABEL, label); Loading Loading
iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +7 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.os.UserHandle; import androidx.annotation.NonNull; import com.android.launcher3.icons.BitmapInfo.Extender; /** * This class will be moved to androidx library. There shouldn't be any dependency outside * this package. Loading Loading @@ -342,7 +344,11 @@ public class BaseIconFactory implements AutoCloseable { int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size), Math.round(size * (1 - scale) / 2 )); icon.setBounds(offset, offset, size - offset, size - offset); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).drawForPersistence(mCanvas); } else { icon.draw(mCanvas); } } else { if (icon instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; Loading
iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +31 −2 Original line number Diff line number Diff line Loading @@ -18,8 +18,12 @@ package com.android.launcher3.icons; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.os.Build; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class BitmapInfo { Loading @@ -45,6 +49,14 @@ public class BitmapInfo { return LOW_RES_ICON == icon; } /** * Returns a serialized version of BitmapInfo */ @Nullable public byte[] toByteArray() { return isNullOrLowRes() ? null : GraphicsUtils.flattenBitmap(icon); } /** * Creates a drawable for the provided BitmapInfo */ Loading @@ -56,6 +68,23 @@ public class BitmapInfo { return drawable; } /** * Returns a BitmapInfo previously serialized using {@link #toByteArray()}; */ @NonNull public static BitmapInfo fromByteArray(byte[] data, int color) { BitmapFactory.Options decodeOptions; if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { decodeOptions = new BitmapFactory.Options(); decodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; } else { decodeOptions = null; } return BitmapInfo.of( BitmapFactory.decodeByteArray(data, 0, data.length, decodeOptions), color); } public static BitmapInfo fromBitmap(@NonNull Bitmap bitmap) { return of(bitmap, 0); } Loading @@ -77,8 +106,8 @@ public class BitmapInfo { } /** * Notifies the drawable that it will be drawn directly in the UI, without any preprocessing * Called to draw the UI independent of any runtime configurations like time or theme */ default void prepareToDrawOnUi() { } default void drawForPersistence(Canvas canvas) { } } }
iconloaderlib/src/com/android/launcher3/icons/ClockDrawableWrapper.java +13 −1 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap foreground.setDrawable(info.secondLayerIndex, null); info.secondLayerIndex = INVALID_VALUE; } info.applyTime(Calendar.getInstance(), foreground); return wrapper; } catch (Exception e) { Log.d(TAG, "Unable to load clock drawable info", e); Loading @@ -149,10 +150,21 @@ public class ClockDrawableWrapper extends AdaptiveIconDrawable implements Bitmap } @Override public void prepareToDrawOnUi() { public void drawForPersistence(Canvas canvas) { LayerDrawable foreground = (LayerDrawable) getForeground(); resetLevel(foreground, mAnimationInfo.hourLayerIndex); resetLevel(foreground, mAnimationInfo.minuteLayerIndex); resetLevel(foreground, mAnimationInfo.secondLayerIndex); draw(canvas); mAnimationInfo.applyTime(Calendar.getInstance(), (LayerDrawable) getForeground()); } private void resetLevel(LayerDrawable drawable, int index) { if (index != INVALID_VALUE) { drawable.getDrawable(index).setLevel(0); } } private static class AnimationInfo { public ConstantState baseDrawableState; Loading
iconloaderlib/src/com/android/launcher3/icons/IconProvider.java +39 −37 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.LauncherActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Bundle; Loading @@ -34,13 +35,12 @@ import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.SafeCloseable; import java.util.Calendar; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Supplier; /** * Class to handle icon loading from different packages Loading @@ -57,13 +57,6 @@ public class IconProvider { // Default value returned if there are problems getting resources. private static final int NO_ID = 0; private static final BiFunction<LauncherActivityInfo, Integer, Drawable> LAI_LOADER = LauncherActivityInfo::getIcon; private static final BiFunction<ActivityInfo, PackageManager, Drawable> AI_LOADER = ActivityInfo::loadUnbadgedIcon; private final Context mContext; private final ComponentName mCalendar; private final ComponentName mClock; Loading @@ -86,59 +79,69 @@ public class IconProvider { } } /** * Loads the icon for the provided LauncherActivityInfo such that it can be drawn directly * on the UI */ public Drawable getIconForUI(LauncherActivityInfo info, int iconDpi) { Drawable icon = getIcon(info, iconDpi); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).prepareToDrawOnUi(); } return icon; } /** * Loads the icon for the provided ActivityInfo such that it can be drawn directly * on the UI * @deprecated Use {@link #getIcon} */ public Drawable getIconForUI(ActivityInfo info, UserHandle user) { Drawable icon = getIcon(info); if (icon instanceof BitmapInfo.Extender) { ((Extender) icon).prepareToDrawOnUi(); } return icon; return getIcon(info); } /** * Loads the icon for the provided LauncherActivityInfo */ public Drawable getIcon(LauncherActivityInfo info, int iconDpi) { return getIcon(info.getApplicationInfo().packageName, info.getUser(), info, iconDpi, LAI_LOADER); return getIconWithOverrides(info.getApplicationInfo().packageName, info.getUser(), iconDpi, () -> info.getIcon(iconDpi)); } /** * Loads the icon for the provided activity info */ public Drawable getIcon(ActivityInfo info) { return getIcon(info.applicationInfo.packageName, return getIcon(info, mContext.getResources().getConfiguration().densityDpi); } /** * Loads the icon for the provided activity info */ public Drawable getIcon(ActivityInfo info, int iconDpi) { return getIconWithOverrides(info.applicationInfo.packageName, UserHandle.getUserHandleForUid(info.applicationInfo.uid), info, mContext.getPackageManager(), AI_LOADER); iconDpi, () -> loadActivityInfoIcon(info, iconDpi)); } private <T, P> Drawable getIcon(String packageName, UserHandle user, T obj, P param, BiFunction<T, P, Drawable> loader) { private Drawable getIconWithOverrides(String packageName, UserHandle user, int iconDpi, Supplier<Drawable> fallback) { Drawable icon = null; if (mCalendar != null && mCalendar.getPackageName().equals(packageName)) { icon = loadCalendarDrawable(0); icon = loadCalendarDrawable(iconDpi); } else if (mClock != null && mClock.getPackageName().equals(packageName) && Process.myUserHandle().equals(user)) { icon = loadClockDrawable(0); icon = loadClockDrawable(iconDpi); } return icon == null ? loader.apply(obj, param) : icon; return icon == null ? fallback.get() : icon; } private Drawable loadActivityInfoIcon(ActivityInfo ai, int density) { final int iconRes = ai.getIconResource(); Drawable icon = null; // Get the preferred density icon from the app's resources if (density != 0 && iconRes != 0) { try { final Resources resources = mContext.getPackageManager() .getResourcesForApplication(ai.applicationInfo); icon = resources.getDrawableForDensity(iconRes, density); } catch (NameNotFoundException | Resources.NotFoundException exc) { } } // Get the default density icon if (icon == null) { icon = ai.loadIcon(mContext.getPackageManager()); } return icon; } private Drawable loadCalendarDrawable(int iconDpi) { Loading Loading @@ -203,7 +206,6 @@ public class IconProvider { return Calendar.getInstance().get(Calendar.DAY_OF_MONTH) - 1; } /** * Registers a callback to listen for calendar icon changes. * The callback receives the packageName for the calendar icon Loading
iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +5 −17 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; Loading @@ -49,8 +48,6 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.SQLiteCacheHelper; Loading Loading @@ -94,7 +91,6 @@ public abstract class BaseIconCache { protected String mSystemState = ""; private final String mDbFileName; private final BitmapFactory.Options mDecodeOptions; private final Looper mBgLooper; public BaseIconCache(Context context, String dbFileName, Looper bgLooper, Loading Loading @@ -122,13 +118,6 @@ public abstract class BaseIconCache { }; } if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mDecodeOptions = new BitmapFactory.Options(); mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE; } else { mDecodeOptions = null; } updateSystemState(); mIconDpi = iconDpi; mIconDb = new IconDB(context, dbFileName, iconPixelSize); Loading Loading @@ -492,10 +481,10 @@ public abstract class BaseIconCache { if (!lowRes) { byte[] data = c.getBlob(2); try { entry.bitmap = BitmapInfo.of( BitmapFactory.decodeByteArray(data, 0, data.length, mDecodeOptions), entry.bitmap.color); } catch (Exception e) { } entry.bitmap = BitmapInfo.fromByteArray(data, entry.bitmap.color); } catch (Exception e) { return false; } } return true; } Loading Loading @@ -564,8 +553,7 @@ public abstract class BaseIconCache { private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName, @Nullable String keywords) { ContentValues values = new ContentValues(); values.put(IconDB.COLUMN_ICON, bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon)); values.put(IconDB.COLUMN_ICON, bitmapInfo.toByteArray()); values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color); values.put(IconDB.COLUMN_LABEL, label); Loading