summaryrefslogtreecommitdiffstats
path: root/mobile/android/components/HelperAppDialog.js
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/components/HelperAppDialog.js')
-rw-r--r--mobile/android/components/HelperAppDialog.js373
1 files changed, 0 insertions, 373 deletions
diff --git a/mobile/android/components/HelperAppDialog.js b/mobile/android/components/HelperAppDialog.js
deleted file mode 100644
index f127fb0b3..000000000
--- a/mobile/android/components/HelperAppDialog.js
+++ /dev/null
@@ -1,373 +0,0 @@
-// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*globals ContentAreaUtils */
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-const APK_MIME_TYPE = "application/vnd.android.package-archive";
-
-const OMA_DOWNLOAD_DESCRIPTOR_MIME_TYPE = "application/vnd.oma.dd+xml";
-const OMA_DRM_MESSAGE_MIME = "application/vnd.oma.drm.message";
-const OMA_DRM_CONTENT_MIME = "application/vnd.oma.drm.content";
-const OMA_DRM_RIGHTS_MIME = "application/vnd.oma.drm.rights+wbxml";
-
-const PREF_BD_USEDOWNLOADDIR = "browser.download.useDownloadDir";
-const URI_GENERIC_ICON_DOWNLOAD = "drawable://alert_download";
-
-Cu.import("resource://gre/modules/Downloads.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/HelperApps.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/Task.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "RuntimePermissions", "resource://gre/modules/RuntimePermissions.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Messaging", "resource://gre/modules/Messaging.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Snackbars.jsm");
-
-// -----------------------------------------------------------------------
-// HelperApp Launcher Dialog
-// -----------------------------------------------------------------------
-
-XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
- let ContentAreaUtils = {};
- Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
- return ContentAreaUtils;
-});
-
-function HelperAppLauncherDialog() { }
-
-HelperAppLauncherDialog.prototype = {
- classID: Components.ID("{e9d277a0-268a-4ec2-bb8c-10fdf3e44611}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]),
-
- /**
- * Returns false if `url` represents a local or special URL that we don't
- * wish to ever download.
- *
- * Returns true otherwise.
- */
- _canDownload: function (url, alreadyResolved=false) {
- // The common case.
- if (url.schemeIs("http") ||
- url.schemeIs("https") ||
- url.schemeIs("ftp")) {
- return true;
- }
-
- // The less-common opposite case.
- if (url.schemeIs("chrome") ||
- url.schemeIs("jar") ||
- url.schemeIs("resource") ||
- url.schemeIs("wyciwyg") ||
- url.schemeIs("file")) {
- return false;
- }
-
- // For all other URIs, try to resolve them to an inner URI, and check that.
- if (!alreadyResolved) {
- let innerURI = NetUtil.newChannel({
- uri: url,
- loadUsingSystemPrincipal: true
- }).URI;
-
- if (!url.equals(innerURI)) {
- return this._canDownload(innerURI, true);
- }
- }
-
- // Anything else is fine to download.
- return true;
- },
-
- /**
- * Returns true if `launcher` represents a download for which we wish
- * to prompt.
- */
- _shouldPrompt: function (launcher) {
- let mimeType = this._getMimeTypeFromLauncher(launcher);
-
- // Straight equality: nsIMIMEInfo normalizes.
- return APK_MIME_TYPE == mimeType || OMA_DOWNLOAD_DESCRIPTOR_MIME_TYPE == mimeType;
- },
-
- /**
- * Returns true if `launcher` represents a download for which we wish to
- * offer a "Save to disk" option.
- */
- _shouldAddSaveToDiskIntent: function(launcher) {
- let mimeType = this._getMimeTypeFromLauncher(launcher);
-
- // We can't handle OMA downloads. So don't even try. (Bug 1219078)
- return mimeType != OMA_DOWNLOAD_DESCRIPTOR_MIME_TYPE;
- },
-
- /**
- * Returns true if `launcher`represents a download that should not be handled by Firefox
- * or a third-party app and instead be forwarded to Android's download manager.
- */
- _shouldForwardToAndroidDownloadManager: function(aLauncher) {
- let forwardDownload = Services.prefs.getBoolPref('browser.download.forward_oma_android_download_manager');
- if (!forwardDownload) {
- return false;
- }
-
- let mimeType = aLauncher.MIMEInfo.MIMEType;
- if (!mimeType) {
- mimeType = ContentAreaUtils.getMIMETypeForURI(aLauncher.source) || "";
- }
-
- return [
- OMA_DOWNLOAD_DESCRIPTOR_MIME_TYPE,
- OMA_DRM_MESSAGE_MIME,
- OMA_DRM_CONTENT_MIME,
- OMA_DRM_RIGHTS_MIME
- ].indexOf(mimeType) != -1;
- },
-
- show: function hald_show(aLauncher, aContext, aReason) {
- if (!this._canDownload(aLauncher.source)) {
- this._refuseDownload(aLauncher);
- return;
- }
-
- if (this._shouldForwardToAndroidDownloadManager(aLauncher)) {
- Task.spawn(function* () {
- try {
- let hasPermission = yield RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
- if (hasPermission) {
- this._downloadWithAndroidDownloadManager(aLauncher);
- aLauncher.cancel(Cr.NS_BINDING_ABORTED);
- }
- } finally {
- }
- }.bind(this)).catch(Cu.reportError);
- return;
- }
-
- let bundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
-
- let defaultHandler = new Object();
- let apps = HelperApps.getAppsForUri(aLauncher.source, {
- mimeType: aLauncher.MIMEInfo.MIMEType,
- });
-
- if (this._shouldAddSaveToDiskIntent(aLauncher)) {
- // Add a fake intent for save to disk at the top of the list.
- apps.unshift({
- name: bundle.GetStringFromName("helperapps.saveToDisk"),
- packageName: "org.mozilla.gecko.Download",
- iconUri: "drawable://icon",
- selected: true, // Default to download for files
- launch: function() {
- // Reset the preferredAction here.
- aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk;
- aLauncher.saveToDisk(null, false);
- return true;
- }
- });
- }
-
- // We do not handle this download and there are no apps that want to do it
- if (apps.length === 0) {
- this._refuseDownload(aLauncher);
- return;
- }
-
- let callback = function(app) {
- aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.useHelperApp;
- if (!app.launch(aLauncher.source)) {
- // Once the app is done we need to get rid of the temp file. This shouldn't
- // get run in the saveToDisk case.
- aLauncher.cancel(Cr.NS_BINDING_ABORTED);
- }
- }
-
- // See if the user already marked something as the default for this mimetype,
- // and if that app is still installed.
- let preferredApp = this._getPreferredApp(aLauncher);
- if (preferredApp) {
- let pref = apps.filter(function(app) {
- return app.packageName === preferredApp;
- });
-
- if (pref.length > 0) {
- callback(pref[0]);
- return;
- }
- }
-
- // If there's only one choice, and we don't want to prompt, go right ahead
- // and choose that app automatically.
- if (!this._shouldPrompt(aLauncher) && (apps.length === 1)) {
- callback(apps[0]);
- return;
- }
-
- // Otherwise, let's go through the prompt.
- HelperApps.prompt(apps, {
- title: bundle.GetStringFromName("helperapps.pick"),
- buttons: [
- bundle.GetStringFromName("helperapps.alwaysUse"),
- bundle.GetStringFromName("helperapps.useJustOnce")
- ],
- // Tapping an app twice should choose "Just once".
- doubleTapButton: 1
- }, (data) => {
- if (data.button < 0) {
- return;
- }
-
- callback(apps[data.icongrid0]);
-
- if (data.button === 0) {
- this._setPreferredApp(aLauncher, apps[data.icongrid0]);
- }
- });
- },
-
- _refuseDownload: function(aLauncher) {
- aLauncher.cancel(Cr.NS_BINDING_ABORTED);
-
- Services.console.logStringMessage("Refusing download of non-downloadable file.");
-
- let bundle = Services.strings.createBundle("chrome://browser/locale/handling.properties");
- let failedText = bundle.GetStringFromName("download.blocked");
-
- Snackbars.show(failedText, Snackbars.LENGTH_LONG);
- },
-
- _downloadWithAndroidDownloadManager(aLauncher) {
- let mimeType = aLauncher.MIMEInfo.MIMEType;
- if (!mimeType) {
- mimeType = ContentAreaUtils.getMIMETypeForURI(aLauncher.source) || "";
- }
-
- Messaging.sendRequest({
- 'type': 'Download:AndroidDownloadManager',
- 'uri': aLauncher.source.spec,
- 'mimeType': mimeType,
- 'filename': aLauncher.suggestedFileName
- });
- },
-
- _getPrefName: function getPrefName(mimetype) {
- return "browser.download.preferred." + mimetype.replace("\\", ".");
- },
-
- _getMimeTypeFromLauncher: function (launcher) {
- let mime = launcher.MIMEInfo.MIMEType;
- if (!mime)
- mime = ContentAreaUtils.getMIMETypeForURI(launcher.source) || "";
- return mime;
- },
-
- _getPreferredApp: function getPreferredApp(launcher) {
- let mime = this._getMimeTypeFromLauncher(launcher);
- if (!mime)
- return;
-
- try {
- return Services.prefs.getCharPref(this._getPrefName(mime));
- } catch(ex) {
- Services.console.logStringMessage("Error getting pref for " + mime + ".");
- }
- return null;
- },
-
- _setPreferredApp: function setPreferredApp(launcher, app) {
- let mime = this._getMimeTypeFromLauncher(launcher);
- if (!mime)
- return;
-
- if (app)
- Services.prefs.setCharPref(this._getPrefName(mime), app.packageName);
- else
- Services.prefs.clearUserPref(this._getPrefName(mime));
- },
-
- promptForSaveToFileAsync: function (aLauncher, aContext, aDefaultFile,
- aSuggestedFileExt, aForcePrompt) {
- Task.spawn(function* () {
- let file = null;
- try {
- let hasPermission = yield RuntimePermissions.waitForPermissions(RuntimePermissions.WRITE_EXTERNAL_STORAGE);
- if (hasPermission) {
- // If we do have the STORAGE permission then pick the public downloads directory as destination
- // for this file. Without the permission saveDestinationAvailable(null) will be called which
- // will effectively cancel the download.
- let preferredDir = yield Downloads.getPreferredDownloadsDirectory();
- file = this.validateLeafName(new FileUtils.File(preferredDir),
- aDefaultFile, aSuggestedFileExt);
- }
- } finally {
- // The file argument will be null in case any exception occurred.
- aLauncher.saveDestinationAvailable(file);
- }
- }.bind(this)).catch(Cu.reportError);
- },
-
- validateLeafName: function hald_validateLeafName(aLocalFile, aLeafName, aFileExt) {
- if (!(aLocalFile && this.isUsableDirectory(aLocalFile)))
- return null;
-
- // Remove any leading periods, since we don't want to save hidden files
- // automatically.
- aLeafName = aLeafName.replace(/^\.+/, "");
-
- if (aLeafName == "")
- aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
- aLocalFile.append(aLeafName);
-
- this.makeFileUnique(aLocalFile);
- return aLocalFile;
- },
-
- makeFileUnique: function hald_makeFileUnique(aLocalFile) {
- try {
- // Note - this code is identical to that in
- // toolkit/content/contentAreaUtils.js.
- // If you are updating this code, update that code too! We can't share code
- // here since this is called in a js component.
- let collisionCount = 0;
- while (aLocalFile.exists()) {
- collisionCount++;
- if (collisionCount == 1) {
- // Append "(2)" before the last dot in (or at the end of) the filename
- // special case .ext.gz etc files so we don't wind up with .tar(2).gz
- if (aLocalFile.leafName.match(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i))
- aLocalFile.leafName = aLocalFile.leafName.replace(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i, "(2)$&");
- else
- aLocalFile.leafName = aLocalFile.leafName.replace(/(\.[^\.]*)?$/, "(2)$&");
- }
- else {
- // replace the last (n) in the filename with (n+1)
- aLocalFile.leafName = aLocalFile.leafName.replace(/^(.*\()\d+\)/, "$1" + (collisionCount+1) + ")");
- }
- }
- aLocalFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
- }
- catch (e) {
- dump("*** exception in validateLeafName: " + e + "\n");
-
- if (e.result == Cr.NS_ERROR_FILE_ACCESS_DENIED)
- throw e;
-
- if (aLocalFile.leafName == "" || aLocalFile.isDirectory()) {
- aLocalFile.append("unnamed");
- if (aLocalFile.exists())
- aLocalFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
- }
- }
- },
-
- isUsableDirectory: function hald_isUsableDirectory(aDirectory) {
- return aDirectory.exists() && aDirectory.isDirectory() && aDirectory.isWritable();
- },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HelperAppLauncherDialog]);