Index: chrome/android/java/src/org/chromium/chrome/browser/ChromeServiceTabLauncher.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeServiceTabLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeServiceTabLauncher.java |
index 0231b296db4fd290d25ce0f6a6049c09544757db..35d77ec8344a3cb2e44bb5406369659789cf84e0 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeServiceTabLauncher.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeServiceTabLauncher.java |
@@ -5,12 +5,17 @@ |
package org.chromium.chrome.browser; |
import android.content.Context; |
+import android.content.Intent; |
+import android.os.AsyncTask; |
import org.chromium.chrome.browser.document.DocumentMetricIds; |
import org.chromium.chrome.browser.tab.Tab; |
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
import org.chromium.chrome.browser.tabmodel.document.AsyncTabCreationParams; |
import org.chromium.chrome.browser.tabmodel.document.TabDelegate; |
+import org.chromium.chrome.browser.webapps.WebappDataStorage; |
+import org.chromium.chrome.browser.webapps.WebappRegistry; |
+import org.chromium.chrome.browser.webapps.WebappRegistry.FetchWebappDataStorageCallback; |
import org.chromium.components.service_tab_launcher.ServiceTabLauncher; |
import org.chromium.content_public.browser.LoadUrlParams; |
import org.chromium.content_public.common.Referrer; |
@@ -18,34 +23,74 @@ import org.chromium.ui.base.PageTransition; |
/** |
* Service Tab Launcher implementation for Chrome. Provides the ability for Android Services |
- * running in Chrome to launch tabs, without having access to an activity. |
+ * running in Chrome to launch URLs, without having access to an activity. |
* |
* This class is referred to from the ServiceTabLauncher implementation in Chromium using a |
* meta-data value in the Android manifest file. The ServiceTabLauncher class has more |
* documentation about why this is necessary. |
* |
+ * URLs within the scope of a recently launched standalone-capable web app on the Android home |
+ * screen are launched in the standalone web app frame. |
+ * |
* TODO(peter): after upstreaming, merge this with ServiceTabLauncher and remove reflection calls |
* in ServiceTabLauncher. |
*/ |
public class ChromeServiceTabLauncher extends ServiceTabLauncher { |
@Override |
- public void launchTab(Context context, int requestId, boolean incognito, String url, |
- int disposition, String referrerUrl, int referrerPolicy, |
- String extraHeaders, byte[] postData) { |
- // TODO(peter): Determine the intent source based on the |disposition| with which the |
- // tab is being launched. Right now this is gated by a check in the native implementation. |
- int intentSource = DocumentMetricIds.STARTED_BY_WINDOW_OPEN; |
- |
- LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.LINK); |
- loadUrlParams.setPostData(postData); |
- loadUrlParams.setVerbatimHeaders(extraHeaders); |
- loadUrlParams.setReferrer(new Referrer(referrerUrl, referrerPolicy)); |
- |
- AsyncTabCreationParams asyncParams = new AsyncTabCreationParams(loadUrlParams, requestId); |
- asyncParams.setDocumentStartedBy(intentSource); |
- |
- TabDelegate tabDelegate = new TabDelegate(incognito); |
- tabDelegate.createNewTab( |
- asyncParams, TabLaunchType.FROM_CHROME_UI, Tab.INVALID_TAB_ID); |
+ public void launchTab(final Context context, final int requestId, final boolean incognito, |
+ final String url, final int disposition, final String referrerUrl, |
+ final int referrerPolicy, final String extraHeaders, final byte[] postData) { |
+ final TabDelegate tabDelegate = new TabDelegate(incognito); |
+ |
+ // Try and retrieve a WebappDataStorage object with scope corresponding to the URL to be |
+ // opened. If one is found, and it has been opened recently, create an intent to launch the |
+ // URL in a standalone web app frame. Otherwise, open the URL in a tab. |
+ FetchWebappDataStorageCallback callback = new FetchWebappDataStorageCallback() { |
+ @Override |
+ public void onWebappDataStorageRetrieved(final WebappDataStorage storage) { |
+ // If we do not find a WebappDataStorage corresponding to this URL, or if it hasn't |
+ // been opened recently enough, open the URL in a tab. |
+ if (storage == null || !storage.wasLaunchedRecently()) { |
+ // TODO(peter): Determine the intent source based on the |disposition| with |
+ // which the tab is being launched. Right now this is gated by a check in the |
+ // native implementation. |
+ int intentSource = DocumentMetricIds.STARTED_BY_WINDOW_OPEN; |
+ |
+ LoadUrlParams loadUrlParams = new LoadUrlParams(url, PageTransition.LINK); |
+ loadUrlParams.setPostData(postData); |
+ loadUrlParams.setVerbatimHeaders(extraHeaders); |
+ loadUrlParams.setReferrer(new Referrer(referrerUrl, referrerPolicy)); |
+ |
+ AsyncTabCreationParams asyncParams = new AsyncTabCreationParams(loadUrlParams, |
+ requestId); |
+ asyncParams.setDocumentStartedBy(intentSource); |
+ |
+ tabDelegate.createNewTab(asyncParams, TabLaunchType.FROM_CHROME_UI, |
+ Tab.INVALID_TAB_ID); |
+ } else { |
+ // The URL is within the scope of a recently launched standalone-capable web app |
+ // on the home screen, so open it a standalone web app frame. An AsyncTask is |
+ // used because WebappDataStorage.createWebappLaunchIntent contains a Bitmap |
+ // decode operation and should not be run on the UI thread. |
+ // |
+ // This currently assumes that the only source is notifications; any future use |
+ // which adds a different source will need to change this. |
+ new AsyncTask<Void, Void, Intent>() { |
+ @Override |
+ protected final Intent doInBackground(Void... nothing) { |
+ return storage.createWebappLaunchIntent(); |
+ } |
+ |
+ @Override |
+ protected final void onPostExecute(Intent intent) { |
+ intent.putExtra(ShortcutHelper.EXTRA_SOURCE, |
+ ShortcutSource.NOTIFICATION); |
+ tabDelegate.createNewStandaloneFrame(intent); |
+ } |
+ }.execute(); |
+ } |
+ } |
+ }; |
+ WebappRegistry.getWebappDataStorageForUrl(context, url, callback); |
} |
} |