IconCompat.java revision 801ca190c6df56bdf67ebd0a320ab5912640db10
1801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal/*
2801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Copyright (C) 2017 The Android Open Source Project
3801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal *
4801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Licensed under the Apache License, Version 2.0 (the "License");
5801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * you may not use this file except in compliance with the License.
6801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * You may obtain a copy of the License at
7801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal *
8801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal *      http://www.apache.org/licenses/LICENSE-2.0
9801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal *
10801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Unless required by applicable law or agreed to in writing, software
11801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * distributed under the License is distributed on an "AS IS" BASIS,
12801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * See the License for the specific language governing permissions and
14801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * limitations under the License.
15801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */
16801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
17801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalpackage android.support.v4.graphics.drawable;
18801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
19801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
20801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
21801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.annotation.TargetApi;
22801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.content.Context;
23801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.content.Intent;
24801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Bitmap;
25801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.BitmapShader;
26801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Canvas;
27801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Color;
28801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Matrix;
29801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Paint;
30801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Shader;
31801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.drawable.Icon;
32801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.net.Uri;
33801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.os.Build;
34801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.DrawableRes;
35801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.RestrictTo;
36801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.VisibleForTesting;
37801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.v4.os.BuildCompat;
38801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
39801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal/**
40801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Helper for accessing features in {@link android.graphics.drawable.Icon}
41801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * introduced after API level 4 in a backwards compatible fashion.
42801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */
43801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalpublic class IconCompat {
44801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
45801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // Ratio of expected size to actual icon size
46801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final float ADAPTIVE_ICON_INSET_FACTOR = 1 / 4f;
47801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final float DEFAULT_VIEW_PORT_SCALE = 1 / (1 + 2 * ADAPTIVE_ICON_INSET_FACTOR);
48801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final float ICON_DIAMETER_FACTOR = 176f / 192;
49801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final float BLUR_FACTOR = 0.5f / 48;
50801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final float KEY_SHADOW_OFFSET_FACTOR = 1f / 48;
51801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
52801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int KEY_SHADOW_ALPHA = 61;
53801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int AMBIENT_SHADOW_ALPHA = 30;
54801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
55801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int TYPE_BITMAP   = 1;
56801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int TYPE_RESOURCE = 2;
57801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int TYPE_DATA     = 3;
58801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int TYPE_URI      = 4;
59801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private static final int TYPE_ADAPTIVE_BITMAP = 5;
60801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
61801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private final int mType;
62801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
63801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
64801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // based on the value of mType.
65801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
66801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_BITMAP: Bitmap
67801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_ADAPTIVE_BITMAP: Bitmap
68801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_RESOURCE: Context
69801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_URI: String
70801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_DATA: DataBytes
71801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private Object          mObj1;
72801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
73801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_RESOURCE: resId
74801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_DATA: data offset
75801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private int             mInt1;
76801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
77801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    // TYPE_DATA: data length
78801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private int             mInt2;
79801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
80801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
81801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to a drawable resource.
82801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param context The context for the application whose resources should be used to resolve the
83801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     *                given resource ID.
84801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param resId ID of the drawable resource
85801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithResource(Context, int)
86801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
87801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithResource(Context context, @DrawableRes int resId) {
88801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (context == null) {
89801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Context must not be null.");
90801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
91801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        final IconCompat rep = new IconCompat(TYPE_RESOURCE);
92801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mInt1 = resId;
93801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mObj1 = context;
94801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return rep;
95801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
96801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
97801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
98801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to a bitmap in memory.
99801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param bits A valid {@link android.graphics.Bitmap} object
100801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithBitmap(Bitmap)
101801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
102801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithBitmap(Bitmap bits) {
103801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (bits == null) {
104801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Bitmap must not be null.");
105801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
106801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        final IconCompat rep = new IconCompat(TYPE_BITMAP);
107801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mObj1 = bits;
108801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return rep;
109801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
110801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
111801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
112801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to a bitmap in memory that follows the icon design guideline defined
113801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * by {@link android.graphics.drawable.AdaptiveIconDrawable}.
114801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param bits A valid {@link android.graphics.Bitmap} object
115801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithAdaptiveBitmap(Bitmap)
116801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
117801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithAdaptiveBitmap(Bitmap bits) {
118801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (bits == null) {
119801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Bitmap must not be null.");
120801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
121801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        final IconCompat rep = new IconCompat(TYPE_ADAPTIVE_BITMAP);
122801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mObj1 = bits;
123801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return rep;
124801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
125801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
126801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
127801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to a compressed bitmap stored in a byte array.
128801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param data Byte array storing compressed bitmap data of a type that
129801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     *             {@link android.graphics.BitmapFactory}
130801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     *             can decode (see {@link android.graphics.Bitmap.CompressFormat}).
131801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param offset Offset into <code>data</code> at which the bitmap data starts
132801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param length Length of the bitmap data
133801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithData(byte[], int, int)
134801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
135801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithData(byte[] data, int offset, int length) {
136801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (data == null) {
137801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Data must not be null.");
138801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
139801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        final IconCompat rep = new IconCompat(TYPE_DATA);
140801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mObj1 = data;
141801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mInt1 = offset;
142801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mInt2 = length;
143801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return rep;
144801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
145801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
146801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
147801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to an image file specified by URI.
148801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     *
149801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param uri A uri referring to local content:// or file:// image data.
150801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithContentUri(String)
151801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
152801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithContentUri(String uri) {
153801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (uri == null) {
154801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Uri must not be null.");
155801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
156801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        final IconCompat rep = new IconCompat(TYPE_URI);
157801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        rep.mObj1 = uri;
158801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return rep;
159801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
160801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
161801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
162801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Create an Icon pointing to an image file specified by URI.
163801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     *
164801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @param uri A uri referring to local content:// or file:// image data.
165801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @see android.graphics.drawable.Icon#createWithContentUri(String)
166801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
167801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public static IconCompat createWithContentUri(Uri uri) {
168801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        if (uri == null) {
169801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            throw new IllegalArgumentException("Uri must not be null.");
170801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
171801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return createWithContentUri(uri.toString());
172801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
173801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
174801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    private IconCompat(int mType) {
175801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        this.mType = mType;
176801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
177801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
178801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
179801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @hide
180801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
181801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    @VisibleForTesting
182801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    @RestrictTo(LIBRARY_GROUP)
183801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    @TargetApi(Build.VERSION_CODES.O)
184801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public Icon toIcon() {
185801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        switch (mType) {
186801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_BITMAP:
187801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                return Icon.createWithBitmap((Bitmap) mObj1);
188801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_ADAPTIVE_BITMAP:
189801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                if (BuildCompat.isAtLeastO()) {
190801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                    return Icon.createWithAdaptiveBitmap((Bitmap) mObj1);
191801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                } else {
192801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                    return Icon.createWithBitmap(createLegacyIconFromAdaptiveIcon((Bitmap) mObj1));
193801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                }
194801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_RESOURCE:
195801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                return Icon.createWithResource((Context) mObj1, mInt1);
196801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_DATA:
197801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                return Icon.createWithData((byte[]) mObj1, mInt1, mInt2);
198801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_URI:
199801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                return Icon.createWithContentUri((String) mObj1);
200801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            default:
201801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                throw new IllegalArgumentException("Unknown type");
202801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
203801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
204801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
205801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
206801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * @hide
207801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
208801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    @RestrictTo(LIBRARY_GROUP)
209801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    public void addToShortcutIntent(Intent outIntent) {
210801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        switch (mType) {
211801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_BITMAP:
212801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, (Bitmap) mObj1);
213801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                break;
214801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_ADAPTIVE_BITMAP:
215801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON,
216801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                        createLegacyIconFromAdaptiveIcon((Bitmap) mObj1));
217801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                break;
218801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            case TYPE_RESOURCE:
219801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
220801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                        Intent.ShortcutIconResource.fromContext((Context) mObj1, mInt1));
221801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                break;
222801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal            default:
223801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                throw new IllegalArgumentException("Icon type not supported for intent shortcuts");
224801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        }
225801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
226801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
227801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    /**
228801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * Converts a bitmap following the adaptive icon guide lines, into a bitmap following the
229801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * shortcut icon guide lines.
230801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     * The returned bitmap will always have same width and height and clipped to a circle.
231801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal     */
232801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    @VisibleForTesting
233801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    static Bitmap createLegacyIconFromAdaptiveIcon(Bitmap adaptiveIconBitmap) {
234801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        int size = (int) (DEFAULT_VIEW_PORT_SCALE * Math.min(adaptiveIconBitmap.getWidth(),
235801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                adaptiveIconBitmap.getHeight()));
236801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
237801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        Bitmap icon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
238801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        Canvas canvas = new Canvas(icon);
239801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
240801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
241801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        float center = size * 0.5f;
242801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        float radius = center * ICON_DIAMETER_FACTOR;
243801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
244801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        // Draw key shadow
245801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        float blur = BLUR_FACTOR * size;
246801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.setColor(Color.TRANSPARENT);
247801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.setShadowLayer(blur, 0, KEY_SHADOW_OFFSET_FACTOR * size, KEY_SHADOW_ALPHA << 24);
248801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        canvas.drawCircle(center, center, radius, paint);
249801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
250801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        // Draw ambient shadow
251801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
252801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        canvas.drawCircle(center, center, radius, paint);
253801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.clearShadowLayer();
254801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
255801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        // Draw the clipped icon
256801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.setColor(Color.BLACK);
257801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        BitmapShader shader = new BitmapShader(adaptiveIconBitmap, Shader.TileMode.CLAMP,
258801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                Shader.TileMode.CLAMP);
259801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        Matrix shift = new Matrix();
260801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        shift.setTranslate(-(adaptiveIconBitmap.getWidth() - size) / 2,
261801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal                -(adaptiveIconBitmap.getHeight() - size) / 2);
262801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        shader.setLocalMatrix(shift);
263801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        paint.setShader(shader);
264801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        canvas.drawCircle(center, center, radius, paint);
265801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal
266801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        canvas.setBitmap(null);
267801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal        return icon;
268801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal    }
269801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal}
270