| Index: chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
|
| index 4547fd18dea153f56e3aebf78b67a921a806e089..813fcac3b1a0f6ad1b4b9090dfb8b1077b8ea7dd 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
|
| @@ -30,6 +30,7 @@ import android.util.Base64;
|
| import org.chromium.base.ApiCompatibilityUtils;
|
| import org.chromium.base.ApplicationStatus;
|
| import org.chromium.base.Log;
|
| +import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.VisibleForTesting;
|
| import org.chromium.base.annotations.CalledByNative;
|
| import org.chromium.chrome.R;
|
| @@ -58,6 +59,7 @@ public class ShortcutHelper {
|
| public static final String EXTRA_NAME = "org.chromium.chrome.browser.webapp_name";
|
| public static final String EXTRA_SHORT_NAME = "org.chromium.chrome.browser.webapp_short_name";
|
| public static final String EXTRA_URL = "org.chromium.chrome.browser.webapp_url";
|
| + public static final String EXTRA_SCOPE = "org.chromium.chrome.browser.webapp_scope";
|
| public static final String EXTRA_ORIENTATION = ScreenOrientationConstants.EXTRA_ORIENTATION;
|
| public static final String EXTRA_SOURCE = "org.chromium.chrome.browser.webapp_source";
|
| public static final String EXTRA_THEME_COLOR = "org.chromium.chrome.browser.theme_color";
|
| @@ -65,9 +67,15 @@ public class ShortcutHelper {
|
| "org.chromium.chrome.browser.background_color";
|
| public static final String EXTRA_IS_ICON_GENERATED =
|
| "org.chromium.chrome.browser.is_icon_generated";
|
| + public static final String EXTRA_VERSION =
|
| + "org.chromium.chrome.browser.webapp_shortcut_version";
|
| public static final String REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB =
|
| "REUSE_URL_MATCHING_TAB_ELSE_NEW_TAB";
|
|
|
| + // When a new field is added to the intent, this version should be incremented so that it will
|
| + // be correctly populated into the WebappRegistry/WebappDataStorage.
|
| + public static final int WEBAPP_SHORTCUT_VERSION = 1;
|
| +
|
| // This value is equal to kInvalidOrMissingColor in the C++ content::Manifest struct.
|
| public static final long MANIFEST_COLOR_INVALID_OR_MISSING = ((long) Integer.MAX_VALUE) + 1;
|
|
|
| @@ -119,30 +127,22 @@ public class ShortcutHelper {
|
| * If the webpage indicated that it was capable of functioning as a webapp, it is added as a
|
| * shortcut to a webapp Activity rather than as a general bookmark. User is sent to the
|
| * home screen as soon as the shortcut is created.
|
| + *
|
| + * This method must not be called on the UI thread.
|
| */
|
| @SuppressWarnings("unused")
|
| @CalledByNative
|
| private static void addShortcut(Context context, String id, String url, final String userTitle,
|
| String name, String shortName, Bitmap icon, boolean isWebappCapable, int orientation,
|
| - int source, long themeColor, long backgroundColor, boolean isIconGenerated) {
|
| - Intent shortcutIntent;
|
| + int source, long themeColor, long backgroundColor, boolean isIconGenerated,
|
| + final long callbackPointer) {
|
| + assert !ThreadUtils.runningOnUiThread();
|
| + final Intent shortcutIntent;
|
| if (isWebappCapable) {
|
| - // Encode the icon as a base64 string (Launcher drops Bitmaps in the Intent).
|
| - String encodedIcon = encodeBitmapAsString(icon);
|
| -
|
| - // Add the shortcut as a launcher icon for a full-screen Activity.
|
| - shortcutIntent = new Intent();
|
| - shortcutIntent.setAction(sDelegate.getFullscreenAction())
|
| - .putExtra(EXTRA_ICON, encodedIcon)
|
| - .putExtra(EXTRA_ID, id)
|
| - .putExtra(EXTRA_NAME, name)
|
| - .putExtra(EXTRA_SHORT_NAME, shortName)
|
| - .putExtra(EXTRA_URL, url)
|
| - .putExtra(EXTRA_ORIENTATION, orientation)
|
| - .putExtra(EXTRA_MAC, getEncodedMac(context, url))
|
| - .putExtra(EXTRA_THEME_COLOR, themeColor)
|
| - .putExtra(EXTRA_BACKGROUND_COLOR, backgroundColor)
|
| - .putExtra(EXTRA_IS_ICON_GENERATED, isIconGenerated);
|
| + shortcutIntent = createWebappShortcutIntent(id, sDelegate.getFullscreenAction(), url,
|
| + getScopeFromUrl(url), name, shortName, icon, WEBAPP_SHORTCUT_VERSION,
|
| + orientation, themeColor, backgroundColor, isIconGenerated);
|
| + shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url));
|
| } else {
|
| // Add the shortcut as a launcher icon to open in the browser Activity.
|
| shortcutIntent = createShortcutIntent(url);
|
| @@ -155,6 +155,20 @@ public class ShortcutHelper {
|
| sDelegate.sendBroadcast(
|
| context, createAddToHomeIntent(url, userTitle, icon, shortcutIntent));
|
|
|
| + if (isWebappCapable) {
|
| + // Store the webapp data so that it is accessible without the intent. Once this process
|
| + // is complete, call back to native code to start the splash image download.
|
| + WebappRegistry.registerWebapp(context, id,
|
| + new WebappRegistry.FetchWebappDataStorageCallback() {
|
| + @Override
|
| + public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
|
| + storage.updateFromShortcutIntent(shortcutIntent);
|
| + nativeOnWebappDataStored(callbackPointer);
|
| + }
|
| + }
|
| + );
|
| + }
|
| +
|
| // Alert the user about adding the shortcut.
|
| Handler handler = new Handler(Looper.getMainLooper());
|
| handler.post(new Runnable() {
|
| @@ -173,16 +187,24 @@ public class ShortcutHelper {
|
| * Creates a storage location and stores the data for a web app using {@link WebappDataStorage}.
|
| * @param context Context to open the WebappDataStorage with.
|
| * @param id ID of the webapp which is storing data.
|
| - * @param scope scope of the webapp which is storing data.
|
| * @param splashImage Image which should be displayed on the splash screen of
|
| * the webapp. This can be null of there is no image to show.
|
| */
|
| @SuppressWarnings("unused")
|
| @CalledByNative
|
| - private static void storeWebappData(Context context, String id, String scope,
|
| - Bitmap splashImage) {
|
| - WebappRegistry.registerWebapp(context, id, scope);
|
| - WebappDataStorage.open(context, id).updateSplashScreenImage(splashImage);
|
| + private static void storeWebappSplashImage(final Context context, final String id,
|
| + final Bitmap splashImage) {
|
| + WebappRegistry.getWebappDataStorage(context, id,
|
| + new WebappRegistry.FetchWebappDataStorageCallback() {
|
| + @Override
|
| + public void onWebappDataStorageRetrieved(WebappDataStorage storage) {
|
| + if (storage == null) return;
|
| +
|
| + storage.updateSplashScreenImage(splashImage);
|
| + }
|
| +
|
| + }
|
| + );
|
| }
|
|
|
| /**
|
| @@ -215,6 +237,45 @@ public class ShortcutHelper {
|
| }
|
|
|
| /**
|
| + * Creates a shortcut to launch a web app on the home screen.
|
| + * @param id Id of the web app.
|
| + * @param action Intent action to open a full screen activity.
|
| + * @param url Url of the web app.
|
| + * @param scope Url scope of the web app.
|
| + * @param name Name of the web app.
|
| + * @param shortName Short name of the web app.
|
| + * @param icon Icon of the web app.
|
| + * @param version Version number of the shortcut.
|
| + * @param orientation Orientation of the web app.
|
| + * @param themeColor Theme color of the web app.
|
| + * @param backgroundColor Background color of the web app.
|
| + * @param isIconGenerated True if the icon is generated by Chromium.
|
| + * @return Intent for onclick action of the shortcut.
|
| + */
|
| + public static Intent createWebappShortcutIntent(String id, String action, String url,
|
| + String scope, String name, String shortName, Bitmap icon, int version, int orientation,
|
| + long themeColor, long backgroundColor, boolean isIconGenerated) {
|
| + // Encode the icon as a base64 string (Launcher drops Bitmaps in the Intent).
|
| + String encodedIcon = encodeBitmapAsString(icon);
|
| +
|
| + // Create an intent as a launcher icon for a full-screen Activity.
|
| + Intent shortcutIntent = new Intent();
|
| + shortcutIntent.setAction(action)
|
| + .putExtra(EXTRA_ID, id)
|
| + .putExtra(EXTRA_URL, url)
|
| + .putExtra(EXTRA_SCOPE, scope)
|
| + .putExtra(EXTRA_NAME, name)
|
| + .putExtra(EXTRA_SHORT_NAME, shortName)
|
| + .putExtra(EXTRA_ICON, encodedIcon)
|
| + .putExtra(EXTRA_VERSION, version)
|
| + .putExtra(EXTRA_ORIENTATION, orientation)
|
| + .putExtra(EXTRA_THEME_COLOR, themeColor)
|
| + .putExtra(EXTRA_BACKGROUND_COLOR, backgroundColor)
|
| + .putExtra(EXTRA_IS_ICON_GENERATED, isIconGenerated);
|
| + return shortcutIntent;
|
| + }
|
| +
|
| + /**
|
| * Shortcut intent for icon on home screen.
|
| * @param url Url of the shortcut.
|
| * @return Intent for onclick action of the shortcut.
|
| @@ -430,6 +491,37 @@ public class ShortcutHelper {
|
| }
|
|
|
| /**
|
| + * Returns the URL with all but the last component of its path removed. This serves as a proxy
|
| + * for scope until the scope manifest member is available. This method assumes that the URL
|
| + * passed in is a valid URL with a path that contains at least one "/".
|
| + * @param url The url to convert to a scope.
|
| + * @return The scope.
|
| + */
|
| + public static String getScopeFromUrl(String url) {
|
| + Uri uri = Uri.parse(url);
|
| + List<String> path = uri.getPathSegments();
|
| + int endIndex = path.size();
|
| +
|
| + // If there is at least one path element, remove the last one.
|
| + if (endIndex > 0) {
|
| + endIndex -= 1;
|
| + }
|
| +
|
| + // Make sure the path starts and ends with a slash (or is only a slash if there is no path).
|
| + Uri.Builder builder = uri.buildUpon();
|
| + String scope_path = "/" + TextUtils.join("/", path.subList(0, endIndex));
|
| + if (scope_path.length() > 1) {
|
| + scope_path += "/";
|
| + }
|
| + builder.path(scope_path);
|
| +
|
| + // Clear out the query and fragment.
|
| + builder.fragment("");
|
| + builder.query("");
|
| + return builder.build().toString();
|
| + }
|
| +
|
| + /**
|
| * Returns an array of sizes which describe the ideal size and minimum size of the Home screen
|
| * icon and the ideal and minimum sizes of the splash screen image in that order.
|
| */
|
| @@ -461,4 +553,6 @@ public class ShortcutHelper {
|
| assert false : "The drawable was not a bitmap drawable as expected";
|
| return null;
|
| }
|
| +
|
| + private static native void nativeOnWebappDataStored(long callbackPointer);
|
| }
|
|
|