Loading iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +39 −4 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import static android.graphics.Paint.FILTER_BITMAP_FLAG; import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFraction; import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT; import static com.android.launcher3.icons.BitmapInfo.FLAG_WORK; import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR; import android.annotation.TargetApi; Loading @@ -27,11 +28,13 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; import android.os.Build; import android.os.UserHandle; import android.util.SparseBooleanArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.util.FlagOp; /** * This class will be moved to androidx library. There shouldn't be any dependency outside Loading @@ -44,6 +47,7 @@ public class BaseIconFactory implements AutoCloseable { private static final float ICON_BADGE_SCALE = 0.444f; private final Rect mOldBounds = new Rect(); private final SparseBooleanArray mIsUserBadged = new SparseBooleanArray(); protected final Context mContext; private final Canvas mCanvas; private final PackageManager mPm; Loading Loading @@ -206,13 +210,33 @@ public class BaseIconFactory implements AutoCloseable { this); } } info = info.withFlags(getBitmapFlagOp(options)); return info; } public FlagOp getBitmapFlagOp(@Nullable IconOptions options) { FlagOp op = FlagOp.NO_OP; if (options != null) { if (options.mIsInstantApp) { info.flags |= FLAG_INSTANT; op = op.addFlag(FLAG_INSTANT); } info.withUser(options.mUserHandle); if (options.mUserHandle != null) { int key = options.mUserHandle.hashCode(); boolean isBadged; int index; if ((index = mIsUserBadged.indexOfKey(key)) >= 0) { isBadged = mIsUserBadged.valueAt(index); } else { // Check packageManager if the provided user needs a badge NoopDrawable d = new NoopDrawable(); isBadged = (d != mPm.getUserBadgedIcon(d, options.mUserHandle)); mIsUserBadged.put(key, isBadged); } op = op.setFlag(FLAG_WORK, isBadged); } return info; } return op; } /** package private */ Loading Loading @@ -390,7 +414,6 @@ public class BaseIconFactory implements AutoCloseable { boolean mIsInstantApp; UserHandle mUserHandle; /** * Set to false if non-adaptive icons should not be treated */ Loading Loading @@ -437,4 +460,16 @@ public class BaseIconFactory implements AutoCloseable { return getBitmap().getWidth(); } } private static class NoopDrawable extends ColorDrawable { @Override public int getIntrinsicHeight() { return 1; } @Override public int getIntrinsicWidth() { return 1; } } } iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +15 −15 Original line number Diff line number Diff line Loading @@ -19,14 +19,13 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.os.Process; import android.os.UserHandle; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.util.FlagOp; public class BitmapInfo { static final int FLAG_WORK = 1 << 0; Loading Loading @@ -71,10 +70,23 @@ public class BitmapInfo { return result; } /** * Returns a bitmapInfo with the flagOP applied */ public BitmapInfo withFlags(@NonNull FlagOp op) { if (op == FlagOp.NO_OP) { return this; } BitmapInfo result = clone(); result.flags = op.apply(result.flags); return result; } protected BitmapInfo copyInternalsTo(BitmapInfo target) { target.mMono = mMono; target.mWhiteShadowLayer = mWhiteShadowLayer; target.flags = flags; target.badgeInfo = badgeInfo; return target; } Loading @@ -88,18 +100,6 @@ public class BitmapInfo { mWhiteShadowLayer = iconFactory.getWhiteShadowLayer(); } /** * Ensures that the BitmapInfo represents the provided user */ public BitmapInfo withUser(UserHandle userHandle) { if (userHandle == null || Process.myUserHandle().equals(userHandle)) { flags &= ~FLAG_WORK; } else { flags |= FLAG_WORK; } return this; } /** * Ideally icon should not be null, except in cases when generating hardware bitmap failed */ Loading iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +27 −8 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.os.Trace; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -58,6 +59,7 @@ import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BaseIconFactory.IconOptions; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.SQLiteCacheHelper; import java.nio.ByteBuffer; Loading Loading @@ -100,6 +102,7 @@ public abstract class BaseIconCache { protected String mSystemState = ""; private BitmapInfo mDefaultIcon; private final SparseArray<FlagOp> mUserFlagOpMap = new SparseArray<>(); private final String mDbFileName; private final Looper mBgLooper; Loading Loading @@ -157,6 +160,7 @@ public abstract class BaseIconCache { private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) { mIconDpi = iconDpi; mDefaultIcon = null; mUserFlagOpMap.clear(); mIconDb.clear(); mIconDb.close(); mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize); Loading Loading @@ -304,7 +308,21 @@ public abstract class BaseIconCache { mDefaultIcon = li.makeDefaultIcon(); } } return mDefaultIcon.clone().withUser(user); return mDefaultIcon.withFlags(getUserFlagOpLocked(user)); } private FlagOp getUserFlagOpLocked(UserHandle user) { int key = user.hashCode(); int index; if ((index = mUserFlagOpMap.indexOfKey(key)) >= 0) { return mUserFlagOpMap.valueAt(index); } else { try (BaseIconFactory li = getIconFactory()) { FlagOp op = li.getBitmapFlagOp(new IconOptions().setUser(user)); mUserFlagOpMap.put(key, op); return op; } } } public boolean isDefaultIcon(BitmapInfo icon, UserHandle user) { Loading Loading @@ -346,8 +364,8 @@ public abstract class BaseIconCache { T object = null; boolean providerFetchedOnce = false; boolean cacheEntryUpdated = cursor == null ? getEntryFromDB(cacheKey, entry, useLowResIcon) : updateTitleAndIcon(cacheKey, entry, cursor, useLowResIcon); ? getEntryFromDBLocked(cacheKey, entry, useLowResIcon) : updateTitleAndIconLocked(cacheKey, entry, cursor, useLowResIcon); if (!cacheEntryUpdated) { object = infoProvider.get(); providerFetchedOnce = true; Loading Loading @@ -442,7 +460,7 @@ public abstract class BaseIconCache { boolean entryUpdated = true; // Check the DB first. if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { if (!getEntryFromDBLocked(cacheKey, entry, useLowResIcon)) { try { int flags = Process.myUserHandle().equals(user) ? 0 : PackageManager.GET_UNINSTALLED_PACKAGES; Loading Loading @@ -486,7 +504,8 @@ public abstract class BaseIconCache { return entry; } protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { protected boolean getEntryFromDBLocked( ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { Cursor c = null; Trace.beginSection("loadIconIndividually"); try { Loading @@ -497,7 +516,7 @@ public abstract class BaseIconCache { cacheKey.componentName.flattenToString(), Long.toString(getSerialNumberForUser(cacheKey.user))}); if (c.moveToNext()) { return updateTitleAndIcon(cacheKey, entry, c, lowRes); return updateTitleAndIconLocked(cacheKey, entry, c, lowRes); } } catch (SQLiteException e) { Log.d(TAG, "Error reading icon cache", e); Loading @@ -510,7 +529,7 @@ public abstract class BaseIconCache { return false; } private boolean updateTitleAndIcon( private boolean updateTitleAndIconLocked( ComponentKey cacheKey, CacheEntry entry, Cursor c, boolean lowRes) { // Set the alpha to be 255, so that we never have a wrong color entry.bitmap = BitmapInfo.of(LOW_RES_ICON, Loading Loading @@ -552,7 +571,7 @@ public abstract class BaseIconCache { } } entry.bitmap.flags = c.getInt(IconDB.INDEX_FLAGS); entry.bitmap.withUser(cacheKey.user); entry.bitmap = entry.bitmap.withFlags(getUserFlagOpLocked(cacheKey.user)); return entry.bitmap != null; } Loading iconloaderlib/src/com/android/launcher3/util/FlagOp.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /** * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; /** * Utility interface for representing flag operations */ public interface FlagOp { FlagOp NO_OP = i -> i; int apply(int flags); /** * Returns a new OP which adds the provided flag after applying all previous operations */ default FlagOp addFlag(int flag) { return i -> apply(i) | flag; } /** * Returns a new OP which removes the provided flag after applying all previous operations */ default FlagOp removeFlag(int flag) { return i -> apply(i) & ~flag; } /** * Returns a new OP which adds or removed the provided flag based on {@code enable} after * applying all previous operations */ default FlagOp setFlag(int flag, boolean enable) { return enable ? addFlag(flag) : removeFlag(flag); } } Loading
iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java +39 −4 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ import static android.graphics.Paint.FILTER_BITMAP_FLAG; import static android.graphics.drawable.AdaptiveIconDrawable.getExtraInsetFraction; import static com.android.launcher3.icons.BitmapInfo.FLAG_INSTANT; import static com.android.launcher3.icons.BitmapInfo.FLAG_WORK; import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR; import android.annotation.TargetApi; Loading @@ -27,11 +28,13 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; import android.os.Build; import android.os.UserHandle; import android.util.SparseBooleanArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.icons.BitmapInfo.Extender; import com.android.launcher3.util.FlagOp; /** * This class will be moved to androidx library. There shouldn't be any dependency outside Loading @@ -44,6 +47,7 @@ public class BaseIconFactory implements AutoCloseable { private static final float ICON_BADGE_SCALE = 0.444f; private final Rect mOldBounds = new Rect(); private final SparseBooleanArray mIsUserBadged = new SparseBooleanArray(); protected final Context mContext; private final Canvas mCanvas; private final PackageManager mPm; Loading Loading @@ -206,13 +210,33 @@ public class BaseIconFactory implements AutoCloseable { this); } } info = info.withFlags(getBitmapFlagOp(options)); return info; } public FlagOp getBitmapFlagOp(@Nullable IconOptions options) { FlagOp op = FlagOp.NO_OP; if (options != null) { if (options.mIsInstantApp) { info.flags |= FLAG_INSTANT; op = op.addFlag(FLAG_INSTANT); } info.withUser(options.mUserHandle); if (options.mUserHandle != null) { int key = options.mUserHandle.hashCode(); boolean isBadged; int index; if ((index = mIsUserBadged.indexOfKey(key)) >= 0) { isBadged = mIsUserBadged.valueAt(index); } else { // Check packageManager if the provided user needs a badge NoopDrawable d = new NoopDrawable(); isBadged = (d != mPm.getUserBadgedIcon(d, options.mUserHandle)); mIsUserBadged.put(key, isBadged); } op = op.setFlag(FLAG_WORK, isBadged); } return info; } return op; } /** package private */ Loading Loading @@ -390,7 +414,6 @@ public class BaseIconFactory implements AutoCloseable { boolean mIsInstantApp; UserHandle mUserHandle; /** * Set to false if non-adaptive icons should not be treated */ Loading Loading @@ -437,4 +460,16 @@ public class BaseIconFactory implements AutoCloseable { return getBitmap().getWidth(); } } private static class NoopDrawable extends ColorDrawable { @Override public int getIntrinsicHeight() { return 1; } @Override public int getIntrinsicWidth() { return 1; } } }
iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java +15 −15 Original line number Diff line number Diff line Loading @@ -19,14 +19,13 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.os.Process; import android.os.UserHandle; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.util.FlagOp; public class BitmapInfo { static final int FLAG_WORK = 1 << 0; Loading Loading @@ -71,10 +70,23 @@ public class BitmapInfo { return result; } /** * Returns a bitmapInfo with the flagOP applied */ public BitmapInfo withFlags(@NonNull FlagOp op) { if (op == FlagOp.NO_OP) { return this; } BitmapInfo result = clone(); result.flags = op.apply(result.flags); return result; } protected BitmapInfo copyInternalsTo(BitmapInfo target) { target.mMono = mMono; target.mWhiteShadowLayer = mWhiteShadowLayer; target.flags = flags; target.badgeInfo = badgeInfo; return target; } Loading @@ -88,18 +100,6 @@ public class BitmapInfo { mWhiteShadowLayer = iconFactory.getWhiteShadowLayer(); } /** * Ensures that the BitmapInfo represents the provided user */ public BitmapInfo withUser(UserHandle userHandle) { if (userHandle == null || Process.myUserHandle().equals(userHandle)) { flags &= ~FLAG_WORK; } else { flags |= FLAG_WORK; } return this; } /** * Ideally icon should not be null, except in cases when generating hardware bitmap failed */ Loading
iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java +27 −8 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.os.Trace; import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -58,6 +59,7 @@ import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BaseIconFactory.IconOptions; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.SQLiteCacheHelper; import java.nio.ByteBuffer; Loading Loading @@ -100,6 +102,7 @@ public abstract class BaseIconCache { protected String mSystemState = ""; private BitmapInfo mDefaultIcon; private final SparseArray<FlagOp> mUserFlagOpMap = new SparseArray<>(); private final String mDbFileName; private final Looper mBgLooper; Loading Loading @@ -157,6 +160,7 @@ public abstract class BaseIconCache { private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) { mIconDpi = iconDpi; mDefaultIcon = null; mUserFlagOpMap.clear(); mIconDb.clear(); mIconDb.close(); mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize); Loading Loading @@ -304,7 +308,21 @@ public abstract class BaseIconCache { mDefaultIcon = li.makeDefaultIcon(); } } return mDefaultIcon.clone().withUser(user); return mDefaultIcon.withFlags(getUserFlagOpLocked(user)); } private FlagOp getUserFlagOpLocked(UserHandle user) { int key = user.hashCode(); int index; if ((index = mUserFlagOpMap.indexOfKey(key)) >= 0) { return mUserFlagOpMap.valueAt(index); } else { try (BaseIconFactory li = getIconFactory()) { FlagOp op = li.getBitmapFlagOp(new IconOptions().setUser(user)); mUserFlagOpMap.put(key, op); return op; } } } public boolean isDefaultIcon(BitmapInfo icon, UserHandle user) { Loading Loading @@ -346,8 +364,8 @@ public abstract class BaseIconCache { T object = null; boolean providerFetchedOnce = false; boolean cacheEntryUpdated = cursor == null ? getEntryFromDB(cacheKey, entry, useLowResIcon) : updateTitleAndIcon(cacheKey, entry, cursor, useLowResIcon); ? getEntryFromDBLocked(cacheKey, entry, useLowResIcon) : updateTitleAndIconLocked(cacheKey, entry, cursor, useLowResIcon); if (!cacheEntryUpdated) { object = infoProvider.get(); providerFetchedOnce = true; Loading Loading @@ -442,7 +460,7 @@ public abstract class BaseIconCache { boolean entryUpdated = true; // Check the DB first. if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { if (!getEntryFromDBLocked(cacheKey, entry, useLowResIcon)) { try { int flags = Process.myUserHandle().equals(user) ? 0 : PackageManager.GET_UNINSTALLED_PACKAGES; Loading Loading @@ -486,7 +504,8 @@ public abstract class BaseIconCache { return entry; } protected boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { protected boolean getEntryFromDBLocked( ComponentKey cacheKey, CacheEntry entry, boolean lowRes) { Cursor c = null; Trace.beginSection("loadIconIndividually"); try { Loading @@ -497,7 +516,7 @@ public abstract class BaseIconCache { cacheKey.componentName.flattenToString(), Long.toString(getSerialNumberForUser(cacheKey.user))}); if (c.moveToNext()) { return updateTitleAndIcon(cacheKey, entry, c, lowRes); return updateTitleAndIconLocked(cacheKey, entry, c, lowRes); } } catch (SQLiteException e) { Log.d(TAG, "Error reading icon cache", e); Loading @@ -510,7 +529,7 @@ public abstract class BaseIconCache { return false; } private boolean updateTitleAndIcon( private boolean updateTitleAndIconLocked( ComponentKey cacheKey, CacheEntry entry, Cursor c, boolean lowRes) { // Set the alpha to be 255, so that we never have a wrong color entry.bitmap = BitmapInfo.of(LOW_RES_ICON, Loading Loading @@ -552,7 +571,7 @@ public abstract class BaseIconCache { } } entry.bitmap.flags = c.getInt(IconDB.INDEX_FLAGS); entry.bitmap.withUser(cacheKey.user); entry.bitmap = entry.bitmap.withFlags(getUserFlagOpLocked(cacheKey.user)); return entry.bitmap != null; } Loading
iconloaderlib/src/com/android/launcher3/util/FlagOp.java 0 → 100644 +48 −0 Original line number Diff line number Diff line /** * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.util; /** * Utility interface for representing flag operations */ public interface FlagOp { FlagOp NO_OP = i -> i; int apply(int flags); /** * Returns a new OP which adds the provided flag after applying all previous operations */ default FlagOp addFlag(int flag) { return i -> apply(i) | flag; } /** * Returns a new OP which removes the provided flag after applying all previous operations */ default FlagOp removeFlag(int flag) { return i -> apply(i) & ~flag; } /** * Returns a new OP which adds or removed the provided flag based on {@code enable} after * applying all previous operations */ default FlagOp setFlag(int flag, boolean enable) { return enable ? addFlag(flag) : removeFlag(flag); } }