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.app.ActivityManager; | 7 import android.app.ActivityManager; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.Intent; | 9 import android.content.Intent; |
10 import android.content.pm.PackageManager; | 10 import android.content.pm.PackageManager; |
(...skipping 10 matching lines...) Expand all Loading... |
21 import android.graphics.RectF; | 21 import android.graphics.RectF; |
22 import android.graphics.drawable.BitmapDrawable; | 22 import android.graphics.drawable.BitmapDrawable; |
23 import android.graphics.drawable.Drawable; | 23 import android.graphics.drawable.Drawable; |
24 import android.net.Uri; | 24 import android.net.Uri; |
25 import android.os.Handler; | 25 import android.os.Handler; |
26 import android.os.Looper; | 26 import android.os.Looper; |
27 import android.text.TextUtils; | 27 import android.text.TextUtils; |
28 import android.util.Base64; | 28 import android.util.Base64; |
29 | 29 |
30 import org.chromium.base.ApiCompatibilityUtils; | 30 import org.chromium.base.ApiCompatibilityUtils; |
| 31 import org.chromium.base.CommandLine; |
31 import org.chromium.base.ContextUtils; | 32 import org.chromium.base.ContextUtils; |
32 import org.chromium.base.Log; | 33 import org.chromium.base.Log; |
33 import org.chromium.base.ThreadUtils; | 34 import org.chromium.base.ThreadUtils; |
34 import org.chromium.base.VisibleForTesting; | 35 import org.chromium.base.VisibleForTesting; |
35 import org.chromium.base.annotations.CalledByNative; | 36 import org.chromium.base.annotations.CalledByNative; |
36 import org.chromium.blink_public.platform.WebDisplayMode; | 37 import org.chromium.blink_public.platform.WebDisplayMode; |
37 import org.chromium.chrome.R; | 38 import org.chromium.chrome.R; |
| 39 import org.chromium.chrome.browser.webapps.WebApkBuilder; |
38 import org.chromium.chrome.browser.webapps.WebappAuthenticator; | 40 import org.chromium.chrome.browser.webapps.WebappAuthenticator; |
39 import org.chromium.chrome.browser.webapps.WebappDataStorage; | 41 import org.chromium.chrome.browser.webapps.WebappDataStorage; |
40 import org.chromium.chrome.browser.webapps.WebappLauncherActivity; | 42 import org.chromium.chrome.browser.webapps.WebappLauncherActivity; |
41 import org.chromium.chrome.browser.webapps.WebappRegistry; | 43 import org.chromium.chrome.browser.webapps.WebappRegistry; |
42 import org.chromium.chrome.browser.widget.RoundedIconGenerator; | 44 import org.chromium.chrome.browser.widget.RoundedIconGenerator; |
43 import org.chromium.content_public.common.ScreenOrientationConstants; | 45 import org.chromium.content_public.common.ScreenOrientationConstants; |
| 46 import org.chromium.net.GURLUtils; |
44 import org.chromium.ui.widget.Toast; | 47 import org.chromium.ui.widget.Toast; |
45 | 48 |
46 import java.io.ByteArrayOutputStream; | 49 import java.io.ByteArrayOutputStream; |
47 import java.util.List; | 50 import java.util.List; |
48 | 51 |
49 /** | 52 /** |
50 * This class contains functions related to adding shortcuts to the Android Home | 53 * This class contains functions related to adding shortcuts to the Android Home |
51 * screen. These shortcuts are used to either open a page in the main browser | 54 * screen. These shortcuts are used to either open a page in the main browser |
52 * or open a web app. | 55 * or open a web app. |
53 */ | 56 */ |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 /** | 133 /** |
131 * Called when we have to fire an Intent to add a shortcut to the home scree
n. | 134 * Called when we have to fire an Intent to add a shortcut to the home scree
n. |
132 * If the webpage indicated that it was capable of functioning as a webapp,
it is added as a | 135 * If the webpage indicated that it was capable of functioning as a webapp,
it is added as a |
133 * shortcut to a webapp Activity rather than as a general bookmark. User is
sent to the | 136 * shortcut to a webapp Activity rather than as a general bookmark. User is
sent to the |
134 * home screen as soon as the shortcut is created. | 137 * home screen as soon as the shortcut is created. |
135 * | 138 * |
136 * This method must not be called on the UI thread. | 139 * This method must not be called on the UI thread. |
137 */ | 140 */ |
138 @SuppressWarnings("unused") | 141 @SuppressWarnings("unused") |
139 @CalledByNative | 142 @CalledByNative |
140 private static void addShortcut(Context context, String id, String url, fina
l String userTitle, | 143 private static void addShortcut(String id, String url, final String userTitl
e, |
141 String name, String shortName, Bitmap icon, int displayMode, int ori
entation, | 144 String name, String shortName, Bitmap icon, int displayMode, int ori
entation, |
142 int source, long themeColor, long backgroundColor, boolean isIconGen
erated, | 145 int source, long themeColor, long backgroundColor, boolean isIconGen
erated, |
143 final long callbackPointer) { | 146 final long callbackPointer) { |
144 assert !ThreadUtils.runningOnUiThread(); | 147 assert !ThreadUtils.runningOnUiThread(); |
| 148 |
| 149 Context context = ContextUtils.getApplicationContext(); |
145 final Intent shortcutIntent; | 150 final Intent shortcutIntent; |
146 boolean isWebappCapable = (displayMode == WebDisplayMode.Standalone | 151 boolean isWebappCapable = (displayMode == WebDisplayMode.Standalone |
147 || displayMode == WebDisplayMode.Fullscreen); | 152 || displayMode == WebDisplayMode.Fullscreen); |
148 if (isWebappCapable) { | 153 if (isWebappCapable) { |
| 154 if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_WEBAPK
)) { |
| 155 WebApkBuilder apkBuilder = ((ChromeApplication) context).createW
ebApkBuilder(); |
| 156 if (apkBuilder != null) { |
| 157 apkBuilder.buildWebApkAsync(url, GURLUtils.getOrigin(url), s
hortName, icon); |
| 158 return; |
| 159 } |
| 160 } |
149 shortcutIntent = createWebappShortcutIntent(id, sDelegate.getFullscr
eenAction(), url, | 161 shortcutIntent = createWebappShortcutIntent(id, sDelegate.getFullscr
eenAction(), url, |
150 getScopeFromUrl(url), name, shortName, icon, WEBAPP_SHORTCUT
_VERSION, | 162 getScopeFromUrl(url), name, shortName, icon, WEBAPP_SHORTCUT
_VERSION, |
151 displayMode, orientation, themeColor, backgroundColor, isIco
nGenerated); | 163 displayMode, orientation, themeColor, backgroundColor, isIco
nGenerated); |
152 shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url)); | 164 shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url)); |
153 } else { | 165 } else { |
154 // Add the shortcut as a launcher icon to open in the browser Activi
ty. | 166 // Add the shortcut as a launcher icon to open in the browser Activi
ty. |
155 shortcutIntent = createShortcutIntent(url); | 167 shortcutIntent = createShortcutIntent(url); |
156 } | 168 } |
157 | 169 |
158 // Always attach a source (one of add to home screen menu item, app bann
er, or unknown) to | 170 // Always attach a source (one of add to home screen menu item, app bann
er, or unknown) to |
(...skipping 26 matching lines...) Expand all Loading... |
185 String toastText = | 197 String toastText = |
186 applicationContext.getString(R.string.added_to_homescree
n, userTitle); | 198 applicationContext.getString(R.string.added_to_homescree
n, userTitle); |
187 Toast toast = Toast.makeText(applicationContext, toastText, Toas
t.LENGTH_SHORT); | 199 Toast toast = Toast.makeText(applicationContext, toastText, Toas
t.LENGTH_SHORT); |
188 toast.show(); | 200 toast.show(); |
189 } | 201 } |
190 }); | 202 }); |
191 } | 203 } |
192 | 204 |
193 /** | 205 /** |
194 * Creates a storage location and stores the data for a web app using {@link
WebappDataStorage}. | 206 * Creates a storage location and stores the data for a web app using {@link
WebappDataStorage}. |
195 * @param context Context to open the WebappDataStorage with. | |
196 * @param id ID of the webapp which is storing data. | 207 * @param id ID of the webapp which is storing data. |
197 * @param splashImage Image which should be displayed on the splash screen o
f | 208 * @param splashImage Image which should be displayed on the splash screen o
f |
198 * the webapp. This can be null of there is no image to s
how. | 209 * the webapp. This can be null of there is no image to s
how. |
199 */ | 210 */ |
200 @SuppressWarnings("unused") | 211 @SuppressWarnings("unused") |
201 @CalledByNative | 212 @CalledByNative |
202 private static void storeWebappSplashImage(final Context context, final Stri
ng id, | 213 private static void storeWebappSplashImage(final String id, final Bitmap spl
ashImage) { |
203 final Bitmap splashImage) { | 214 WebappRegistry.getWebappDataStorage(ContextUtils.getApplicationContext()
, id, |
204 WebappRegistry.getWebappDataStorage(context, id, | |
205 new WebappRegistry.FetchWebappDataStorageCallback() { | 215 new WebappRegistry.FetchWebappDataStorageCallback() { |
206 @Override | 216 @Override |
207 public void onWebappDataStorageRetrieved(WebappDataStorage s
torage) { | 217 public void onWebappDataStorageRetrieved(WebappDataStorage s
torage) { |
208 if (storage == null) return; | 218 if (storage == null) return; |
209 | 219 |
210 storage.updateSplashScreenImage(splashImage); | 220 storage.updateSplashScreenImage(splashImage); |
211 } | 221 } |
212 | 222 |
213 } | 223 }); |
214 ); | |
215 } | 224 } |
216 | 225 |
217 /** | 226 /** |
218 * Creates an intent that will add a shortcut to the home screen. | 227 * Creates an intent that will add a shortcut to the home screen. |
219 * @param shortcutIntent Intent to fire when the shortcut is activated. | 228 * @param shortcutIntent Intent to fire when the shortcut is activated. |
220 * @param url URL of the shortcut. | 229 * @param url URL of the shortcut. |
221 * @param title Title of the shortcut. | 230 * @param title Title of the shortcut. |
222 * @param icon Image that represents the shortcut. | 231 * @param icon Image that represents the shortcut. |
223 * @return Intent for the shortcut. | 232 * @return Intent for the shortcut. |
224 */ | 233 */ |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 public static boolean isAddToHomeIntentSupported(Context context) { | 312 public static boolean isAddToHomeIntentSupported(Context context) { |
304 PackageManager pm = context.getPackageManager(); | 313 PackageManager pm = context.getPackageManager(); |
305 Intent i = new Intent(INSTALL_SHORTCUT); | 314 Intent i = new Intent(INSTALL_SHORTCUT); |
306 List<ResolveInfo> receivers = pm.queryBroadcastReceivers( | 315 List<ResolveInfo> receivers = pm.queryBroadcastReceivers( |
307 i, PackageManager.GET_INTENT_FILTERS); | 316 i, PackageManager.GET_INTENT_FILTERS); |
308 return !receivers.isEmpty(); | 317 return !receivers.isEmpty(); |
309 } | 318 } |
310 | 319 |
311 /** | 320 /** |
312 * Returns whether the given icon matches the size requirements to be used o
n the home screen. | 321 * Returns whether the given icon matches the size requirements to be used o
n the home screen. |
313 * @param context Context used to create the intent. | |
314 * @param width Icon width, in pixels. | 322 * @param width Icon width, in pixels. |
315 * @param height Icon height, in pixels. | 323 * @param height Icon height, in pixels. |
316 * @return whether the given icon matches the size requirements to be used o
n the home screen. | 324 * @return whether the given icon matches the size requirements to be used o
n the home screen. |
317 */ | 325 */ |
318 @CalledByNative | 326 @CalledByNative |
319 public static boolean isIconLargeEnoughForLauncher(Context context, int widt
h, int height) { | 327 public static boolean isIconLargeEnoughForLauncher(int width, int height) { |
| 328 Context context = ContextUtils.getApplicationContext(); |
320 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); | 329 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); |
321 final int minimalSize = am.getLauncherLargeIconSize() / 2; | 330 final int minimalSize = am.getLauncherLargeIconSize() / 2; |
322 return width >= minimalSize && height >= minimalSize; | 331 return width >= minimalSize && height >= minimalSize; |
323 } | 332 } |
324 | 333 |
325 /** | 334 /** |
326 * Adapts a website's icon (e.g. favicon or touch icon) to the Material desi
gn style guidelines | 335 * Adapts a website's icon (e.g. favicon or touch icon) to the Material desi
gn style guidelines |
327 * for home screen icons. This involves adding some padding and rounding the
corners. | 336 * for home screen icons. This involves adding some padding and rounding the
corners. |
328 * | 337 * |
329 * @param context Context used to create the intent. | 338 * @param context Context used to create the intent. |
330 * @param webIcon The website's favicon or touch icon. | 339 * @param webIcon The website's favicon or touch icon. |
331 * @return Bitmap Either the touch-icon or the newly created favicon. | 340 * @return Bitmap Either the touch-icon or the newly created favicon. |
332 */ | 341 */ |
333 @CalledByNative | 342 @CalledByNative |
334 public static Bitmap createHomeScreenIconFromWebIcon(Context context, Bitmap
webIcon) { | 343 public static Bitmap createHomeScreenIconFromWebIcon(Bitmap webIcon) { |
335 // getLauncherLargeIconSize() is just a guess at the launcher icon size,
and is often | 344 // getLauncherLargeIconSize() is just a guess at the launcher icon size,
and is often |
336 // wrong -- the launcher can show icons at any size it pleases. Instead
of resizing the | 345 // wrong -- the launcher can show icons at any size it pleases. Instead
of resizing the |
337 // icon to the supposed launcher size and then having the launcher resiz
e the icon again, | 346 // icon to the supposed launcher size and then having the launcher resiz
e the icon again, |
338 // just leave the icon at its original size and let the launcher do a si
ngle rescaling. | 347 // just leave the icon at its original size and let the launcher do a si
ngle rescaling. |
339 // Unless the icon is much too big; then scale it down here too. | 348 // Unless the icon is much too big; then scale it down here too. |
| 349 Context context = ContextUtils.getApplicationContext(); |
340 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); | 350 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); |
341 int maxInnerSize = Math.round(am.getLauncherLargeIconSize() * MAX_INNER_
SIZE_RATIO); | 351 int maxInnerSize = Math.round(am.getLauncherLargeIconSize() * MAX_INNER_
SIZE_RATIO); |
342 int innerSize = Math.min(maxInnerSize, Math.max(webIcon.getWidth(), webI
con.getHeight())); | 352 int innerSize = Math.min(maxInnerSize, Math.max(webIcon.getWidth(), webI
con.getHeight())); |
343 int padding = Math.round(ICON_PADDING_RATIO * innerSize); | 353 int padding = Math.round(ICON_PADDING_RATIO * innerSize); |
344 int outerSize = innerSize + 2 * padding; | 354 int outerSize = innerSize + 2 * padding; |
345 | 355 |
346 Bitmap bitmap = null; | 356 Bitmap bitmap = null; |
347 try { | 357 try { |
348 bitmap = Bitmap.createBitmap(outerSize, outerSize, Bitmap.Config.ARG
B_8888); | 358 bitmap = Bitmap.createBitmap(outerSize, outerSize, Bitmap.Config.ARG
B_8888); |
349 } catch (OutOfMemoryError e) { | 359 } catch (OutOfMemoryError e) { |
(...skipping 17 matching lines...) Expand all Loading... |
367 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); | 377 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); |
368 canvas.drawPath(path, paint); | 378 canvas.drawPath(path, paint); |
369 | 379 |
370 return bitmap; | 380 return bitmap; |
371 } | 381 } |
372 | 382 |
373 /** | 383 /** |
374 * Generates a generic icon to be used in the launcher. This is just a round
ed rectangle with | 384 * Generates a generic icon to be used in the launcher. This is just a round
ed rectangle with |
375 * a letter in the middle taken from the website's domain name. | 385 * a letter in the middle taken from the website's domain name. |
376 * | 386 * |
377 * @param context Context used to create the intent. | |
378 * @param url URL of the shortcut. | 387 * @param url URL of the shortcut. |
379 * @param red Red component of the dominant icon color. | 388 * @param red Red component of the dominant icon color. |
380 * @param green Green component of the dominant icon color. | 389 * @param green Green component of the dominant icon color. |
381 * @param blue Blue component of the dominant icon color. | 390 * @param blue Blue component of the dominant icon color. |
382 * @return Bitmap Either the touch-icon or the newly created favicon. | 391 * @return Bitmap Either the touch-icon or the newly created favicon. |
383 */ | 392 */ |
384 @CalledByNative | 393 @CalledByNative |
385 public static Bitmap generateHomeScreenIcon(Context context, String url, int
red, int green, | 394 public static Bitmap generateHomeScreenIcon(String url, int red, int green, |
386 int blue) { | 395 int blue) { |
| 396 Context context = ContextUtils.getApplicationContext(); |
387 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); | 397 ActivityManager am = (ActivityManager) context.getSystemService(Context.
ACTIVITY_SERVICE); |
388 final int outerSize = am.getLauncherLargeIconSize(); | 398 final int outerSize = am.getLauncherLargeIconSize(); |
389 final int iconDensity = am.getLauncherLargeIconDensity(); | 399 final int iconDensity = am.getLauncherLargeIconDensity(); |
390 | 400 |
391 Bitmap bitmap = null; | 401 Bitmap bitmap = null; |
392 try { | 402 try { |
393 bitmap = Bitmap.createBitmap(outerSize, outerSize, Bitmap.Config.ARG
B_8888); | 403 bitmap = Bitmap.createBitmap(outerSize, outerSize, Bitmap.Config.ARG
B_8888); |
394 } catch (OutOfMemoryError e) { | 404 } catch (OutOfMemoryError e) { |
395 Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas."
); | 405 Log.w(TAG, "OutOfMemoryError while trying to draw bitmap on canvas."
); |
396 return null; | 406 return null; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 builder.fragment(""); | 538 builder.fragment(""); |
529 builder.query(""); | 539 builder.query(""); |
530 return builder.build().toString(); | 540 return builder.build().toString(); |
531 } | 541 } |
532 | 542 |
533 /** | 543 /** |
534 * Returns an array of sizes which describe the ideal size and minimum size
of the Home screen | 544 * Returns an array of sizes which describe the ideal size and minimum size
of the Home screen |
535 * icon and the ideal and minimum sizes of the splash screen image in that o
rder. | 545 * icon and the ideal and minimum sizes of the splash screen image in that o
rder. |
536 */ | 546 */ |
537 @CalledByNative | 547 @CalledByNative |
538 private static int[] getHomeScreenIconAndSplashImageSizes(Context context) { | 548 private static int[] getHomeScreenIconAndSplashImageSizes() { |
| 549 Context context = ContextUtils.getApplicationContext(); |
539 // This ordering must be kept up to date with the C++ ShortcutHelper. | 550 // This ordering must be kept up to date with the C++ ShortcutHelper. |
540 return new int[] { | 551 return new int[] { |
541 getIdealHomescreenIconSizeInDp(context), | 552 getIdealHomescreenIconSizeInDp(context), |
542 getMinimumHomescreenIconSizeInDp(context), | 553 getMinimumHomescreenIconSizeInDp(context), |
543 getIdealSplashImageSizeInDp(context), | 554 getIdealSplashImageSizeInDp(context), |
544 getMinimumSplashImageSizeInDp(context) | 555 getMinimumSplashImageSizeInDp(context) |
545 }; | 556 }; |
546 } | 557 } |
547 | 558 |
548 private static int getIdealSizeFromResourceInDp(Context context, int resourc
e) { | 559 private static int getIdealSizeFromResourceInDp(Context context, int resourc
e) { |
549 float sizeInPx = context.getResources().getDimension(resource); | 560 float sizeInPx = context.getResources().getDimension(resource); |
550 float density = context.getResources().getDisplayMetrics().density; | 561 float density = context.getResources().getDisplayMetrics().density; |
551 return Math.round(sizeInPx / density); | 562 return Math.round(sizeInPx / density); |
552 } | 563 } |
553 | 564 |
554 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { | 565 private static Bitmap getBitmapFromResourceId(Context context, int id, int d
ensity) { |
555 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity( | 566 Drawable drawable = ApiCompatibilityUtils.getDrawableForDensity( |
556 context.getResources(), id, density); | 567 context.getResources(), id, density); |
557 | 568 |
558 if (drawable instanceof BitmapDrawable) { | 569 if (drawable instanceof BitmapDrawable) { |
559 BitmapDrawable bd = (BitmapDrawable) drawable; | 570 BitmapDrawable bd = (BitmapDrawable) drawable; |
560 return bd.getBitmap(); | 571 return bd.getBitmap(); |
561 } | 572 } |
562 assert false : "The drawable was not a bitmap drawable as expected"; | 573 assert false : "The drawable was not a bitmap drawable as expected"; |
563 return null; | 574 return null; |
564 } | 575 } |
565 | 576 |
566 private static native void nativeOnWebappDataStored(long callbackPointer); | 577 private static native void nativeOnWebappDataStored(long callbackPointer); |
567 } | 578 } |
OLD | NEW |