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

Commit f281e7af authored by Hyunyoung Song's avatar Hyunyoung Song
Browse files

ShortcutManager should support MaskableBitmap Icon type

Note: https://ag/1872683/ is where initial code review happened.

Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest3 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest4 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest5 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest6 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest7 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest8 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest9 -w com.android.frameworks.servicestests
Test: adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest10 -w com.android.frameworks.servicestests

Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsShortcutHostTestCases -t 'android.content.pm.cts.shortcuthost.ShortcutManagerMultiuserTest'
Test: cts-tradefed run cts --skip-device-info --skip-preconditions --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker -a armeabi-v7a -m CtsDevicePolicyManagerTestCases -t 'com.android.cts.devicepolicy.LauncherAppsProfileTest'


b/34196580

Change-Id: I3b983c29387e474c7a8c687a524105ceaceac81e
parent f5e10714
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.MaskableIconDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -803,7 +804,15 @@ public class LauncherApps {
            }
            try {
                final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
                return (bmp == null) ? null : new BitmapDrawable(mContext.getResources(), bmp);
                if (bmp != null) {
                    BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
                    if (shortcut.hasMaskableBitmap()) {
                        return new MaskableIconDrawable(null, dr);
                    } else {
                        return dr;
                    }
                }
                return null;
            } finally {
                try {
                    pfd.close();
@@ -821,7 +830,8 @@ public class LauncherApps {
                    return loadDrawableResourceFromPackage(shortcut.getPackage(),
                            icon.getResId(), shortcut.getUserHandle(), density);
                }
                case Icon.TYPE_BITMAP: {
                case Icon.TYPE_BITMAP:
                case Icon.TYPE_BITMAP_MASKABLE: {
                    return icon.loadDrawable(mContext);
                }
                default:
+17 −2
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ public final class ShortcutInfo implements Parcelable {
    /** @hide */
    public static final int FLAG_IMMUTABLE = 1 << 8;

    /** @hide */
    public static final int FLAG_MASKABLE_BITMAP = 1 << 9;

    /** @hide */
    @IntDef(flag = true,
            value = {
@@ -103,6 +106,7 @@ public final class ShortcutInfo implements Parcelable {
            FLAG_DISABLED,
            FLAG_STRINGS_RESOLVED,
            FLAG_IMMUTABLE,
            FLAG_MASKABLE_BITMAP,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ShortcutFlags {}
@@ -690,6 +694,7 @@ public final class ShortcutInfo implements Parcelable {
        switch (icon.getType()) {
            case Icon.TYPE_RESOURCE:
            case Icon.TYPE_BITMAP:
            case Icon.TYPE_BITMAP_MASKABLE:
                break; // OK
            default:
                throw getInvalidIconException();
@@ -815,8 +820,9 @@ public final class ShortcutInfo implements Parcelable {
         * <p>Tints set with {@link Icon#setTint} or {@link Icon#setTintList} are not supported
         * and will be ignored.
         *
         * <p>Only icons created with {@link Icon#createWithBitmap(Bitmap)} and
         * {@link Icon#createWithResource} are supported.
         * <p>Only icons created with {@link Icon#createWithBitmap(Bitmap)},
         * {@link Icon#createWithMaskableBitmap(Bitmap)}
         * and {@link Icon#createWithResource} are supported.
         * Other types, such as URI-based icons, are not supported.
         *
         * @see LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)
@@ -1441,6 +1447,15 @@ public final class ShortcutInfo implements Parcelable {
        return hasFlags(FLAG_HAS_ICON_FILE);
    }

    /**
     * Return whether a shortcut's icon is maskable.
     *
     * @hide internal/unit tests only
     */
    public boolean hasMaskableBitmap() {
        return hasFlags(FLAG_MASKABLE_BITMAP);
    }

    /**
     * Return whether a shortcut only contains "key" information only or not.  If true, only the
     * following fields are available.
+5 −0
Original line number Diff line number Diff line
@@ -1581,6 +1581,11 @@ class ShortcutPackage extends ShortcutPackageItem {
                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                        + " still has an icon");
            }
            if (si.hasMaskableBitmap() && !si.hasIconFile()) {
                failed = true;
                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                    + " has maskable bitmap but was not saved to a file.");
            }
            if (si.hasIconFile() && si.hasIconResource()) {
                failed = true;
                Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+7 −2
Original line number Diff line number Diff line
@@ -1216,7 +1216,8 @@ public class ShortcutService extends IShortcutService.Stub {
        // he XML we'd lose the icon.  We just remove all dangling files after saving the XML.
        shortcut.setIconResourceId(0);
        shortcut.setIconResName(null);
        shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES);
        shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE |
            ShortcutInfo.FLAG_MASKABLE_BITMAP | ShortcutInfo.FLAG_HAS_ICON_RES);
    }

    public void cleanupBitmapsForPackage(@UserIdInt int userId, String packageName) {
@@ -1351,7 +1352,8 @@ public class ShortcutService extends IShortcutService.Stub {
                        shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_RES);
                        return;
                    }
                    case Icon.TYPE_BITMAP: {
                    case Icon.TYPE_BITMAP:
                    case Icon.TYPE_BITMAP_MASKABLE: {
                        bitmap = icon.getBitmap(); // Don't recycle in this case.
                        break;
                    }
@@ -1382,6 +1384,9 @@ public class ShortcutService extends IShortcutService.Stub {

                        shortcut.setBitmapPath(out.getFile().getAbsolutePath());
                        shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_FILE);
                        if (icon.getType() == Icon.TYPE_BITMAP_MASKABLE) {
                            shortcut.addFlags(ShortcutInfo.FLAG_MASKABLE_BITMAP);
                        }
                    } finally {
                        IoUtils.closeQuietly(out);
                    }
+24 −5
Original line number Diff line number Diff line
@@ -75,7 +75,9 @@ import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.graphics.drawable.MaskableIconDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -244,6 +246,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
        final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
        final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                getTestContext().getResources(), R.drawable.icon2));
        final Icon icon3 = Icon.createWithMaskableBitmap(BitmapFactory.decodeResource(
            getTestContext().getResources(), R.drawable.icon2));

        final ShortcutInfo si1 = makeShortcut(
                "shortcut1",
@@ -261,12 +265,18 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
                icon2,
                makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
                /* weight */ 12);
        final ShortcutInfo si3 = makeShortcut("shortcut3");
        final ShortcutInfo si3 = makeShortcut(
                "shortcut3",
                "Title 3",
                /* activity */ null,
                icon3,
                makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
                /* weight */ 13);

        assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
        assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
        assertShortcutIds(assertAllNotKeyFieldsOnly(
                mManager.getDynamicShortcuts()),
                "shortcut1", "shortcut2");
                "shortcut1", "shortcut2", "shortcut3");
        assertEquals(2, mManager.getRemainingCallCount());

        // TODO: Check fields
@@ -550,7 +560,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {

        final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                getTestContext().getResources(), R.drawable.black_32x32));
        final Icon bmp64x64 = Icon.createWithBitmap(BitmapFactory.decodeResource(
        final Icon bmp64x64_maskable = Icon.createWithMaskableBitmap(BitmapFactory.decodeResource(
                getTestContext().getResources(), R.drawable.black_64x64));
        final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                getTestContext().getResources(), R.drawable.black_512x512));
@@ -561,7 +571,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
                makeShortcutWithIcon("res32x32", res32x32),
                makeShortcutWithIcon("res64x64", res64x64),
                makeShortcutWithIcon("bmp32x32", bmp32x32),
                makeShortcutWithIcon("bmp64x64", bmp64x64),
                makeShortcutWithIcon("bmp64x64", bmp64x64_maskable),
                makeShortcutWithIcon("bmp512x512", bmp512x512),
                makeShortcut("none")
        )));
@@ -691,6 +701,15 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
        bmp = pfdToBitmap(
                mLauncherApps.getShortcutIconFd(CALLING_PACKAGE_1, "bmp32x32", HANDLE_USER_P0));
        assertBitmapSize(128, 128, bmp);

        Drawable dr = mLauncherApps.getShortcutIconDrawable(
            makeShortcutWithIcon("bmp64x64", bmp64x64_maskable), 0);
        assertTrue(dr instanceof MaskableIconDrawable);
        float viewportPercentage = 1 / (1 + 2 * MaskableIconDrawable.getExtraInsetPercentage());
        assertEquals((int) (bmp64x64_maskable.getBitmap().getWidth() * viewportPercentage),
            dr.getIntrinsicWidth());
        assertEquals((int) (bmp64x64_maskable.getBitmap().getHeight() * viewportPercentage),
            dr.getIntrinsicHeight());
    }

    public void testCleanupDanglingBitmaps() throws Exception {
Loading