Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java

Issue 2872473002: Merge ChromeShortcutManager into ShortcutHelper. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser; 5 package org.chromium.chrome.browser;
6 6
7 import android.annotation.SuppressLint;
8 import android.annotation.TargetApi;
7 import android.app.ActivityManager; 9 import android.app.ActivityManager;
8 import android.content.Context; 10 import android.content.Context;
9 import android.content.Intent; 11 import android.content.Intent;
12 import android.content.IntentSender;
10 import android.content.pm.ApplicationInfo; 13 import android.content.pm.ApplicationInfo;
11 import android.content.pm.PackageInfo; 14 import android.content.pm.PackageInfo;
12 import android.content.pm.PackageManager; 15 import android.content.pm.PackageManager;
13 import android.content.pm.PackageManager.NameNotFoundException; 16 import android.content.pm.PackageManager.NameNotFoundException;
17 import android.content.pm.ResolveInfo;
14 import android.graphics.Bitmap; 18 import android.graphics.Bitmap;
15 import android.graphics.BitmapFactory; 19 import android.graphics.BitmapFactory;
16 import android.graphics.Canvas; 20 import android.graphics.Canvas;
17 import android.graphics.Color; 21 import android.graphics.Color;
18 import android.graphics.Paint; 22 import android.graphics.Paint;
19 import android.graphics.Rect; 23 import android.graphics.Rect;
20 import android.graphics.drawable.BitmapDrawable; 24 import android.graphics.drawable.BitmapDrawable;
21 import android.graphics.drawable.Drawable; 25 import android.graphics.drawable.Drawable;
26 import android.graphics.drawable.Icon;
22 import android.net.Uri; 27 import android.net.Uri;
23 import android.os.AsyncTask; 28 import android.os.AsyncTask;
24 import android.support.annotation.NonNull; 29 import android.support.annotation.NonNull;
25 import android.text.TextUtils; 30 import android.text.TextUtils;
26 import android.util.Base64; 31 import android.util.Base64;
27 32
28 import org.chromium.base.ApiCompatibilityUtils; 33 import org.chromium.base.ApiCompatibilityUtils;
34 import org.chromium.base.BuildInfo;
29 import org.chromium.base.ContextUtils; 35 import org.chromium.base.ContextUtils;
30 import org.chromium.base.Log; 36 import org.chromium.base.Log;
31 import org.chromium.base.ThreadUtils; 37 import org.chromium.base.ThreadUtils;
32 import org.chromium.base.VisibleForTesting; 38 import org.chromium.base.VisibleForTesting;
33 import org.chromium.base.annotations.CalledByNative; 39 import org.chromium.base.annotations.CalledByNative;
34 import org.chromium.blink_public.platform.WebDisplayMode; 40 import org.chromium.blink_public.platform.WebDisplayMode;
35 import org.chromium.chrome.R; 41 import org.chromium.chrome.R;
36 import org.chromium.chrome.browser.webapps.ChromeShortcutManager;
37 import org.chromium.chrome.browser.webapps.ChromeWebApkHost; 42 import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
38 import org.chromium.chrome.browser.webapps.WebApkInfo; 43 import org.chromium.chrome.browser.webapps.WebApkInfo;
39 import org.chromium.chrome.browser.webapps.WebappActivity; 44 import org.chromium.chrome.browser.webapps.WebappActivity;
40 import org.chromium.chrome.browser.webapps.WebappAuthenticator; 45 import org.chromium.chrome.browser.webapps.WebappAuthenticator;
41 import org.chromium.chrome.browser.webapps.WebappDataStorage; 46 import org.chromium.chrome.browser.webapps.WebappDataStorage;
42 import org.chromium.chrome.browser.webapps.WebappLauncherActivity; 47 import org.chromium.chrome.browser.webapps.WebappLauncherActivity;
43 import org.chromium.chrome.browser.webapps.WebappRegistry; 48 import org.chromium.chrome.browser.webapps.WebappRegistry;
44 import org.chromium.chrome.browser.widget.RoundedIconGenerator; 49 import org.chromium.chrome.browser.widget.RoundedIconGenerator;
45 import org.chromium.content_public.common.ScreenOrientationConstants; 50 import org.chromium.content_public.common.ScreenOrientationConstants;
46 import org.chromium.ui.widget.Toast; 51 import org.chromium.ui.widget.Toast;
47 import org.chromium.webapk.lib.client.WebApkValidator; 52 import org.chromium.webapk.lib.client.WebApkValidator;
48 53
49 import java.io.ByteArrayOutputStream; 54 import java.io.ByteArrayOutputStream;
55 import java.lang.reflect.Constructor;
56 import java.lang.reflect.InvocationTargetException;
57 import java.lang.reflect.Method;
50 import java.util.ArrayList; 58 import java.util.ArrayList;
51 import java.util.List; 59 import java.util.List;
52 60
53 /** 61 /**
54 * This class contains functions related to adding shortcuts to the Android Home 62 * This class contains functions related to adding shortcuts to the Android Home
55 * screen. These shortcuts are used to either open a page in the main browser 63 * screen. These shortcuts are used to either open a page in the main browser
56 * or open a web app. 64 * or open a web app.
57 */ 65 */
58 public class ShortcutHelper { 66 public class ShortcutHelper {
59 public static final String EXTRA_ICON = "org.chromium.chrome.browser.webapp_ icon"; 67 public static final String EXTRA_ICON = "org.chromium.chrome.browser.webapp_ icon";
(...skipping 21 matching lines...) Expand all
81 89
82 // When a new field is added to the intent, this version should be increment ed so that it will 90 // When a new field is added to the intent, this version should be increment ed so that it will
83 // be correctly populated into the WebappRegistry/WebappDataStorage. 91 // be correctly populated into the WebappRegistry/WebappDataStorage.
84 public static final int WEBAPP_SHORTCUT_VERSION = 2; 92 public static final int WEBAPP_SHORTCUT_VERSION = 2;
85 93
86 // This value is equal to kInvalidOrMissingColor in the C++ content::Manifes t struct. 94 // This value is equal to kInvalidOrMissingColor in the C++ content::Manifes t struct.
87 public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ((long) Integer .MAX_VALUE) + 1; 95 public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ((long) Integer .MAX_VALUE) + 1;
88 96
89 private static final String TAG = "ShortcutHelper"; 97 private static final String TAG = "ShortcutHelper";
90 98
99 // There is no public string defining this intent so if Home changes the val ue, we
100 // have to update this string.
dominickn 2017/05/08 04:51:22 Nit: I think we can remove this comment now since
Marti Wong 2017/05/09 04:36:42 Done.
101 private static final String INSTALL_SHORTCUT = "com.android.launcher.action. INSTALL_SHORTCUT";
102
91 // The activity class used for launching a WebApk. 103 // The activity class used for launching a WebApk.
92 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel l_apk.MainActivity"; 104 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel l_apk.MainActivity";
93 105
94 // These sizes are from the Material spec for icons: 106 // These sizes are from the Material spec for icons:
95 // https://www.google.com/design/spec/style/icons.html#icons-product-icons 107 // https://www.google.com/design/spec/style/icons.html#icons-product-icons
96 private static final float MAX_INNER_SIZE_RATIO = 1.25f; 108 private static final float MAX_INNER_SIZE_RATIO = 1.25f;
97 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f; 109 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f;
98 private static final float ICON_CORNER_RADIUS_RATIO = 1.0f / 16.0f; 110 private static final float ICON_CORNER_RADIUS_RATIO = 1.0f / 16.0f;
99 private static final float GENERATED_ICON_PADDING_RATIO = 1.0f / 12.0f; 111 private static final float GENERATED_ICON_PADDING_RATIO = 1.0f / 12.0f;
100 private static final float GENERATED_ICON_FONT_SIZE_RATIO = 1.0f / 3.0f; 112 private static final float GENERATED_ICON_FONT_SIZE_RATIO = 1.0f / 3.0f;
101 113
114 // True when Android O's ShortcutManager.requestPinShortcut() is supported.
115 private static boolean sIsRequestPinShortcutSupported;
116
117 // True when it is already checked if ShortcutManager.requestPinShortcut() i s supported.
118 private static boolean sCheckedIfRequestPinShortcutSupported;
119
120 // TODO(martiw): Use 'ShortcutInfo' instead of 'Object' below when compileSd k is bumped to O.
121 private static Object sShortcutManager;
122
102 /** Helper for generating home screen shortcuts. */ 123 /** Helper for generating home screen shortcuts. */
103 public static class Delegate { 124 public static class Delegate {
104 /** 125 /**
105 * Request Android to add a shortcut to the home screen. 126 * Request Android to add a shortcut to the home screen.
106 * @param title Title of the shortcut. 127 * @param title Title of the shortcut.
107 * @param icon Image that represents the shortcut. 128 * @param icon Image that represents the shortcut.
108 * @param intent Intent to fire when the shortcut is activated. 129 * @param intent Intent to fire when the shortcut is activated.
109 */ 130 */
110 public void addShortcutToHomescreen(String title, Bitmap icon, Intent sh ortcutIntent) { 131 public void addShortcutToHomescreen(String title, Bitmap icon, Intent sh ortcutIntent) {
111 ChromeShortcutManager.getInstance().addShortcutToHomeScreen( 132 if (isRequestPinShortcutSupported()) {
112 title, icon, shortcutIntent); 133 addShortcutWithShortcutManager(title, icon, shortcutIntent);
134 return;
135 }
136 Intent intent = createAddToHomeIntent(title, icon, shortcutIntent);
137 ContextUtils.getApplicationContext().sendBroadcast(intent);
113 } 138 }
114 139
115 /** 140 /**
116 * Returns the name of the fullscreen Activity to use when launching sho rtcuts. 141 * Returns the name of the fullscreen Activity to use when launching sho rtcuts.
117 */ 142 */
118 public String getFullscreenAction() { 143 public String getFullscreenAction() {
119 return WebappLauncherActivity.ACTION_START_WEBAPP; 144 return WebappLauncherActivity.ACTION_START_WEBAPP;
120 } 145 }
121 } 146 }
122 147
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // process is complete, call back to native code to start the sp lash image 191 // process is complete, call back to native code to start the sp lash image
167 // download. 192 // download.
168 WebappRegistry.getInstance().register( 193 WebappRegistry.getInstance().register(
169 id, new WebappRegistry.FetchWebappDataStorageCallback() { 194 id, new WebappRegistry.FetchWebappDataStorageCallback() {
170 @Override 195 @Override
171 public void onWebappDataStorageRetrieved(WebappDataS torage storage) { 196 public void onWebappDataStorageRetrieved(WebappDataS torage storage) {
172 storage.updateFromShortcutIntent(resultIntent); 197 storage.updateFromShortcutIntent(resultIntent);
173 nativeOnWebappDataStored(callbackPointer); 198 nativeOnWebappDataStored(callbackPointer);
174 } 199 }
175 }); 200 });
176 if (ChromeShortcutManager.getInstance().shouldShowToastWhenAddin gShortcut()) { 201 if (shouldShowToastWhenAddingShortcut()) {
177 showAddedToHomescreenToast(userTitle); 202 showAddedToHomescreenToast(userTitle);
178 } 203 }
179 } 204 }
180 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 205 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
181 } 206 }
182 207
183 public static void addWebApkShortcut(Context context, String packageName) { 208 public static void addWebApkShortcut(Context context, String packageName) {
184 PackageManager pm = context.getPackageManager(); 209 PackageManager pm = context.getPackageManager();
185 try { 210 try {
186 ApplicationInfo appInfo = pm.getApplicationInfo( 211 ApplicationInfo appInfo = pm.getApplicationInfo(
187 packageName, PackageManager.GET_META_DATA); 212 packageName, PackageManager.GET_META_DATA);
188 String shortcutTitle = pm.getApplicationLabel(appInfo).toString(); 213 String shortcutTitle = pm.getApplicationLabel(appInfo).toString();
189 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag eName)).getBitmap(); 214 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag eName)).getBitmap();
190 215
191 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon); 216 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon);
192 Intent i = new Intent(); 217 Intent i = new Intent();
193 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY); 218 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY);
194 i.addCategory(Intent.CATEGORY_LAUNCHER); 219 i.addCategory(Intent.CATEGORY_LAUNCHER);
195 context.sendBroadcast( 220 context.sendBroadcast(createAddToHomeIntent(shortcutTitle, bitmap, i ));
196 ChromeShortcutManager.createAddToHomeIntent(shortcutTitle, b itmap, i));
197 } catch (NameNotFoundException e) { 221 } catch (NameNotFoundException e) {
198 e.printStackTrace(); 222 e.printStackTrace();
199 } 223 }
200 } 224 }
201 225
202 /** 226 /**
203 * Adds home screen shortcut which opens in the browser Activity. 227 * Adds home screen shortcut which opens in the browser Activity.
204 */ 228 */
205 @SuppressWarnings("unused") 229 @SuppressWarnings("unused")
206 @CalledByNative 230 @CalledByNative
207 private static void addShortcut( 231 private static void addShortcut(
208 String id, String url, String userTitle, Bitmap icon, int source) { 232 String id, String url, String userTitle, Bitmap icon, int source) {
209 Context context = ContextUtils.getApplicationContext(); 233 Context context = ContextUtils.getApplicationContext();
210 final Intent shortcutIntent = createShortcutIntent(url); 234 final Intent shortcutIntent = createShortcutIntent(url);
211 shortcutIntent.putExtra(EXTRA_ID, id); 235 shortcutIntent.putExtra(EXTRA_ID, id);
212 shortcutIntent.putExtra(EXTRA_SOURCE, source); 236 shortcutIntent.putExtra(EXTRA_SOURCE, source);
213 shortcutIntent.setPackage(context.getPackageName()); 237 shortcutIntent.setPackage(context.getPackageName());
214 sDelegate.addShortcutToHomescreen(userTitle, icon, shortcutIntent); 238 sDelegate.addShortcutToHomescreen(userTitle, icon, shortcutIntent);
215 if (ChromeShortcutManager.getInstance().shouldShowToastWhenAddingShortcu t()) { 239 if (shouldShowToastWhenAddingShortcut()) {
216 showAddedToHomescreenToast(userTitle); 240 showAddedToHomescreenToast(userTitle);
217 } 241 }
218 } 242 }
219 243
244 // TODO(martiw): Use Build.VERSION_CODES.O instead of hardcoded number when it is available.
245 @TargetApi(26)
246 private static void addShortcutWithShortcutManager(
247 String title, Bitmap icon, Intent shortcutIntent) {
248 String id = shortcutIntent.getStringExtra(ShortcutHelper.EXTRA_ID);
249 Context context = ContextUtils.getApplicationContext();
250
251 // The code in the try-block uses reflection in order to compile as it c alls APIs newer than
252 // our compileSdkVersion of Android. The equivalent code without reflect ion looks like this:
253 // ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(context, id)
254 // .setShortLabel(title)
255 // .setLongLabel(title)
256 // .setIcon(Icon.createWithBitmap(icon) )
257 // .setIntent(shortcutIntent)
258 // .build();
259 // sShortcutManager.requestPinShortcut(shortcutInfo, null);
260 // TODO(martiw): Remove the following reflection once compileSdk is bump ed to O.
261 try {
262 Class<?> builderClass = Class.forName("android.content.pm.ShortcutIn fo$Builder");
263 Constructor<?> builderConstructor =
264 builderClass.getDeclaredConstructor(Context.class, String.cl ass);
265 Object shortcutBuilder = builderConstructor.newInstance(context, id) ;
266
267 Method setShortLabel = builderClass.getMethod("setShortLabel", CharS equence.class);
268 setShortLabel.invoke(shortcutBuilder, title);
269
270 Method setLongLabel = builderClass.getMethod("setLongLabel", CharSeq uence.class);
271 setLongLabel.invoke(shortcutBuilder, title);
272
273 Method setIcon = builderClass.getMethod("setIcon", Icon.class);
274 setIcon.invoke(shortcutBuilder, Icon.createWithBitmap(icon));
275
276 Method setIntent = builderClass.getMethod("setIntent", Intent.class) ;
277 setIntent.invoke(shortcutBuilder, shortcutIntent);
278
279 Method build = builderClass.getMethod("build");
280 Object shortcutInfo = build.invoke(shortcutBuilder);
281
282 Class<?> ShortcutInfoClass = Class.forName("android.content.pm.Short cutInfo");
283 Method requestPinShortcut = sShortcutManager.getClass().getMethod(
284 "requestPinShortcut", ShortcutInfoClass, IntentSender.class) ;
285 requestPinShortcut.invoke(sShortcutManager, shortcutInfo, null);
286 } catch (ClassNotFoundException | NoSuchMethodException | InstantiationE xception
287 | InvocationTargetException | IllegalAccessException e) {
288 Log.e(TAG, "Error adding shortcut with ShortcutManager:", e);
289 }
290 }
291
220 /** 292 /**
221 * Show toast to alert user that the shortcut was added to the home screen. 293 * Show toast to alert user that the shortcut was added to the home screen.
222 */ 294 */
223 private static void showAddedToHomescreenToast(final String title) { 295 private static void showAddedToHomescreenToast(final String title) {
224 Context applicationContext = ContextUtils.getApplicationContext(); 296 Context applicationContext = ContextUtils.getApplicationContext();
225 String toastText = applicationContext.getString(R.string.added_to_homesc reen, title); 297 String toastText = applicationContext.getString(R.string.added_to_homesc reen, title);
226 showToast(toastText); 298 showToast(toastText);
227 } 299 }
228 300
229 /** 301 /**
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 336
265 @Override 337 @Override
266 protected void onPostExecute(String encodedImage) { 338 protected void onPostExecute(String encodedImage) {
267 storage.updateSplashScreenImage(encodedImage); 339 storage.updateSplashScreenImage(encodedImage);
268 } 340 }
269 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 341 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
270 } 342 }
271 } 343 }
272 344
273 /** 345 /**
346 * Creates an intent that will add a shortcut to the home screen.
347 * @param title Title of the shortcut.
348 * @param icon Image that represents the shortcut.
349 * @param shortcutIntent Intent to fire when the shortcut is activated.
350 * @return Intent for the shortcut.
351 */
352 public static Intent createAddToHomeIntent(String title, Bitmap icon, Intent shortcutIntent) {
353 Intent i = new Intent(INSTALL_SHORTCUT);
354 i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
355 i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
356 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon);
357 return i;
358 }
359
360 /**
274 * Creates a shortcut to launch a web app on the home screen. 361 * Creates a shortcut to launch a web app on the home screen.
275 * @param id Id of the web app. 362 * @param id Id of the web app.
276 * @param action Intent action to open a full screen activity. 363 * @param action Intent action to open a full screen activity.
277 * @param url Url of the web app. 364 * @param url Url of the web app.
278 * @param scope Url scope of the web app. 365 * @param scope Url scope of the web app.
279 * @param name Name of the web app. 366 * @param name Name of the web app.
280 * @param shortName Short name of the web app. 367 * @param shortName Short name of the web app.
281 * @param icon Icon of the web app. 368 * @param icon Icon of the web app.
282 * @param version Version number of the shortcut. 369 * @param version Version number of the shortcut.
283 * @param displayMode Display mode of the web app. 370 * @param displayMode Display mode of the web app.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 public static Intent createShortcutIntent(String url) { 422 public static Intent createShortcutIntent(String url) {
336 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); 423 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
337 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true); 424 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true);
338 return shortcutIntent; 425 return shortcutIntent;
339 } 426 }
340 427
341 /** 428 /**
342 * Utility method to check if a shortcut can be added to the home screen. 429 * Utility method to check if a shortcut can be added to the home screen.
343 * @return if a shortcut can be added to the home screen under the current p rofile. 430 * @return if a shortcut can be added to the home screen under the current p rofile.
344 */ 431 */
432 // TODO(crbug.com/635567): Fix this properly.
433 @SuppressLint("WrongConstant")
345 public static boolean isAddToHomeIntentSupported() { 434 public static boolean isAddToHomeIntentSupported() {
346 return ChromeShortcutManager.getInstance().canAddShortcutToHomescreen(); 435 if (isRequestPinShortcutSupported()) return true;
436 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag er();
437 Intent i = new Intent(INSTALL_SHORTCUT);
438 List<ResolveInfo> receivers =
439 pm.queryBroadcastReceivers(i, PackageManager.GET_INTENT_FILTERS) ;
440 return !receivers.isEmpty();
347 } 441 }
348 442
349 /** 443 /**
350 * Returns whether the given icon matches the size requirements to be used o n the home screen. 444 * Returns whether the given icon matches the size requirements to be used o n the home screen.
351 * @param width Icon width, in pixels. 445 * @param width Icon width, in pixels.
352 * @param height Icon height, in pixels. 446 * @param height Icon height, in pixels.
353 * @return whether the given icon matches the size requirements to be used o n the home screen. 447 * @return whether the given icon matches the size requirements to be used o n the home screen.
354 */ 448 */
355 @CalledByNative 449 @CalledByNative
356 public static boolean isIconLargeEnoughForLauncher(int width, int height) { 450 public static boolean isIconLargeEnoughForLauncher(int width, int height) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 int maxY = icon.getHeight() - 1; 710 int maxY = icon.getHeight() - 1;
617 711
618 if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixe l(maxX, maxY)) != 0) 712 if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixe l(maxX, maxY)) != 0)
619 && (Color.alpha(icon.getPixel(0, maxY)) != 0) 713 && (Color.alpha(icon.getPixel(0, maxY)) != 0)
620 && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) { 714 && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) {
621 return true; 715 return true;
622 } 716 }
623 return false; 717 return false;
624 } 718 }
625 719
720 private static boolean shouldShowToastWhenAddingShortcut() {
721 return !isRequestPinShortcutSupported();
722 }
723
724 private static boolean isRequestPinShortcutSupported() {
725 if (!sCheckedIfRequestPinShortcutSupported) {
726 if (BuildInfo.isAtLeastO()) {
727 checkIfRequestPinShortcutSupported();
728 }
729 sCheckedIfRequestPinShortcutSupported = true;
730 }
731 return sIsRequestPinShortcutSupported;
732 }
733
734 // TODO(martiw): Use Build.VERSION_CODES.O instead of hardcoded number when it is available.
735 @TargetApi(26)
736 private static void checkIfRequestPinShortcutSupported() {
737 // The code in the try-block uses reflection in order to compile as it c alls APIs newer than
738 // our target version of Android. The equivalent code without reflection is as follows:
739 // sShortcutManager =
740 // ContextUtils.getApplicationContext().getSystemService(Shortc utManager.class);
741 // sIsRequestPinShortcutSupported = sShortcutManager.isRequestPinShortc utSupported();
742 // TODO(martiw): Remove the following reflection once compileSdk is bump ed to O.
743 try {
744 Class<?> ShortcutManagerClass = Class.forName("android.content.pm.Sh ortcutManager");
745 sShortcutManager =
746 ContextUtils.getApplicationContext().getSystemService(Shortc utManagerClass);
747
748 Method isRequestPinShortcutSupported =
749 ShortcutManagerClass.getMethod("isRequestPinShortcutSupporte d");
750 sIsRequestPinShortcutSupported =
751 (boolean) isRequestPinShortcutSupported.invoke(sShortcutMana ger);
752 } catch (ClassNotFoundException | NoSuchMethodException | InvocationTarg etException
753 | IllegalAccessException e) {
754 Log.e(TAG, "Error checking if RequestPinShortcut is supported:", e);
755 }
756 }
757
626 private static int getSizeFromResourceInPx(Context context, int resource) { 758 private static int getSizeFromResourceInPx(Context context, int resource) {
627 return Math.round(context.getResources().getDimension(resource)); 759 return Math.round(context.getResources().getDimension(resource));
628 } 760 }
629 761
630 private static Bitmap getBitmapFromResourceId(Context context, int id, int d ensity) { 762 private static Bitmap getBitmapFromResourceId(Context context, int id, int d ensity) {
631 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity( 763 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity(
632 context.getResources(), id, density); 764 context.getResources(), id, density);
633 765
634 if (drawable instanceof BitmapDrawable) { 766 if (drawable instanceof BitmapDrawable) {
635 BitmapDrawable bd = (BitmapDrawable) drawable; 767 BitmapDrawable bd = (BitmapDrawable) drawable;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
709 } 841 }
710 return array; 842 return array;
711 } 843 }
712 844
713 private static native void nativeOnWebappDataStored(long callbackPointer); 845 private static native void nativeOnWebappDataStored(long callbackPointer);
714 private static native void nativeOnWebApksRetrieved(long callbackPointer, St ring[] names, 846 private static native void nativeOnWebApksRetrieved(long callbackPointer, St ring[] names,
715 String[] shortNames, String[] packageName, int[] shellApkVersions, i nt[] versionCodes, 847 String[] shortNames, String[] packageName, int[] shellApkVersions, i nt[] versionCodes,
716 String[] uris, String[] scopes, String[] manifestUrls, String[] mani festStartUrls, 848 String[] uris, String[] scopes, String[] manifestUrls, String[] mani festStartUrls,
717 int[] displayModes, int[] orientations, long[] themeColors, long[] b ackgroundColors); 849 int[] displayModes, int[] orientations, long[] themeColors, long[] b ackgroundColors);
718 } 850 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698