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); |
} |