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.content.Context; 22801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.content.Intent; 23801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Bitmap; 24801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.BitmapShader; 25801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Canvas; 26801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Color; 27801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Matrix; 28801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Paint; 29801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.Shader; 30801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.graphics.drawable.Icon; 31801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.net.Uri; 32801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.os.Build; 33801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.DrawableRes; 349053f4f45adbf08773dbfa3188779c53e4c3dcdcHyunyoung Songimport android.support.annotation.RequiresApi; 35801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.RestrictTo; 36801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalimport android.support.annotation.VisibleForTesting; 37801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 38801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal/** 39645e5c8aa6b31961c5f73f3d30bb5261d5e04aebKirill Grouchnikov * Helper for accessing features in {@link android.graphics.drawable.Icon}. 40801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 41801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyalpublic class IconCompat { 42801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 43801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Ratio of expected size to actual icon size 44801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float ADAPTIVE_ICON_INSET_FACTOR = 1 / 4f; 45801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float DEFAULT_VIEW_PORT_SCALE = 1 / (1 + 2 * ADAPTIVE_ICON_INSET_FACTOR); 46801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float ICON_DIAMETER_FACTOR = 176f / 192; 47801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float BLUR_FACTOR = 0.5f / 48; 48801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final float KEY_SHADOW_OFFSET_FACTOR = 1f / 48; 49801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 50801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int KEY_SHADOW_ALPHA = 61; 51801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int AMBIENT_SHADOW_ALPHA = 30; 52801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 53801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_BITMAP = 1; 54801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_RESOURCE = 2; 55801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_DATA = 3; 56801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_URI = 4; 57801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private static final int TYPE_ADAPTIVE_BITMAP = 5; 58801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 59801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private final int mType; 60801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 61801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed 62801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // based on the value of mType. 63801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 64801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_BITMAP: Bitmap 65801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_ADAPTIVE_BITMAP: Bitmap 66801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_RESOURCE: Context 67801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_URI: String 68801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: DataBytes 69801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private Object mObj1; 70801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 71801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_RESOURCE: resId 72801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: data offset 73801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private int mInt1; 74801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 75801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // TYPE_DATA: data length 76801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private int mInt2; 77801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 78801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 79801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a drawable resource. 80801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param context The context for the application whose resources should be used to resolve the 81801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * given resource ID. 82801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param resId ID of the drawable resource 83801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithResource(Context, int) 84801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 85801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithResource(Context context, @DrawableRes int resId) { 86801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (context == null) { 87801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Context must not be null."); 88801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 89801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_RESOURCE); 90801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt1 = resId; 91801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = context; 92801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 93801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 94801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 95801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 96801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a bitmap in memory. 97801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param bits A valid {@link android.graphics.Bitmap} object 98801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithBitmap(Bitmap) 99801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 100801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithBitmap(Bitmap bits) { 101801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (bits == null) { 102801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Bitmap must not be null."); 103801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 104801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_BITMAP); 105801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = bits; 106801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 107801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 108801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 109801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 110801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a bitmap in memory that follows the icon design guideline defined 111801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * by {@link android.graphics.drawable.AdaptiveIconDrawable}. 112801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param bits A valid {@link android.graphics.Bitmap} object 113801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithAdaptiveBitmap(Bitmap) 114801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 115801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithAdaptiveBitmap(Bitmap bits) { 116801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (bits == null) { 117801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Bitmap must not be null."); 118801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 119801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_ADAPTIVE_BITMAP); 120801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = bits; 121801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 122801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 123801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 124801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 125801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to a compressed bitmap stored in a byte array. 126801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param data Byte array storing compressed bitmap data of a type that 127801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * {@link android.graphics.BitmapFactory} 128801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * can decode (see {@link android.graphics.Bitmap.CompressFormat}). 129801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param offset Offset into <code>data</code> at which the bitmap data starts 130801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param length Length of the bitmap data 131801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithData(byte[], int, int) 132801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 133801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithData(byte[] data, int offset, int length) { 134801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (data == null) { 135801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Data must not be null."); 136801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 137801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_DATA); 138801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = data; 139801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt1 = offset; 140801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mInt2 = length; 141801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 142801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 143801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 144801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 145801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to an image file specified by URI. 146801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 147801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param uri A uri referring to local content:// or file:// image data. 148801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithContentUri(String) 149801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 150801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithContentUri(String uri) { 151801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (uri == null) { 152801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Uri must not be null."); 153801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 154801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal final IconCompat rep = new IconCompat(TYPE_URI); 155801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal rep.mObj1 = uri; 156801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return rep; 157801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 158801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 159801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 160801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Create an Icon pointing to an image file specified by URI. 161801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * 162801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @param uri A uri referring to local content:// or file:// image data. 163801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @see android.graphics.drawable.Icon#createWithContentUri(String) 164801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 165801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public static IconCompat createWithContentUri(Uri uri) { 166801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal if (uri == null) { 167801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Uri must not be null."); 168801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 169801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return createWithContentUri(uri.toString()); 170801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 171801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 172801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal private IconCompat(int mType) { 173801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal this.mType = mType; 174801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 175801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 176801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 1779053f4f45adbf08773dbfa3188779c53e4c3dcdcHyunyoung Song * Convert this compat object to {@link Icon} object. 1789053f4f45adbf08773dbfa3188779c53e4c3dcdcHyunyoung Song * 1799053f4f45adbf08773dbfa3188779c53e4c3dcdcHyunyoung Song * @return {@link Icon} object 180801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 1819053f4f45adbf08773dbfa3188779c53e4c3dcdcHyunyoung Song @RequiresApi(23) 182801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public Icon toIcon() { 183801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal switch (mType) { 184801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_BITMAP: 185801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithBitmap((Bitmap) mObj1); 186801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_ADAPTIVE_BITMAP: 1877301f0cca4f9dc9249cd660c05d5b2107f5b3d04Aurimas Liutikas if (Build.VERSION.SDK_INT >= 26) { 188801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithAdaptiveBitmap((Bitmap) mObj1); 189801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } else { 190801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithBitmap(createLegacyIconFromAdaptiveIcon((Bitmap) mObj1)); 191801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 192801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_RESOURCE: 193801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithResource((Context) mObj1, mInt1); 194801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_DATA: 195801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithData((byte[]) mObj1, mInt1, mInt2); 196801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_URI: 197801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return Icon.createWithContentUri((String) mObj1); 198801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal default: 199801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Unknown type"); 200801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 201801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 202801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 203801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 204801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * @hide 205801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 206801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @RestrictTo(LIBRARY_GROUP) 207801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal public void addToShortcutIntent(Intent outIntent) { 208801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal switch (mType) { 209801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_BITMAP: 210801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, (Bitmap) mObj1); 211801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 212801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_ADAPTIVE_BITMAP: 213801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, 214801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal createLegacyIconFromAdaptiveIcon((Bitmap) mObj1)); 215801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 216801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal case TYPE_RESOURCE: 217801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal outIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, 218801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Intent.ShortcutIconResource.fromContext((Context) mObj1, mInt1)); 219801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal break; 220801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal default: 221801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal throw new IllegalArgumentException("Icon type not supported for intent shortcuts"); 222801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 223801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 224801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 225801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal /** 226801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * Converts a bitmap following the adaptive icon guide lines, into a bitmap following the 227801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * shortcut icon guide lines. 228801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal * The returned bitmap will always have same width and height and clipped to a circle. 229801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal */ 230801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal @VisibleForTesting 231801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal static Bitmap createLegacyIconFromAdaptiveIcon(Bitmap adaptiveIconBitmap) { 232801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal int size = (int) (DEFAULT_VIEW_PORT_SCALE * Math.min(adaptiveIconBitmap.getWidth(), 233801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal adaptiveIconBitmap.getHeight())); 234801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 235801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Bitmap icon = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); 236801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Canvas canvas = new Canvas(icon); 237801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 238801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 239801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float center = size * 0.5f; 240801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float radius = center * ICON_DIAMETER_FACTOR; 241801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 242801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw key shadow 243801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal float blur = BLUR_FACTOR * size; 244801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setColor(Color.TRANSPARENT); 245801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShadowLayer(blur, 0, KEY_SHADOW_OFFSET_FACTOR * size, KEY_SHADOW_ALPHA << 24); 246801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 247801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 248801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw ambient shadow 249801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24); 250801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 251801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.clearShadowLayer(); 252801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 253801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal // Draw the clipped icon 254801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setColor(Color.BLACK); 255801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal BitmapShader shader = new BitmapShader(adaptiveIconBitmap, Shader.TileMode.CLAMP, 256801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Shader.TileMode.CLAMP); 257801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal Matrix shift = new Matrix(); 258801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal shift.setTranslate(-(adaptiveIconBitmap.getWidth() - size) / 2, 259801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal -(adaptiveIconBitmap.getHeight() - size) / 2); 260801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal shader.setLocalMatrix(shift); 261801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal paint.setShader(shader); 262801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.drawCircle(center, center, radius, paint); 263801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal 264801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal canvas.setBitmap(null); 265801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal return icon; 266801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal } 267801ca190c6df56bdf67ebd0a320ab5912640db10Sunny Goyal} 268