Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 417997ff authored by Sunny Goyal's avatar Sunny Goyal Committed by Android (Google) Code Review
Browse files

Merge "Updating logic for user badge check"

parents 2c1e1df8 3da17f74
Loading
Loading
Loading
Loading
+39 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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;
@@ -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 */
@@ -390,7 +414,6 @@ public class BaseIconFactory implements AutoCloseable {
        boolean mIsInstantApp;
        UserHandle mUserHandle;


        /**
         * Set to false if non-adaptive icons should not be treated
         */
@@ -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;
        }
    }
}
+15 −15
Original line number Diff line number Diff line
@@ -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;
@@ -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;
    }

@@ -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
     */
+27 −8
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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) {
@@ -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;
@@ -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;
@@ -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 {
@@ -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);
@@ -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,
@@ -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;
    }

+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);
    }
}