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 private static final String INSTALL_SHORTCUT = "com.android.launcher.action.
INSTALL_SHORTCUT"; |
| 100 |
91 // The activity class used for launching a WebApk. | 101 // The activity class used for launching a WebApk. |
92 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel
l_apk.MainActivity"; | 102 private static final String WEBAPK_MAIN_ACTIVITY = "org.chromium.webapk.shel
l_apk.MainActivity"; |
93 | 103 |
94 // These sizes are from the Material spec for icons: | 104 // These sizes are from the Material spec for icons: |
95 // https://www.google.com/design/spec/style/icons.html#icons-product-icons | 105 // https://www.google.com/design/spec/style/icons.html#icons-product-icons |
96 private static final float MAX_INNER_SIZE_RATIO = 1.25f; | 106 private static final float MAX_INNER_SIZE_RATIO = 1.25f; |
97 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f; | 107 private static final float ICON_PADDING_RATIO = 2.0f / 44.0f; |
98 private static final float ICON_CORNER_RADIUS_RATIO = 1.0f / 16.0f; | 108 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; | 109 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; | 110 private static final float GENERATED_ICON_FONT_SIZE_RATIO = 1.0f / 3.0f; |
101 | 111 |
| 112 // True when Android O's ShortcutManager.requestPinShortcut() is supported. |
| 113 private static boolean sIsRequestPinShortcutSupported; |
| 114 |
| 115 // True when it is already checked if ShortcutManager.requestPinShortcut() i
s supported. |
| 116 private static boolean sCheckedIfRequestPinShortcutSupported; |
| 117 |
| 118 // TODO(martiw): Use 'ShortcutInfo' instead of 'Object' below when compileSd
k is bumped to O. |
| 119 private static Object sShortcutManager; |
| 120 |
102 /** Helper for generating home screen shortcuts. */ | 121 /** Helper for generating home screen shortcuts. */ |
103 public static class Delegate { | 122 public static class Delegate { |
104 /** | 123 /** |
105 * Request Android to add a shortcut to the home screen. | 124 * Request Android to add a shortcut to the home screen. |
106 * @param title Title of the shortcut. | 125 * @param title Title of the shortcut. |
107 * @param icon Image that represents the shortcut. | 126 * @param icon Image that represents the shortcut. |
108 * @param intent Intent to fire when the shortcut is activated. | 127 * @param intent Intent to fire when the shortcut is activated. |
109 */ | 128 */ |
110 public void addShortcutToHomescreen(String title, Bitmap icon, Intent sh
ortcutIntent) { | 129 public void addShortcutToHomescreen(String title, Bitmap icon, Intent sh
ortcutIntent) { |
111 ChromeShortcutManager.getInstance().addShortcutToHomeScreen( | 130 if (isRequestPinShortcutSupported()) { |
112 title, icon, shortcutIntent); | 131 addShortcutWithShortcutManager(title, icon, shortcutIntent); |
| 132 return; |
| 133 } |
| 134 Intent intent = createAddToHomeIntent(title, icon, shortcutIntent); |
| 135 ContextUtils.getApplicationContext().sendBroadcast(intent); |
113 } | 136 } |
114 | 137 |
115 /** | 138 /** |
116 * Returns the name of the fullscreen Activity to use when launching sho
rtcuts. | 139 * Returns the name of the fullscreen Activity to use when launching sho
rtcuts. |
117 */ | 140 */ |
118 public String getFullscreenAction() { | 141 public String getFullscreenAction() { |
119 return WebappLauncherActivity.ACTION_START_WEBAPP; | 142 return WebappLauncherActivity.ACTION_START_WEBAPP; |
120 } | 143 } |
121 } | 144 } |
122 | 145 |
(...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 | 189 // process is complete, call back to native code to start the sp
lash image |
167 // download. | 190 // download. |
168 WebappRegistry.getInstance().register( | 191 WebappRegistry.getInstance().register( |
169 id, new WebappRegistry.FetchWebappDataStorageCallback()
{ | 192 id, new WebappRegistry.FetchWebappDataStorageCallback()
{ |
170 @Override | 193 @Override |
171 public void onWebappDataStorageRetrieved(WebappDataS
torage storage) { | 194 public void onWebappDataStorageRetrieved(WebappDataS
torage storage) { |
172 storage.updateFromShortcutIntent(resultIntent); | 195 storage.updateFromShortcutIntent(resultIntent); |
173 nativeOnWebappDataStored(callbackPointer); | 196 nativeOnWebappDataStored(callbackPointer); |
174 } | 197 } |
175 }); | 198 }); |
176 if (ChromeShortcutManager.getInstance().shouldShowToastWhenAddin
gShortcut()) { | 199 if (shouldShowToastWhenAddingShortcut()) { |
177 showAddedToHomescreenToast(userTitle); | 200 showAddedToHomescreenToast(userTitle); |
178 } | 201 } |
179 } | 202 } |
180 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | 203 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
181 } | 204 } |
182 | 205 |
183 public static void addWebApkShortcut(Context context, String packageName) { | 206 public static void addWebApkShortcut(Context context, String packageName) { |
184 PackageManager pm = context.getPackageManager(); | 207 PackageManager pm = context.getPackageManager(); |
185 try { | 208 try { |
186 ApplicationInfo appInfo = pm.getApplicationInfo( | 209 ApplicationInfo appInfo = pm.getApplicationInfo( |
187 packageName, PackageManager.GET_META_DATA); | 210 packageName, PackageManager.GET_META_DATA); |
188 String shortcutTitle = pm.getApplicationLabel(appInfo).toString(); | 211 String shortcutTitle = pm.getApplicationLabel(appInfo).toString(); |
189 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag
eName)).getBitmap(); | 212 Bitmap shortcutIcon = ((BitmapDrawable) pm.getApplicationIcon(packag
eName)).getBitmap(); |
190 | 213 |
191 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon); | 214 Bitmap bitmap = createHomeScreenIconFromWebIcon(shortcutIcon); |
192 Intent i = new Intent(); | 215 Intent i = new Intent(); |
193 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY); | 216 i.setClassName(packageName, WEBAPK_MAIN_ACTIVITY); |
194 i.addCategory(Intent.CATEGORY_LAUNCHER); | 217 i.addCategory(Intent.CATEGORY_LAUNCHER); |
195 context.sendBroadcast( | 218 context.sendBroadcast(createAddToHomeIntent(shortcutTitle, bitmap, i
)); |
196 ChromeShortcutManager.createAddToHomeIntent(shortcutTitle, b
itmap, i)); | |
197 } catch (NameNotFoundException e) { | 219 } catch (NameNotFoundException e) { |
198 e.printStackTrace(); | 220 e.printStackTrace(); |
199 } | 221 } |
200 } | 222 } |
201 | 223 |
202 /** | 224 /** |
203 * Adds home screen shortcut which opens in the browser Activity. | 225 * Adds home screen shortcut which opens in the browser Activity. |
204 */ | 226 */ |
205 @SuppressWarnings("unused") | 227 @SuppressWarnings("unused") |
206 @CalledByNative | 228 @CalledByNative |
207 private static void addShortcut( | 229 private static void addShortcut( |
208 String id, String url, String userTitle, Bitmap icon, int source) { | 230 String id, String url, String userTitle, Bitmap icon, int source) { |
209 Context context = ContextUtils.getApplicationContext(); | 231 Context context = ContextUtils.getApplicationContext(); |
210 final Intent shortcutIntent = createShortcutIntent(url); | 232 final Intent shortcutIntent = createShortcutIntent(url); |
211 shortcutIntent.putExtra(EXTRA_ID, id); | 233 shortcutIntent.putExtra(EXTRA_ID, id); |
212 shortcutIntent.putExtra(EXTRA_SOURCE, source); | 234 shortcutIntent.putExtra(EXTRA_SOURCE, source); |
213 shortcutIntent.setPackage(context.getPackageName()); | 235 shortcutIntent.setPackage(context.getPackageName()); |
214 sDelegate.addShortcutToHomescreen(userTitle, icon, shortcutIntent); | 236 sDelegate.addShortcutToHomescreen(userTitle, icon, shortcutIntent); |
215 if (ChromeShortcutManager.getInstance().shouldShowToastWhenAddingShortcu
t()) { | 237 if (shouldShowToastWhenAddingShortcut()) { |
216 showAddedToHomescreenToast(userTitle); | 238 showAddedToHomescreenToast(userTitle); |
217 } | 239 } |
218 } | 240 } |
219 | 241 |
| 242 // TODO(martiw): Use Build.VERSION_CODES.O instead of hardcoded number when
it is available. |
| 243 @TargetApi(26) |
| 244 private static void addShortcutWithShortcutManager( |
| 245 String title, Bitmap icon, Intent shortcutIntent) { |
| 246 String id = shortcutIntent.getStringExtra(ShortcutHelper.EXTRA_ID); |
| 247 Context context = ContextUtils.getApplicationContext(); |
| 248 |
| 249 // The code in the try-block uses reflection in order to compile as it c
alls APIs newer than |
| 250 // our compileSdkVersion of Android. The equivalent code without reflect
ion looks like this: |
| 251 // ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(context, id) |
| 252 // .setShortLabel(title) |
| 253 // .setLongLabel(title) |
| 254 // .setIcon(Icon.createWithBitmap(icon)
) |
| 255 // .setIntent(shortcutIntent) |
| 256 // .build(); |
| 257 // sShortcutManager.requestPinShortcut(shortcutInfo, null); |
| 258 // TODO(martiw): Remove the following reflection once compileSdk is bump
ed to O. |
| 259 try { |
| 260 Class<?> builderClass = Class.forName("android.content.pm.ShortcutIn
fo$Builder"); |
| 261 Constructor<?> builderConstructor = |
| 262 builderClass.getDeclaredConstructor(Context.class, String.cl
ass); |
| 263 Object shortcutBuilder = builderConstructor.newInstance(context, id)
; |
| 264 |
| 265 Method setShortLabel = builderClass.getMethod("setShortLabel", CharS
equence.class); |
| 266 setShortLabel.invoke(shortcutBuilder, title); |
| 267 |
| 268 Method setLongLabel = builderClass.getMethod("setLongLabel", CharSeq
uence.class); |
| 269 setLongLabel.invoke(shortcutBuilder, title); |
| 270 |
| 271 Method setIcon = builderClass.getMethod("setIcon", Icon.class); |
| 272 setIcon.invoke(shortcutBuilder, Icon.createWithBitmap(icon)); |
| 273 |
| 274 Method setIntent = builderClass.getMethod("setIntent", Intent.class)
; |
| 275 setIntent.invoke(shortcutBuilder, shortcutIntent); |
| 276 |
| 277 Method build = builderClass.getMethod("build"); |
| 278 Object shortcutInfo = build.invoke(shortcutBuilder); |
| 279 |
| 280 Class<?> ShortcutInfoClass = Class.forName("android.content.pm.Short
cutInfo"); |
| 281 Method requestPinShortcut = sShortcutManager.getClass().getMethod( |
| 282 "requestPinShortcut", ShortcutInfoClass, IntentSender.class)
; |
| 283 requestPinShortcut.invoke(sShortcutManager, shortcutInfo, null); |
| 284 } catch (ClassNotFoundException | NoSuchMethodException | InstantiationE
xception |
| 285 | InvocationTargetException | IllegalAccessException e) { |
| 286 Log.e(TAG, "Error adding shortcut with ShortcutManager:", e); |
| 287 } |
| 288 } |
| 289 |
220 /** | 290 /** |
221 * Show toast to alert user that the shortcut was added to the home screen. | 291 * Show toast to alert user that the shortcut was added to the home screen. |
222 */ | 292 */ |
223 private static void showAddedToHomescreenToast(final String title) { | 293 private static void showAddedToHomescreenToast(final String title) { |
224 Context applicationContext = ContextUtils.getApplicationContext(); | 294 Context applicationContext = ContextUtils.getApplicationContext(); |
225 String toastText = applicationContext.getString(R.string.added_to_homesc
reen, title); | 295 String toastText = applicationContext.getString(R.string.added_to_homesc
reen, title); |
226 showToast(toastText); | 296 showToast(toastText); |
227 } | 297 } |
228 | 298 |
229 /** | 299 /** |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 334 |
265 @Override | 335 @Override |
266 protected void onPostExecute(String encodedImage) { | 336 protected void onPostExecute(String encodedImage) { |
267 storage.updateSplashScreenImage(encodedImage); | 337 storage.updateSplashScreenImage(encodedImage); |
268 } | 338 } |
269 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | 339 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
270 } | 340 } |
271 } | 341 } |
272 | 342 |
273 /** | 343 /** |
| 344 * Creates an intent that will add a shortcut to the home screen. |
| 345 * @param title Title of the shortcut. |
| 346 * @param icon Image that represents the shortcut. |
| 347 * @param shortcutIntent Intent to fire when the shortcut is activated. |
| 348 * @return Intent for the shortcut. |
| 349 */ |
| 350 public static Intent createAddToHomeIntent(String title, Bitmap icon, Intent
shortcutIntent) { |
| 351 Intent i = new Intent(INSTALL_SHORTCUT); |
| 352 i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); |
| 353 i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title); |
| 354 i.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon); |
| 355 return i; |
| 356 } |
| 357 |
| 358 /** |
274 * Creates a shortcut to launch a web app on the home screen. | 359 * Creates a shortcut to launch a web app on the home screen. |
275 * @param id Id of the web app. | 360 * @param id Id of the web app. |
276 * @param action Intent action to open a full screen activity. | 361 * @param action Intent action to open a full screen activity. |
277 * @param url Url of the web app. | 362 * @param url Url of the web app. |
278 * @param scope Url scope of the web app. | 363 * @param scope Url scope of the web app. |
279 * @param name Name of the web app. | 364 * @param name Name of the web app. |
280 * @param shortName Short name of the web app. | 365 * @param shortName Short name of the web app. |
281 * @param icon Icon of the web app. | 366 * @param icon Icon of the web app. |
282 * @param version Version number of the shortcut. | 367 * @param version Version number of the shortcut. |
283 * @param displayMode Display mode of the web app. | 368 * @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) { | 420 public static Intent createShortcutIntent(String url) { |
336 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); | 421 Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); |
337 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true); | 422 shortcutIntent.putExtra(REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB, true); |
338 return shortcutIntent; | 423 return shortcutIntent; |
339 } | 424 } |
340 | 425 |
341 /** | 426 /** |
342 * Utility method to check if a shortcut can be added to the home screen. | 427 * 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. | 428 * @return if a shortcut can be added to the home screen under the current p
rofile. |
344 */ | 429 */ |
| 430 // TODO(crbug.com/635567): Fix this properly. |
| 431 @SuppressLint("WrongConstant") |
345 public static boolean isAddToHomeIntentSupported() { | 432 public static boolean isAddToHomeIntentSupported() { |
346 return ChromeShortcutManager.getInstance().canAddShortcutToHomescreen(); | 433 if (isRequestPinShortcutSupported()) return true; |
| 434 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag
er(); |
| 435 Intent i = new Intent(INSTALL_SHORTCUT); |
| 436 List<ResolveInfo> receivers = |
| 437 pm.queryBroadcastReceivers(i, PackageManager.GET_INTENT_FILTERS)
; |
| 438 return !receivers.isEmpty(); |
347 } | 439 } |
348 | 440 |
349 /** | 441 /** |
350 * Returns whether the given icon matches the size requirements to be used o
n the home screen. | 442 * Returns whether the given icon matches the size requirements to be used o
n the home screen. |
351 * @param width Icon width, in pixels. | 443 * @param width Icon width, in pixels. |
352 * @param height Icon height, in pixels. | 444 * @param height Icon height, in pixels. |
353 * @return whether the given icon matches the size requirements to be used o
n the home screen. | 445 * @return whether the given icon matches the size requirements to be used o
n the home screen. |
354 */ | 446 */ |
355 @CalledByNative | 447 @CalledByNative |
356 public static boolean isIconLargeEnoughForLauncher(int width, int height) { | 448 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; | 708 int maxY = icon.getHeight() - 1; |
617 | 709 |
618 if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixe
l(maxX, maxY)) != 0) | 710 if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixe
l(maxX, maxY)) != 0) |
619 && (Color.alpha(icon.getPixel(0, maxY)) != 0) | 711 && (Color.alpha(icon.getPixel(0, maxY)) != 0) |
620 && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) { | 712 && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) { |
621 return true; | 713 return true; |
622 } | 714 } |
623 return false; | 715 return false; |
624 } | 716 } |
625 | 717 |
| 718 private static boolean shouldShowToastWhenAddingShortcut() { |
| 719 return !isRequestPinShortcutSupported(); |
| 720 } |
| 721 |
| 722 private static boolean isRequestPinShortcutSupported() { |
| 723 if (!sCheckedIfRequestPinShortcutSupported) { |
| 724 if (BuildInfo.isAtLeastO()) { |
| 725 checkIfRequestPinShortcutSupported(); |
| 726 } |
| 727 sCheckedIfRequestPinShortcutSupported = true; |
| 728 } |
| 729 return sIsRequestPinShortcutSupported; |
| 730 } |
| 731 |
| 732 // TODO(martiw): Use Build.VERSION_CODES.O instead of hardcoded number when
it is available. |
| 733 @TargetApi(26) |
| 734 private static void checkIfRequestPinShortcutSupported() { |
| 735 // The code in the try-block uses reflection in order to compile as it c
alls APIs newer than |
| 736 // our target version of Android. The equivalent code without reflection
is as follows: |
| 737 // sShortcutManager = |
| 738 // ContextUtils.getApplicationContext().getSystemService(Shortc
utManager.class); |
| 739 // sIsRequestPinShortcutSupported = sShortcutManager.isRequestPinShortc
utSupported(); |
| 740 // TODO(martiw): Remove the following reflection once compileSdk is bump
ed to O. |
| 741 try { |
| 742 Class<?> ShortcutManagerClass = Class.forName("android.content.pm.Sh
ortcutManager"); |
| 743 sShortcutManager = |
| 744 ContextUtils.getApplicationContext().getSystemService(Shortc
utManagerClass); |
| 745 |
| 746 Method isRequestPinShortcutSupported = |
| 747 ShortcutManagerClass.getMethod("isRequestPinShortcutSupporte
d"); |
| 748 sIsRequestPinShortcutSupported = |
| 749 (boolean) isRequestPinShortcutSupported.invoke(sShortcutMana
ger); |
| 750 } catch (ClassNotFoundException | NoSuchMethodException | InvocationTarg
etException |
| 751 | IllegalAccessException e) { |
| 752 Log.e(TAG, "Error checking if RequestPinShortcut is supported:", e); |
| 753 } |
| 754 } |
| 755 |
626 private static int getSizeFromResourceInPx(Context context, int resource) { | 756 private static int getSizeFromResourceInPx(Context context, int resource) { |
627 return Math.round(context.getResources().getDimension(resource)); | 757 return Math.round(context.getResources().getDimension(resource)); |
628 } | 758 } |
629 | 759 |
630 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { | 760 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { |
631 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity( | 761 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity( |
632 context.getResources(), id, density); | 762 context.getResources(), id, density); |
633 | 763 |
634 if (drawable instanceof BitmapDrawable) { | 764 if (drawable instanceof BitmapDrawable) { |
635 BitmapDrawable bd = (BitmapDrawable) drawable; | 765 BitmapDrawable bd = (BitmapDrawable) drawable; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 } | 839 } |
710 return array; | 840 return array; |
711 } | 841 } |
712 | 842 |
713 private static native void nativeOnWebappDataStored(long callbackPointer); | 843 private static native void nativeOnWebappDataStored(long callbackPointer); |
714 private static native void nativeOnWebApksRetrieved(long callbackPointer, St
ring[] names, | 844 private static native void nativeOnWebApksRetrieved(long callbackPointer, St
ring[] names, |
715 String[] shortNames, String[] packageName, int[] shellApkVersions, i
nt[] versionCodes, | 845 String[] shortNames, String[] packageName, int[] shellApkVersions, i
nt[] versionCodes, |
716 String[] uris, String[] scopes, String[] manifestUrls, String[] mani
festStartUrls, | 846 String[] uris, String[] scopes, String[] manifestUrls, String[] mani
festStartUrls, |
717 int[] displayModes, int[] orientations, long[] themeColors, long[] b
ackgroundColors); | 847 int[] displayModes, int[] orientations, long[] themeColors, long[] b
ackgroundColors); |
718 } | 848 } |
OLD | NEW |