diff --git a/mobile/android/base/GeckoApp.java b/mobile/android/base/GeckoApp.java index 59613c86020..f6b76a2e3b8 100644 --- a/mobile/android/base/GeckoApp.java +++ b/mobile/android/base/GeckoApp.java @@ -931,23 +931,23 @@ abstract public class GeckoApp final String type = message.getString("shortcutType"); GeckoAppShell.removeShortcut(title, url, origin, type); } else if (event.equals("WebApps:Open")) { - String url = message.getString("uri"); + String manifestURL = message.getString("manifestURL"); String origin = message.getString("origin"); - Intent intent = GeckoAppShell.getWebAppIntent(url, origin, "", null); + Intent intent = GeckoAppShell.getWebAppIntent(manifestURL, origin, "", null); if (intent == null) return; startActivity(intent); } else if (event.equals("WebApps:Install")) { String name = message.getString("name"); - String launchPath = message.getString("launchPath"); + String manifestURL = message.getString("manifestURL"); String iconURL = message.getString("iconURL"); - String uniqueURI = message.getString("uniqueURI"); + String origin = message.getString("origin"); // installWebapp will return a File object pointing to the profile directory of the webapp - mCurrentResponse = GeckoAppShell.installWebApp(name, launchPath, uniqueURI, iconURL).toString(); + mCurrentResponse = GeckoAppShell.installWebApp(name, manifestURL, origin, iconURL).toString(); } else if (event.equals("WebApps:Uninstall")) { - String uniqueURI = message.getString("uniqueURI"); - GeckoAppShell.uninstallWebApp(uniqueURI); + String origin = message.getString("origin"); + GeckoAppShell.uninstallWebApp(origin); } else if (event.equals("DesktopMode:Changed")) { int tabId = message.getInt("tabId"); boolean desktopMode = message.getBoolean("desktopMode"); diff --git a/mobile/android/base/WebApp.java.in b/mobile/android/base/WebApp.java.in index 9abfceb569e..94eed5aa082 100644 --- a/mobile/android/base/WebApp.java.in +++ b/mobile/android/base/WebApp.java.in @@ -88,12 +88,6 @@ public class WebApp extends GeckoApp { } } - @Override - protected void initializeChrome(String uri, boolean isExternalURL) { - super.initializeChrome(uri, isExternalURL); - Tabs.getInstance().loadUrl(uri, Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_USER_ENTERED | Tabs.LOADURL_PINNED); - } - private void showSplash() { mSplashscreen = (RelativeLayout) findViewById(R.id.splashscreen); diff --git a/mobile/android/chrome/content/WebAppRT.js b/mobile/android/chrome/content/WebAppRT.js index 1197523a4cc..b3f42ede962 100644 --- a/mobile/android/chrome/content/WebAppRT.js +++ b/mobile/android/chrome/content/WebAppRT.js @@ -8,6 +8,7 @@ let Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/FileUtils.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/commonjs/promise/core.js"); function pref(name, value) { return { @@ -16,7 +17,7 @@ function pref(name, value) { } } -var WebAppRT = { +let WebAppRT = { DEFAULT_PREFS_FILENAME: "default-prefs.js", prefs: [ @@ -52,6 +53,56 @@ var WebAppRT = { blocklist = blocklist.replace(/%APP_ID%/g, "webapprt-mobile@mozilla.org"); Services.prefs.setCharPref("extensions.blocklist.url", blocklist); } + + return this.findManifestUrlFor(url); + }, + + findManifestUrlFor: function(aUrl) { + let deferred = Promise.defer(); + let request = navigator.mozApps.mgmt.getAll(); + request.onsuccess = function() { + let apps = request.result; + for (let i = 0; i < apps.length; i++) { + let app = apps[i]; + let manifest = new ManifestHelper(app.manifest, app.origin); + + // First see if this url matches any manifests we have registered + // If so, get the launchUrl from the manifest and we'll launch with that + //let app = DOMApplicationRegistry.getAppByManifestURL(aUrl); + if (app.manifestURL == aUrl) { + BrowserApp.manifestUrl = aUrl; + deferred.resolve(manifest.fullLaunchPath()); + return; + } + + // Otherwise, see if the apps launch path is this url + if (manifest.fullLaunchPath() == aUrl) { + // remove the old shortuct + sendMessageToJava({ + gecko: { + type: "Shortcut:Remove", + title: manifest.name, + url: manifest.fullLaunchPath(), + origin: app.origin, + shortcutType: "webapp" + } + }); + WebappsUI.createShortcut(manifest.name, manifest.fullLaunchPath(), + WebappsUI.getBiggestIcon(manifest.icons, app.origin), "webapp"); + + BrowserApp.manifestUrl = app.manifestURL; + deferred.resolve(aUrl); + return; + } + } + deferred.reject(""); + }; + + request.onerror = function() { + deferred.reject(""); + }; + + return deferred.promise; }, getDefaultPrefs: function() { diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index ba48bcf0aab..8385a178ed0 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -276,7 +276,15 @@ var BrowserApp = { let updated = this.isAppUpdated(); if (pinned) { - WebAppRT.init(updated, url); + WebAppRT.init(updated, url).then(function(aUrl) { + BrowserApp.addTab(aUrl); + }, function() { + let uri = Services.io.newURI(url, null, null); + if (!uri) + return; + Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService).getProtocolHandlerInfo(uri.scheme).launchWithURI(uri); + BrowserApp.quit(); + }); } else { SearchEngines.init(); this.initContextMenu(); @@ -2747,6 +2755,15 @@ Tab.prototype = { BrowserApp.deck.insertBefore(this.browser, aParams.sibling || null); BrowserApp.deck.selectedPanel = selectedPanel; + if (BrowserApp.manifestUrl) { + let appsService = Cc["@mozilla.org/AppsService;1"].getService(Ci.nsIAppsService); + let manifest = appsService.getAppByManifestURL(BrowserApp.manifestUrl); + if (manifest) { + let app = manifest.QueryInterface(Ci.mozIApplication); + this.browser.docShell.setIsApp(app.localId); + } + } + // Must be called after appendChild so the docshell has been created. this.setActive(false); @@ -7002,7 +7019,6 @@ var WebappsUI = { Services.obs.addObserver(this, "webapps-sync-install", false); Services.obs.addObserver(this, "webapps-sync-uninstall", false); Services.obs.addObserver(this, "webapps-install-error", false); - Services.obs.addObserver(this, "WebApps:InstallMarketplace", false); }, uninit: function unint() { @@ -7011,7 +7027,6 @@ var WebappsUI = { Services.obs.removeObserver(this, "webapps-sync-install"); Services.obs.removeObserver(this, "webapps-sync-uninstall"); Services.obs.removeObserver(this, "webapps-install-error", false); - Services.obs.removeObserver(this, "WebApps:InstallMarketplace", false); }, DEFAULT_PREFS_FILENAME: "default-prefs.js", @@ -7044,12 +7059,7 @@ var WebappsUI = { this.doInstall(data); break; case "webapps-launch": - DOMApplicationRegistry.getManifestFor(data.origin, (function(aManifest) { - if (!aManifest) - return; - let manifest = new ManifestHelper(aManifest, data.origin); - this.openURL(manifest.fullLaunchPath(), data.origin); - }).bind(this)); + this.openURL(data.manifestURL, data.origin); break; case "webapps-sync-install": // Create a system notification allowing the user to launch the app @@ -7061,7 +7071,7 @@ var WebappsUI = { let observer = { observe: function (aSubject, aTopic) { if (aTopic == "alertclickcallback") { - WebappsUI.openURL(manifest.fullLaunchPath(), data.origin); + WebappsUI.openURL(data.manifestURL, data.origin); } } }; @@ -7075,64 +7085,10 @@ var WebappsUI = { sendMessageToJava({ gecko: { type: "WebApps:Uninstall", - uniqueURI: data.origin + origin: data.origin } }); break; - case "WebApps:InstallMarketplace": - this.installAndLaunchMarketplace(data.url); - break; - } - }, - - MARKETPLACE: { - MANIFEST: "https://marketplace.mozilla.org/manifest.webapp", - get URI() { - delete this.URI; - return this.URI = Services.io.newURI(this.MANIFEST, null, null); - } - }, - - isMarketplace: function isMarketplace(aUri) { - try { - return !aUri.schemeIs("about") && aUri.host == this.MARKETPLACE.URI.host; - } catch(ex) { - console.log("could not find host for " + aUri.spec + ", " + ex); - } - return false; - }, - - // installs the marketplace, if a url is passed in, will launch it when the install - // is complete - installAndLaunchMarketplace: function installAndLaunchMarketplace(aLaunchUrl) { - // TODO: Add a flag to hide other install prompt dialogs. This should be silent if possible - let request = navigator.mozApps.getInstalled(); - request.onsuccess = function() { - let foundMarket = false; - for (let i = 0; i < request.result.length; i++) { - if (request.result[i].origin == WebappsUI.MARKETPLACE.URI.prePath) - foundMarket = true; - } - - let launchFun = (function() { - if (aLaunchUrl) - WebappsUI.openURL(aLaunchUrl || WebappsUI.MARKETPLACE.URI.prePath, WebappsUI.MARKETPLACE.URI.prePath); - }).bind(this); - - if (foundMarket) { - launchFun(); - } else { - let r = navigator.mozApps.install(WebappsUI.MARKETPLACE.MANIFEST); - r.onsuccess = function() { - launchFun(); - }; - r.onerror = function() { - console.log("error installing market " + this.error.name); - }; - } - }; - request.onerror = function() { - console.log("error getting installed " + this.error.name); } }, @@ -7183,9 +7139,9 @@ var WebappsUI = { gecko: { type: "WebApps:Install", name: manifest.name, - launchPath: manifest.fullLaunchPath(), + manifestURL: aData.app.manifestURL, + origin: aData.app.origin, iconURL: scaledIcon, - uniqueURI: aData.app.origin } }); @@ -7244,11 +7200,11 @@ var WebappsUI = { } }, - openURL: function openURL(aURI, aOrigin) { + openURL: function openURL(aManifestURL, aOrigin) { sendMessageToJava({ gecko: { type: "WebApps:Open", - uri: aURI, + manifestURL: aManifestURL, origin: aOrigin } });