OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |