diff options
Diffstat (limited to 'b2g/components')
81 files changed, 0 insertions, 10537 deletions
diff --git a/b2g/components/AboutServiceWorkers.jsm b/b2g/components/AboutServiceWorkers.jsm deleted file mode 100644 index fe67e9c34..000000000 --- a/b2g/components/AboutServiceWorkers.jsm +++ /dev/null @@ -1,183 +0,0 @@ -/* 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/. */ - -"use strict" - -this.EXPORTED_SYMBOLS = ["AboutServiceWorkers"]; - -const { interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager", - "@mozilla.org/serviceworkers/manager;1", - "nsIServiceWorkerManager"); - -function debug(aMsg) { - dump("AboutServiceWorkers - " + aMsg + "\n"); -} - -function serializeServiceWorkerInfo(aServiceWorkerInfo) { - if (!aServiceWorkerInfo) { - throw new Error("Invalid service worker information"); - } - - let result = {}; - - result.principal = { - origin: aServiceWorkerInfo.principal.originNoSuffix, - originAttributes: aServiceWorkerInfo.principal.originAttributes - }; - - ["scope", "scriptSpec"].forEach(property => { - result[property] = aServiceWorkerInfo[property]; - }); - - return result; -} - - -this.AboutServiceWorkers = { - get enabled() { - if (this._enabled) { - return this._enabled; - } - this._enabled = false; - try { - this._enabled = Services.prefs.getBoolPref("dom.serviceWorkers.enabled"); - } catch(e) {} - return this._enabled; - }, - - init: function() { - SystemAppProxy.addEventListener("mozAboutServiceWorkersContentEvent", - AboutServiceWorkers); - }, - - sendResult: function(aId, aResult) { - SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", { - id: aId, - result: aResult - }); - }, - - sendError: function(aId, aError) { - SystemAppProxy._sendCustomEvent("mozAboutServiceWorkersChromeEvent", { - id: aId, - error: aError - }); - }, - - handleEvent: function(aEvent) { - let message = aEvent.detail; - - debug("Got content event " + JSON.stringify(message)); - - if (!message.id || !message.name) { - dump("Invalid event " + JSON.stringify(message) + "\n"); - return; - } - - let self = AboutServiceWorkers; - - switch(message.name) { - case "init": - if (!self.enabled) { - self.sendResult(message.id, { - enabled: false, - registrations: [] - }); - return; - }; - - let data = gServiceWorkerManager.getAllRegistrations(); - if (!data) { - self.sendError(message.id, "NoServiceWorkersRegistrations"); - return; - } - - let registrations = []; - - for (let i = 0; i < data.length; i++) { - let info = data.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo); - if (!info) { - dump("AboutServiceWorkers: Invalid nsIServiceWorkerRegistrationInfo " + - "interface.\n"); - continue; - } - registrations.push(serializeServiceWorkerInfo(info)); - } - - self.sendResult(message.id, { - enabled: self.enabled, - registrations: registrations - }); - break; - - case "update": - if (!message.scope) { - self.sendError(message.id, "MissingScope"); - return; - } - - if (!message.principal || - !message.principal.originAttributes) { - self.sendError(message.id, "MissingOriginAttributes"); - return; - } - - gServiceWorkerManager.propagateSoftUpdate( - message.principal.originAttributes, - message.scope - ); - - self.sendResult(message.id, true); - break; - - case "unregister": - if (!message.principal || - !message.principal.origin || - !message.principal.originAttributes || - !message.principal.originAttributes.appId || - (message.principal.originAttributes.inIsolatedMozBrowser == null)) { - self.sendError(message.id, "MissingPrincipal"); - return; - } - - let principal = Services.scriptSecurityManager.createCodebasePrincipal( - // TODO: Bug 1196652. use originNoSuffix - Services.io.newURI(message.principal.origin, null, null), - message.principal.originAttributes); - - if (!message.scope) { - self.sendError(message.id, "MissingScope"); - return; - } - - let serviceWorkerUnregisterCallback = { - unregisterSucceeded: function() { - self.sendResult(message.id, true); - }, - - unregisterFailed: function() { - self.sendError(message.id, "UnregisterError"); - }, - - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIServiceWorkerUnregisterCallback - ]) - }; - gServiceWorkerManager.propagateUnregister(principal, - serviceWorkerUnregisterCallback, - message.scope); - break; - } - } -}; - -AboutServiceWorkers.init(); diff --git a/b2g/components/ActivityChannel.jsm b/b2g/components/ActivityChannel.jsm deleted file mode 100644 index 9dfa13d67..000000000 --- a/b2g/components/ActivityChannel.jsm +++ /dev/null @@ -1,64 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsIMessageSender"); - -XPCOMUtils.defineLazyServiceGetter(this, "contentSecManager", - "@mozilla.org/contentsecuritymanager;1", - "nsIContentSecurityManager"); - -this.EXPORTED_SYMBOLS = ["ActivityChannel"]; - -this.ActivityChannel = function(aURI, aLoadInfo, aName, aDetails) { - this._activityName = aName; - this._activityDetails = aDetails; - this.originalURI = aURI; - this.URI = aURI; - this.loadInfo = aLoadInfo; -} - -this.ActivityChannel.prototype = { - originalURI: null, - URI: null, - owner: null, - notificationCallbacks: null, - securityInfo: null, - contentType: null, - contentCharset: null, - contentLength: 0, - contentDisposition: Ci.nsIChannel.DISPOSITION_INLINE, - contentDispositionFilename: null, - contentDispositionHeader: null, - loadInfo: null, - - open: function() { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - open2: function() { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - asyncOpen: function(aListener, aContext) { - cpmm.sendAsyncMessage(this._activityName, this._activityDetails); - // Let the listener cleanup. - aListener.onStopRequest(this, aContext, Cr.NS_OK); - }, - - asyncOpen2: function(aListener) { - // throws an error if security checks fail - var outListener = contentSecManager.performSecurityCheck(this, aListener); - this.asyncOpen(outListener, null); - }, - - QueryInterface2: XPCOMUtils.generateQI([Ci.nsIChannel]) -} diff --git a/b2g/components/AlertsHelper.jsm b/b2g/components/AlertsHelper.jsm deleted file mode 100644 index 820f2406c..000000000 --- a/b2g/components/AlertsHelper.jsm +++ /dev/null @@ -1,279 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = []; - -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cc = Components.classes; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppsUtils.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage", - "@mozilla.org/notificationStorage;1", - "nsINotificationStorage"); - -XPCOMUtils.defineLazyGetter(this, "ppmm", function() { - return Cc["@mozilla.org/parentprocessmessagemanager;1"] - .getService(Ci.nsIMessageListenerManager); -}); - -function debug(str) { - //dump("=*= AlertsHelper.jsm : " + str + "\n"); -} - -const kNotificationIconSize = 128; - -const kDesktopNotificationPerm = "desktop-notification"; - -const kNotificationSystemMessageName = "notification"; - -const kDesktopNotification = "desktop-notification"; -const kDesktopNotificationShow = "desktop-notification-show"; -const kDesktopNotificationClick = "desktop-notification-click"; -const kDesktopNotificationClose = "desktop-notification-close"; - -const kTopicAlertClickCallback = "alertclickcallback"; -const kTopicAlertShow = "alertshow"; -const kTopicAlertFinished = "alertfinished"; - -const kMozChromeNotificationEvent = "mozChromeNotificationEvent"; -const kMozContentNotificationEvent = "mozContentNotificationEvent"; - -const kMessageAlertNotificationSend = "alert-notification-send"; -const kMessageAlertNotificationClose = "alert-notification-close"; - -const kMessages = [ - kMessageAlertNotificationSend, - kMessageAlertNotificationClose -]; - -var AlertsHelper = { - - _listeners: {}, - - init: function() { - Services.obs.addObserver(this, "xpcom-shutdown", false); - for (let message of kMessages) { - ppmm.addMessageListener(message, this); - } - SystemAppProxy.addEventListener(kMozContentNotificationEvent, this); - }, - - observe: function(aSubject, aTopic, aData) { - switch (aTopic) { - case "xpcom-shutdown": - Services.obs.removeObserver(this, "xpcom-shutdown"); - for (let message of kMessages) { - ppmm.removeMessageListener(message, this); - } - SystemAppProxy.removeEventListener(kMozContentNotificationEvent, this); - break; - } - }, - - handleEvent: function(evt) { - let detail = evt.detail; - - switch(detail.type) { - case kDesktopNotificationShow: - case kDesktopNotificationClick: - case kDesktopNotificationClose: - this.handleNotificationEvent(detail); - break; - default: - debug("FIXME: Unhandled notification event: " + detail.type); - break; - } - }, - - handleNotificationEvent: function(detail) { - if (!detail || !detail.id) { - return; - } - - let uid = detail.id; - let listener = this._listeners[uid]; - if (!listener) { - return; - } - - let topic; - if (detail.type === kDesktopNotificationClick) { - topic = kTopicAlertClickCallback; - } else if (detail.type === kDesktopNotificationShow) { - topic = kTopicAlertShow; - } else { - /* kDesktopNotificationClose */ - topic = kTopicAlertFinished; - } - - if (listener.cookie) { - try { - listener.observer.observe(null, topic, listener.cookie); - } catch (e) { } - } else { - if (detail.type === kDesktopNotificationClose && listener.dbId) { - notificationStorage.delete(listener.manifestURL, listener.dbId); - } - } - - // we"re done with this notification - if (detail.type === kDesktopNotificationClose) { - delete this._listeners[uid]; - } - }, - - registerListener: function(alertId, cookie, alertListener) { - this._listeners[alertId] = { observer: alertListener, cookie: cookie }; - }, - - registerAppListener: function(uid, listener) { - this._listeners[uid] = listener; - - appsService.getManifestFor(listener.manifestURL).then((manifest) => { - let app = appsService.getAppByManifestURL(listener.manifestURL); - let helper = new ManifestHelper(manifest, app.origin, app.manifestURL); - let getNotificationURLFor = function(messages) { - if (!messages) { - return null; - } - - for (let i = 0; i < messages.length; i++) { - let message = messages[i]; - if (message === kNotificationSystemMessageName) { - return helper.fullLaunchPath(); - } else if (typeof message === "object" && - kNotificationSystemMessageName in message) { - return helper.resolveURL(message[kNotificationSystemMessageName]); - } - } - - // No message found... - return null; - } - - listener.target = getNotificationURLFor(manifest.messages); - - // Bug 816944 - Support notification messages for entry_points. - }); - }, - - deserializeStructuredClone: function(dataString) { - if (!dataString) { - return null; - } - let scContainer = Cc["@mozilla.org/docshell/structured-clone-container;1"]. - createInstance(Ci.nsIStructuredCloneContainer); - - // The maximum supported structured-clone serialization format version - // as defined in "js/public/StructuredClone.h" - let JS_STRUCTURED_CLONE_VERSION = 4; - scContainer.initFromBase64(dataString, JS_STRUCTURED_CLONE_VERSION); - let dataObj = scContainer.deserializeToVariant(); - - // We have to check whether dataObj contains DOM objects (supported by - // nsIStructuredCloneContainer, but not by Cu.cloneInto), e.g. ImageData. - // After the structured clone callback systems will be unified, we'll not - // have to perform this check anymore. - try { - let data = Cu.cloneInto(dataObj, {}); - } catch(e) { dataObj = null; } - - return dataObj; - }, - - showNotification: function(imageURL, title, text, textClickable, cookie, - uid, dir, lang, dataObj, manifestURL, timestamp, - behavior) { - function send(appName, appIcon) { - SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, { - type: kDesktopNotification, - id: uid, - icon: imageURL, - title: title, - text: text, - dir: dir, - lang: lang, - appName: appName, - appIcon: appIcon, - manifestURL: manifestURL, - timestamp: timestamp, - data: dataObj, - mozbehavior: behavior - }); - } - - if (!manifestURL || !manifestURL.length) { - send(null, null); - return; - } - - // If we have a manifest URL, get the icon and title from the manifest - // to prevent spoofing. - appsService.getManifestFor(manifestURL).then((manifest) => { - let app = appsService.getAppByManifestURL(manifestURL); - let helper = new ManifestHelper(manifest, app.origin, manifestURL); - send(helper.name, helper.iconURLForSize(kNotificationIconSize)); - }); - }, - - showAlertNotification: function(aMessage) { - let data = aMessage.data; - let currentListener = this._listeners[data.name]; - if (currentListener && currentListener.observer) { - currentListener.observer.observe(null, kTopicAlertFinished, currentListener.cookie); - } - - let dataObj = this.deserializeStructuredClone(data.dataStr); - this.registerListener(data.name, data.cookie, data.alertListener); - this.showNotification(data.imageURL, data.title, data.text, - data.textClickable, data.cookie, data.name, data.dir, - data.lang, dataObj, null, data.inPrivateBrowsing); - }, - - closeAlert: function(name) { - SystemAppProxy._sendCustomEvent(kMozChromeNotificationEvent, { - type: kDesktopNotificationClose, - id: name - }); - }, - - receiveMessage: function(aMessage) { - if (!aMessage.target.assertAppHasPermission(kDesktopNotificationPerm)) { - Cu.reportError("Desktop-notification message " + aMessage.name + - " from a content process with no " + kDesktopNotificationPerm + - " privileges."); - return; - } - - switch(aMessage.name) { - case kMessageAlertNotificationSend: - this.showAlertNotification(aMessage); - break; - - case kMessageAlertNotificationClose: - this.closeAlert(aMessage.data.name); - break; - } - - }, -} - -AlertsHelper.init(); diff --git a/b2g/components/AlertsService.js b/b2g/components/AlertsService.js deleted file mode 100644 index 19a164f0e..000000000 --- a/b2g/components/AlertsService.js +++ /dev/null @@ -1,153 +0,0 @@ -/* 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/. */ - -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cc = Components.classes; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger", - "@mozilla.org/system-message-internal;1", - "nsISystemMessagesInternal"); - -XPCOMUtils.defineLazyServiceGetter(this, "uuidGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - -XPCOMUtils.defineLazyServiceGetter(this, "notificationStorage", - "@mozilla.org/notificationStorage;1", - "nsINotificationStorage"); - -XPCOMUtils.defineLazyGetter(this, "cpmm", function() { - return Cc["@mozilla.org/childprocessmessagemanager;1"] - .getService(Ci.nsIMessageSender); -}); - -function debug(str) { - dump("=*= AlertsService.js : " + str + "\n"); -} - -// ----------------------------------------------------------------------- -// Alerts Service -// ----------------------------------------------------------------------- - -const kNotificationSystemMessageName = "notification"; - -const kMessageAlertNotificationSend = "alert-notification-send"; -const kMessageAlertNotificationClose = "alert-notification-close"; - -const kTopicAlertShow = "alertshow"; -const kTopicAlertFinished = "alertfinished"; -const kTopicAlertClickCallback = "alertclickcallback"; - -function AlertsService() { - Services.obs.addObserver(this, "xpcom-shutdown", false); -} - -AlertsService.prototype = { - classID: Components.ID("{fe33c107-82a4-41d6-8c64-5353267e04c9}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIAlertsService, - Ci.nsIObserver]), - - observe: function(aSubject, aTopic, aData) { - switch (aTopic) { - case "xpcom-shutdown": - Services.obs.removeObserver(this, "xpcom-shutdown"); - break; - } - }, - - // nsIAlertsService - showAlert: function(aAlert, aAlertListener) { - if (!aAlert) { - return; - } - cpmm.sendAsyncMessage(kMessageAlertNotificationSend, { - imageURL: aAlert.imageURL, - title: aAlert.title, - text: aAlert.text, - clickable: aAlert.textClickable, - cookie: aAlert.cookie, - listener: aAlertListener, - id: aAlert.name, - dir: aAlert.dir, - lang: aAlert.lang, - dataStr: aAlert.data, - inPrivateBrowsing: aAlert.inPrivateBrowsing - }); - }, - - showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable, - aCookie, aAlertListener, aName, aBidi, - aLang, aDataStr, aPrincipal, - aInPrivateBrowsing) { - let alert = Cc["@mozilla.org/alert-notification;1"]. - createInstance(Ci.nsIAlertNotification); - - alert.init(aName, aImageUrl, aTitle, aText, aTextClickable, aCookie, - aBidi, aLang, aDataStr, aPrincipal, aInPrivateBrowsing); - - this.showAlert(alert, aAlertListener); - }, - - closeAlert: function(aName) { - cpmm.sendAsyncMessage(kMessageAlertNotificationClose, { - name: aName - }); - }, - - // AlertsService.js custom implementation - _listeners: [], - - receiveMessage: function(aMessage) { - let data = aMessage.data; - let listener = this._listeners[data.uid]; - if (!listener) { - return; - } - - let topic = data.topic; - - try { - listener.observer.observe(null, topic, null); - } catch (e) { - if (topic === kTopicAlertFinished && listener.dbId) { - notificationStorage.delete(listener.manifestURL, listener.dbId); - } - } - - // we're done with this notification - if (topic === kTopicAlertFinished) { - delete this._listeners[data.uid]; - } - }, - - deserializeStructuredClone: function(dataString) { - if (!dataString) { - return null; - } - let scContainer = Cc["@mozilla.org/docshell/structured-clone-container;1"]. - createInstance(Ci.nsIStructuredCloneContainer); - - // The maximum supported structured-clone serialization format version - // as defined in "js/public/StructuredClone.h" - let JS_STRUCTURED_CLONE_VERSION = 4; - scContainer.initFromBase64(dataString, JS_STRUCTURED_CLONE_VERSION); - let dataObj = scContainer.deserializeToVariant(); - - // We have to check whether dataObj contains DOM objects (supported by - // nsIStructuredCloneContainer, but not by Cu.cloneInto), e.g. ImageData. - // After the structured clone callback systems will be unified, we'll not - // have to perform this check anymore. - try { - let data = Cu.cloneInto(dataObj, {}); - } catch(e) { dataObj = null; } - - return dataObj; - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlertsService]); diff --git a/b2g/components/B2GAboutRedirector.js b/b2g/components/B2GAboutRedirector.js deleted file mode 100644 index f4bcf47f4..000000000 --- a/b2g/components/B2GAboutRedirector.js +++ /dev/null @@ -1,78 +0,0 @@ -/* 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/. */ -const Cc = Components.classes; -const Ci = Components.interfaces; - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -function debug(msg) { - //dump("B2GAboutRedirector: " + msg + "\n"); -} - -function netErrorURL() { - let systemManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url"); - systemManifestURL = Services.io.newURI(systemManifestURL, null, null); - let netErrorURL = Services.prefs.getCharPref("b2g.neterror.url"); - netErrorURL = Services.io.newURI(netErrorURL, null, systemManifestURL); - return netErrorURL.spec; -} - -var modules = { - certerror: { - uri: "chrome://b2g/content/aboutCertError.xhtml", - privileged: false, - hide: true - }, - neterror: { - uri: netErrorURL(), - privileged: false, - hide: true - } -}; - -function B2GAboutRedirector() {} -B2GAboutRedirector.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), - classID: Components.ID("{920400b1-cf8f-4760-a9c4-441417b15134}"), - - _getModuleInfo: function (aURI) { - let moduleName = aURI.path.replace(/[?#].*/, "").toLowerCase(); - return modules[moduleName]; - }, - - // nsIAboutModule - getURIFlags: function(aURI) { - let flags; - let moduleInfo = this._getModuleInfo(aURI); - if (moduleInfo.hide) - flags = Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT; - - return flags | Ci.nsIAboutModule.ALLOW_SCRIPT; - }, - - newChannel: function(aURI, aLoadInfo) { - let moduleInfo = this._getModuleInfo(aURI); - - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - - var newURI = ios.newURI(moduleInfo.uri, null, null); - - var channel = ios.newChannelFromURIWithLoadInfo(newURI, aLoadInfo); - - if (!moduleInfo.privileged) { - // Setting the owner to null means that we'll go through the normal - // path in GetChannelPrincipal and create a codebase principal based - // on the channel's originalURI - channel.owner = null; - } - - channel.originalURI = aURI; - - return channel; - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GAboutRedirector]); diff --git a/b2g/components/B2GAppMigrator.js b/b2g/components/B2GAppMigrator.js deleted file mode 100644 index 65671d151..000000000 --- a/b2g/components/B2GAppMigrator.js +++ /dev/null @@ -1,152 +0,0 @@ -/* 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/. */ - -'use strict'; - -function debug(s) { - dump("-*- B2GAppMigrator.js: " + s + "\n"); -} -const DEBUG = false; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -const kMigrationMessageName = "webapps-before-update-merge"; - -const kIDBDirType = "indexedDBPDir"; -const kProfileDirType = "ProfD"; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "appsService", - "@mozilla.org/AppsService;1", - "nsIAppsService"); - -function B2GAppMigrator() { -} - -B2GAppMigrator.prototype = { - classID: Components.ID('{7211ece0-b458-4635-9afc-f8d7f376ee95}'), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsISupportsWeakReference]), - executeBrowserMigration: function() { - if (DEBUG) debug("Executing Browser Migration"); - // The browser db file and directory names are hashed the same way - // everywhere, so it should be the same on all systems. We should - // be able to just hardcode it. - let browserDBDirName = "2959517650brreosw"; - let browserDBFileName = browserDBDirName + ".sqlite"; - - // Storage directories need to be prefixed with the local id of - // the app - let browserLocalAppId = appsService.getAppLocalIdByManifestURL("app://browser.gaiamobile.org/manifest.webapp"); - let browserAppStorageDirName = browserLocalAppId + "+f+app+++browser.gaiamobile.org"; - - // On the phone, the browser db will only be in the old IDB - // directory, since it only existed up until v2.0. On desktop, it - // will exist in the profile directory. - // - // Uses getDir with filename appending to make sure we don't - // create extra directories along the way if they don't already - // exist. - let browserDBFile = FileUtils.getDir(kIDBDirType, - ["storage", - "persistent", - browserAppStorageDirName, - "idb"], false, true); - browserDBFile.append(browserDBFileName); - let browserDBDir = FileUtils.getDir(kIDBDirType, - ["storage", - "persistent", - browserAppStorageDirName, - "idb", - browserDBDirName - ], false, true); - - if (!browserDBFile.exists()) { - if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist, trying profile location"); - browserDBFile = FileUtils.getDir(kProfileDirType, - ["storage", - "persistent", - browserAppStorageDirName, - "idb"], false, true); - browserDBFile.append(browserDBFileName); - if (!browserDBFile.exists()) { - if (DEBUG) debug("Browser DB " + browserDBFile.path + " does not exist. Cannot copy browser db."); - return; - } - // If we have confirmed we have a DB file, we should also have a - // directory. - browserDBDir = FileUtils.getDir(kProfileDirType, - ["storage", - "persistent", - browserAppStorageDirName, - "idb", - browserDBDirName - ], false, true); - } - - let systemLocalAppId = appsService.getAppLocalIdByManifestURL("app://system.gaiamobile.org/manifest.webapp"); - let systemAppStorageDirName = systemLocalAppId + "+f+app+++system.gaiamobile.org"; - - // This check futureproofs the system DB storage directory. It - // currently exists outside of the profile but will most likely - // move into the profile at some point. - let systemDBDir = FileUtils.getDir(kIDBDirType, - ["storage", - "persistent", - systemAppStorageDirName, - "idb"], false, true); - - if (!systemDBDir.exists()) { - if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist, trying profile location"); - systemDBDir = FileUtils.getDir(kProfileDirType, - ["storage", - "persistent", - systemAppStorageDirName, - "idb"], false, true); - if (!systemDBDir.exists()) { - if (DEBUG) debug("System DB directory " + systemDBDir.path + " does not exist. Cannot copy browser db."); - return; - } - } - - if (DEBUG) { - debug("Browser DB file exists, copying"); - debug("Browser local id: " + browserLocalAppId + ""); - debug("System local id: " + systemLocalAppId + ""); - debug("Browser DB file path: " + browserDBFile.path + ""); - debug("Browser DB dir path: " + browserDBDir.path + ""); - debug("System DB directory path: " + systemDBDir.path + ""); - } - - try { - browserDBFile.copyTo(systemDBDir, browserDBFileName); - } catch (e) { - debug("File copy caused error! " + e.name); - } - try { - browserDBDir.copyTo(systemDBDir, browserDBDirName); - } catch (e) { - debug("Dir copy caused error! " + e.name); - } - if (DEBUG) debug("Browser DB copied successfully"); - }, - - observe: function(subject, topic, data) { - switch (topic) { - case kMigrationMessageName: - this.executeBrowserMigration(); - break; - default: - debug("Unhandled topic: " + topic); - break; - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GAppMigrator]); diff --git a/b2g/components/B2GComponents.manifest b/b2g/components/B2GComponents.manifest deleted file mode 100644 index 53d0032f9..000000000 --- a/b2g/components/B2GComponents.manifest +++ /dev/null @@ -1,108 +0,0 @@ -# Scrollbars -category agent-style-sheets browser-content-stylesheet chrome://b2g/content/content.css - -# AlertsService.js -component {fe33c107-82a4-41d6-8c64-5353267e04c9} AlertsService.js -contract @mozilla.org/system-alerts-service;1 {fe33c107-82a4-41d6-8c64-5353267e04c9} - -# ContentPermissionPrompt.js -component {8c719f03-afe0-4aac-91ff-6c215895d467} ContentPermissionPrompt.js -contract @mozilla.org/content-permission/prompt;1 {8c719f03-afe0-4aac-91ff-6c215895d467} - -#ifdef MOZ_UPDATER -# UpdatePrompt.js -component {88b3eb21-d072-4e3b-886d-f89d8c49fe59} UpdatePrompt.js -contract @mozilla.org/updates/update-prompt;1 {88b3eb21-d072-4e3b-886d-f89d8c49fe59} -category system-update-provider MozillaProvider @mozilla.org/updates/update-prompt;1,{88b3eb21-d072-4e3b-886d-f89d8c49fe59} -#endif - -#ifdef MOZ_B2G -# DirectoryProvider.js -component {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} DirectoryProvider.js -contract @mozilla.org/b2g/directory-provider;1 {9181eb7c-6f87-11e1-90b1-4f59d80dd2e5} -category xpcom-directory-providers b2g-directory-provider @mozilla.org/b2g/directory-provider;1 -#endif - -# SystemMessageGlue.js -component {2846f034-e614-11e3-93cd-74d02b97e723} SystemMessageGlue.js -contract @mozilla.org/dom/messages/system-message-glue;1 {2846f034-e614-11e3-93cd-74d02b97e723} - -# ProcessGlobal.js -component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js -contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28} -category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1 - -# OMAContentHandler.js -component {a6b2ab13-9037-423a-9897-dde1081be323} OMAContentHandler.js -contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.drm.message {a6b2ab13-9037-423a-9897-dde1081be323} -contract @mozilla.org/uriloader/content-handler;1?type=application/vnd.oma.dd+xml {a6b2ab13-9037-423a-9897-dde1081be323} - -# TelProtocolHandler.js -component {782775dd-7351-45ea-aff1-0ffa872cfdd2} TelProtocolHandler.js -contract @mozilla.org/network/protocol;1?name=tel {782775dd-7351-45ea-aff1-0ffa872cfdd2} - -# SmsProtocolHandler.js -component {81ca20cb-0dad-4e32-8566-979c8998bd73} SmsProtocolHandler.js -contract @mozilla.org/network/protocol;1?name=sms {81ca20cb-0dad-4e32-8566-979c8998bd73} - -# MailtoProtocolHandler.js -component {50777e53-0331-4366-a191-900999be386c} MailtoProtocolHandler.js -contract @mozilla.org/network/protocol;1?name=mailto {50777e53-0331-4366-a191-900999be386c} - -# RecoveryService.js -component {b3caca5d-0bb0-48c6-912b-6be6cbf08832} RecoveryService.js -contract @mozilla.org/recovery-service;1 {b3caca5d-0bb0-48c6-912b-6be6cbf08832} - -# B2GAboutRedirector -component {920400b1-cf8f-4760-a9c4-441417b15134} B2GAboutRedirector.js -contract @mozilla.org/network/protocol/about;1?what=certerror {920400b1-cf8f-4760-a9c4-441417b15134} -contract @mozilla.org/network/protocol/about;1?what=neterror {920400b1-cf8f-4760-a9c4-441417b15134} - -#ifndef MOZ_GRAPHENE -# FilePicker.js -component {436ff8f9-0acc-4b11-8ec7-e293efba3141} FilePicker.js -contract @mozilla.org/filepicker;1 {436ff8f9-0acc-4b11-8ec7-e293efba3141} -#endif - -# FxAccountsUIGlue.js -component {51875c14-91d7-4b8c-b65d-3549e101228c} FxAccountsUIGlue.js -contract @mozilla.org/fxaccounts/fxaccounts-ui-glue;1 {51875c14-91d7-4b8c-b65d-3549e101228c} - -# HelperAppDialog.js -component {710322af-e6ae-4b0c-b2c9-1474a87b077e} HelperAppDialog.js -contract @mozilla.org/helperapplauncherdialog;1 {710322af-e6ae-4b0c-b2c9-1474a87b077e} - -#ifndef MOZ_WIDGET_GONK -component {c83c02c0-5d43-4e3e-987f-9173b313e880} SimulatorScreen.js -contract @mozilla.org/simulator-screen;1 {c83c02c0-5d43-4e3e-987f-9173b313e880} -category profile-after-change SimulatorScreen @mozilla.org/simulator-screen;1 - -component {e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e} OopCommandLine.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=b2goop {e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e} -category command-line-handler m-b2goop @mozilla.org/commandlinehandler/general-startup;1?type=b2goop - -component {385993fe-8710-4621-9fb1-00a09d8bec37} CommandLine.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds {385993fe-8710-4621-9fb1-00a09d8bec37} -category command-line-handler m-b2gcmds @mozilla.org/commandlinehandler/general-startup;1?type=b2gcmds -#endif - -# BootstrapCommandLine.js -component {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} BootstrapCommandLine.js -contract @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap {fd663ec8-cf3f-4c2b-aacb-17a6915ccb44} -category command-line-handler m-b2gbootstrap @mozilla.org/commandlinehandler/general-startup;1?type=b2gbootstrap - -# B2GAppMigrator.js -component {7211ece0-b458-4635-9afc-f8d7f376ee95} B2GAppMigrator.js -contract @mozilla.org/app-migrator;1 {7211ece0-b458-4635-9afc-f8d7f376ee95} - -# B2GPresentationDevicePrompt.js -component {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} B2GPresentationDevicePrompt.js -contract @mozilla.org/presentation-device/prompt;1 {4a300c26-e99b-4018-ab9b-c48cf9bc4de1} - -# PresentationRequestUIGlue.js -component {ccc8a839-0b64-422b-8a60-fb2af0e376d0} PresentationRequestUIGlue.js -contract @mozilla.org/presentation/requestuiglue;1 {ccc8a839-0b64-422b-8a60-fb2af0e376d0} - -# SystemMessageInternal.js -component {70589ca5-91ac-4b9e-b839-d6a88167d714} SystemMessageInternal.js -contract @mozilla.org/system-message-internal;1 {70589ca5-91ac-4b9e-b839-d6a88167d714} diff --git a/b2g/components/B2GPresentationDevicePrompt.js b/b2g/components/B2GPresentationDevicePrompt.js deleted file mode 100644 index 998e0b7ac..000000000 --- a/b2g/components/B2GPresentationDevicePrompt.js +++ /dev/null @@ -1,87 +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/. */ - -"use strict"; - -function debug(aMsg) { - //dump("-*- B2GPresentationDevicePrompt: " + aMsg + "\n"); -} - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -const kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID = "@mozilla.org/presentation-device/prompt;1"; -const kB2GPRESENTATIONDEVICEPROMPT_CID = Components.ID("{4a300c26-e99b-4018-ab9b-c48cf9bc4de1}"); - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -function B2GPresentationDevicePrompt() {} - -B2GPresentationDevicePrompt.prototype = { - classID: kB2GPRESENTATIONDEVICEPROMPT_CID, - contractID: kB2GPRESENTATIONDEVICEPROMPT_CONTRACTID, - classDescription: "B2G Presentation Device Prompt", - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevicePrompt]), - - // nsIPresentationDevicePrompt - promptDeviceSelection: function(aRequest) { - let self = this; - let requestId = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator).generateUUID().toString(); - - SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(aEvent) { - let detail = aEvent.detail; - if (detail.id !== requestId) { - return; - } - - SystemAppProxy.removeEventListener("mozContentEvent", contentEvent); - - switch (detail.type) { - case "presentation-select-result": - debug("device " + detail.deviceId + " is selected by user"); - let device = self._getDeviceById(detail.deviceId); - if (!device) { - debug("cancel request because device is not found"); - aRequest.cancel(Cr.NS_ERROR_DOM_NOT_FOUND_ERR); - } - aRequest.select(device); - break; - case "presentation-select-deny": - debug("request canceled by user"); - aRequest.cancel(Cr.NS_ERROR_DOM_NOT_ALLOWED_ERR); - break; - } - }); - - let detail = { - type: "presentation-select-device", - origin: aRequest.origin, - requestURL: aRequest.requestURL, - id: requestId, - }; - - SystemAppProxy.dispatchEvent(detail); - }, - - _getDeviceById: function(aDeviceId) { - let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"] - .getService(Ci.nsIPresentationDeviceManager); - let devices = deviceManager.getAvailableDevices().QueryInterface(Ci.nsIArray); - - for (let i = 0; i < devices.length; i++) { - let device = devices.queryElementAt(i, Ci.nsIPresentationDevice); - if (device.id === aDeviceId) { - return device; - } - } - - return null; - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([B2GPresentationDevicePrompt]); diff --git a/b2g/components/BootstrapCommandLine.js b/b2g/components/BootstrapCommandLine.js deleted file mode 100644 index 24d9f5461..000000000 --- a/b2g/components/BootstrapCommandLine.js +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/. */ - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/AppsUtils.jsm"); - -function BootstrapCommandlineHandler() { - this.wrappedJSObject = this; - this.startManifestURL = null; -} - -BootstrapCommandlineHandler.prototype = { - bailout: function(aMsg) { - dump("************************************************************\n"); - dump("* /!\\ " + aMsg + "\n"); - dump("************************************************************\n"); - let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] - .getService(Ci.nsIAppStartup); - appStartup.quit(appStartup.eForceQuit); - }, - - handle: function(aCmdLine) { - this.startManifestURL = null; - - try { - // Returns null if the argument was not specified. Throws - // NS_ERROR_INVALID_ARG if there is no parameter specified (because - // it was the last argument or the next argument starts with '-'). - // However, someone could still explicitly pass an empty argument! - this.startManifestURL = aCmdLine.handleFlagWithParam("start-manifest", false); - } catch(e) { - return; - } - - if (!this.startManifestURL) { - return; - } - - if (!isAbsoluteURI(this.startManifestURL)) { - this.bailout("The start manifest url must be absolute."); - return; - } - }, - - helpInfo: "--start-manifest=manifest_url", - classID: Components.ID("{fd663ec8-cf3f-4c2b-aacb-17a6915ccb44}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BootstrapCommandlineHandler]); diff --git a/b2g/components/Bootstraper.jsm b/b2g/components/Bootstraper.jsm deleted file mode 100644 index 3d3fb37d9..000000000 --- a/b2g/components/Bootstraper.jsm +++ /dev/null @@ -1,156 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["Bootstraper"]; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const CC = Components.Constructor; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppsUtils.jsm"); - -function debug(aMsg) { - //dump("-*- Bootstraper: " + aMsg + "\n"); -} - -/** - * This module loads the manifest for app from the --start-url enpoint and - * ensures that it's installed as the system app. - */ -this.Bootstraper = { - _manifestURL: null, - _startupURL: null, - - bailout: function(aMsg) { - dump("************************************************************\n"); - dump("* /!\\ " + aMsg + "\n"); - dump("************************************************************\n"); - let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] - .getService(Ci.nsIAppStartup); - appStartup.quit(appStartup.eForceQuit); - }, - - installSystemApp: function(aManifest) { - // Get the appropriate startup url from the manifest launch_path. - let base = Services.io.newURI(this._manifestURL, null, null); - let origin = base.prePath; - let helper = new ManifestHelper(aManifest, origin, this._manifestURL); - this._startupURL = helper.fullLaunchPath(); - - return new Promise((aResolve, aReject) => { - debug("Origin is " + origin); - let appData = { - app: { - installOrigin: origin, - origin: origin, - manifest: aManifest, - manifestURL: this._manifestURL, - manifestHash: AppsUtils.computeHash(JSON.stringify(aManifest)), - appStatus: Ci.nsIPrincipal.APP_STATUS_CERTIFIED - }, - appId: 1, - isBrowser: false, - isPackage: false - }; - - //DOMApplicationRegistry.confirmInstall(appData, null, aResolve); - }); - }, - - /** - * Resolves to a json manifest. - */ - loadManifest: function() { - return new Promise((aResolve, aReject) => { - debug("Loading manifest " + this._manifestURL); - - let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Ci.nsIXMLHttpRequest); - xhr.mozBackgroundRequest = true; - xhr.open("GET", this._manifestURL); - xhr.responseType = "json"; - xhr.addEventListener("load", () => { - if (xhr.status >= 200 && xhr.status < 400) { - debug("Success loading " + this._manifestURL); - aResolve(xhr.response); - } else { - aReject("Error loading " + this._manifestURL); - } - }); - xhr.addEventListener("error", () => { - aReject("Error loading " + this._manifestURL); - }); - xhr.send(null); - }); - }, - - configure: function() { - debug("Setting startup prefs... " + this._startupURL); - Services.prefs.setCharPref("b2g.system_manifest_url", this._manifestURL); - Services.prefs.setCharPref("b2g.system_startup_url", this._startupURL); - return Promise.resolve(); - }, - - /** - * If a system app is already installed, uninstall it so that we can - * cleanly replace it by the current one. - */ - uninstallPreviousSystemApp: function() { - // TODO: FIXME - return Promise.resolve(); - - let oldManifestURL; - try{ - oldManifestURL = Services.prefs.getCharPref("b2g.system_manifest_url"); - } catch(e) { - // No preference set, so nothing to uninstall. - return Promise.resolve(); - } - - let id = DOMApplicationRegistry.getAppLocalIdByManifestURL(oldManifestURL); - if (id == Ci.nsIScriptSecurityManager.NO_APP_ID) { - return Promise.resolve(); - } - debug("Uninstalling " + oldManifestURL); - return DOMApplicationRegistry.uninstall(oldManifestURL); - }, - - /** - * Check if we are already configured to run from this manifest url. - */ - isInstallRequired: function(aManifestURL) { - try { - if (Services.prefs.getCharPref("b2g.system_manifest_url") == aManifestURL) { - return false; - } - } catch(e) { } - return true; - }, - - /** - * Resolves once we have installed the app. - */ - ensureSystemAppInstall: function(aManifestURL) { - this._manifestURL = aManifestURL; - debug("Installing app from " + this._manifestURL); - - if (!this.isInstallRequired(this._manifestURL)) { - debug("Already configured for " + this._manifestURL); - return Promise.resolve(); - } - - return new Promise((aResolve, aReject) => { - this.uninstallPreviousSystemApp.bind(this) - .then(this.loadManifest.bind(this)) - .then(this.installSystemApp.bind(this)) - .then(this.configure.bind(this)) - .then(aResolve) - .catch(aReject); - }); - } -}; diff --git a/b2g/components/CommandLine.js b/b2g/components/CommandLine.js deleted file mode 100644 index 6dc48bd33..000000000 --- a/b2g/components/CommandLine.js +++ /dev/null @@ -1,29 +0,0 @@ -/* 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/. */ - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); - -// Small helper to expose nsICommandLine object to chrome code - -function CommandlineHandler() { - this.wrappedJSObject = this; -} - -CommandlineHandler.prototype = { - handle: function(cmdLine) { - this.cmdLine = cmdLine; - let win = Services.wm.getMostRecentWindow("navigator:browser"); - if (win && win.shell) { - win.shell.handleCmdLine(); - } - }, - - helpInfo: "", - classID: Components.ID("{385993fe-8710-4621-9fb1-00a09d8bec37}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([CommandlineHandler]); diff --git a/b2g/components/ContentPermissionPrompt.js b/b2g/components/ContentPermissionPrompt.js deleted file mode 100644 index e11b1b458..000000000 --- a/b2g/components/ContentPermissionPrompt.js +++ /dev/null @@ -1,461 +0,0 @@ -/* 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/. */ - -"use strict" - -function debug(str) { - //dump("-*- ContentPermissionPrompt: " + str + "\n"); -} - -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; -const Cc = Components.classes; - -const PROMPT_FOR_UNKNOWN = ["audio-capture", - "desktop-notification", - "geolocation", - "video-capture"]; -// Due to privary issue, permission requests like GetUserMedia should prompt -// every time instead of providing session persistence. -const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"]; -const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"]; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppsUtils.jsm"); -Cu.import("resource://gre/modules/PermissionsInstaller.jsm"); -Cu.import("resource://gre/modules/PermissionsTable.jsm"); - -var permissionManager = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager); -var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); - -var permissionSpecificChecker = {}; - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -/** - * Determine if a permission should be prompt to user or not. - * - * @param aPerm requested permission - * @param aAction the action according to principal - * @return true if prompt is required - */ -function shouldPrompt(aPerm, aAction) { - return ((aAction == Ci.nsIPermissionManager.PROMPT_ACTION) || - (aAction == Ci.nsIPermissionManager.UNKNOWN_ACTION && - PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0)); -} - -/** - * Create the default choices for the requested permissions - * - * @param aTypesInfo requested permissions - * @return the default choices for permissions with options, return - * undefined if no option in all requested permissions. - */ -function buildDefaultChoices(aTypesInfo) { - let choices; - for (let type of aTypesInfo) { - if (type.options.length > 0) { - if (!choices) { - choices = {}; - } - choices[type.access] = type.options[0]; - } - } - return choices; -} - -/** - * aTypesInfo is an array of {permission, access, action, deny} which keeps - * the information of each permission. This arrary is initialized in - * ContentPermissionPrompt.prompt and used among functions. - * - * aTypesInfo[].permission : permission name - * aTypesInfo[].access : permission name + request.access - * aTypesInfo[].action : the default action of this permission - * aTypesInfo[].deny : true if security manager denied this app's origin - * principal. - * Note: - * aTypesInfo[].permission will be sent to prompt only when - * aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false. - */ -function rememberPermission(aTypesInfo, aPrincipal, aSession) -{ - function convertPermToAllow(aPerm, aPrincipal) - { - let type = - permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm); - if (shouldPrompt(aPerm, type)) { - debug("add " + aPerm + " to permission manager with ALLOW_ACTION"); - if (!aSession) { - permissionManager.addFromPrincipal(aPrincipal, - aPerm, - Ci.nsIPermissionManager.ALLOW_ACTION); - } else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) { - permissionManager.addFromPrincipal(aPrincipal, - aPerm, - Ci.nsIPermissionManager.ALLOW_ACTION, - Ci.nsIPermissionManager.EXPIRE_SESSION, 0); - } - } - } - - for (let i in aTypesInfo) { - // Expand the permission to see if we have multiple access properties - // to convert - let perm = aTypesInfo[i].permission; - let access = PermissionsTable[perm].access; - if (access) { - for (let idx in access) { - convertPermToAllow(perm + "-" + access[idx], aPrincipal); - } - } else { - convertPermToAllow(perm, aPrincipal); - } - } -} - -function ContentPermissionPrompt() {} - -ContentPermissionPrompt.prototype = { - - handleExistingPermission: function handleExistingPermission(request, - typesInfo) { - typesInfo.forEach(function(type) { - type.action = - Services.perms.testExactPermissionFromPrincipal(request.principal, - type.access); - if (shouldPrompt(type.access, type.action)) { - type.action = Ci.nsIPermissionManager.PROMPT_ACTION; - } - }); - - // If all permissions are allowed already and no more than one option, - // call allow() without prompting. - let checkAllowPermission = function(type) { - if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION && - type.options.length <= 1) { - return true; - } - return false; - } - if (typesInfo.every(checkAllowPermission)) { - debug("all permission requests are allowed"); - request.allow(buildDefaultChoices(typesInfo)); - return true; - } - - // If all permissions are DENY_ACTION or UNKNOWN_ACTION, call cancel() - // without prompting. - let checkDenyPermission = function(type) { - if (type.action == Ci.nsIPermissionManager.DENY_ACTION || - type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION) { - return true; - } - return false; - } - if (typesInfo.every(checkDenyPermission)) { - debug("all permission requests are denied"); - request.cancel(); - return true; - } - return false; - }, - - // multiple requests should be audio and video - checkMultipleRequest: function checkMultipleRequest(typesInfo) { - if (typesInfo.length == 1) { - return true; - } else if (typesInfo.length > 1) { - let checkIfAllowMultiRequest = function(type) { - return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1); - } - if (typesInfo.every(checkIfAllowMultiRequest)) { - debug("legal multiple requests"); - return true; - } - } - - return false; - }, - - handledByApp: function handledByApp(request, typesInfo) { - if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID || - request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) { - // This should not really happen - request.cancel(); - return true; - } - - let appsService = Cc["@mozilla.org/AppsService;1"] - .getService(Ci.nsIAppsService); - let app = appsService.getAppByLocalId(request.principal.appId); - - // Check each permission if it's denied by permission manager with app's - // URL. - let notDenyAppPrincipal = function(type) { - let url = Services.io.newURI(app.origin, null, null); - let principal = - secMan.createCodebasePrincipal(url, - {appId: request.principal.appId}); - let result = Services.perms.testExactPermissionFromPrincipal(principal, - type.access); - - if (result == Ci.nsIPermissionManager.ALLOW_ACTION || - result == Ci.nsIPermissionManager.PROMPT_ACTION) { - type.deny = false; - } - return !type.deny; - } - // Cancel the entire request if one of the requested permissions is denied - if (!typesInfo.every(notDenyAppPrincipal)) { - request.cancel(); - return true; - } - - return false; - }, - - handledByPermissionType: function handledByPermissionType(request, typesInfo) { - for (let i in typesInfo) { - if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) && - permissionSpecificChecker[typesInfo[i].permission](request)) { - return true; - } - } - - return false; - }, - - prompt: function(request) { - // Initialize the typesInfo and set the default value. - let typesInfo = []; - let perms = request.types.QueryInterface(Ci.nsIArray); - for (let idx = 0; idx < perms.length; idx++) { - let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType); - let tmp = { - permission: perm.type, - access: (perm.access && perm.access !== "unused") ? - perm.type + "-" + perm.access : perm.type, - options: [], - deny: true, - action: Ci.nsIPermissionManager.UNKNOWN_ACTION - }; - - // Append available options, if any. - let options = perm.options.QueryInterface(Ci.nsIArray); - for (let i = 0; i < options.length; i++) { - let option = options.queryElementAt(i, Ci.nsISupportsString).data; - tmp.options.push(option); - } - typesInfo.push(tmp); - } - - if (secMan.isSystemPrincipal(request.principal)) { - request.allow(buildDefaultChoices(typesInfo)); - return; - } - - - if (typesInfo.length == 0) { - request.cancel(); - return; - } - - if(!this.checkMultipleRequest(typesInfo)) { - request.cancel(); - return; - } - - if (this.handledByApp(request, typesInfo) || - this.handledByPermissionType(request, typesInfo)) { - return; - } - - // returns true if the request was handled - if (this.handleExistingPermission(request, typesInfo)) { - return; - } - - // prompt PROMPT_ACTION request or request with options. - typesInfo = typesInfo.filter(function(type) { - return !type.deny && (type.action == Ci.nsIPermissionManager.PROMPT_ACTION || type.options.length > 0) ; - }); - - if (!request.element) { - this.delegatePrompt(request, typesInfo); - return; - } - - var cancelRequest = function() { - request.requester.onVisibilityChange = null; - request.cancel(); - } - - var self = this; - - // If the request was initiated from a hidden iframe - // we don't forward it to content and cancel it right away - request.requester.getVisibility( { - notifyVisibility: function(isVisible) { - if (!isVisible) { - cancelRequest(); - return; - } - - // Monitor the frame visibility and cancel the request if the frame goes - // away but the request is still here. - request.requester.onVisibilityChange = { - notifyVisibility: function(isVisible) { - if (isVisible) - return; - - self.cancelPrompt(request, typesInfo); - cancelRequest(); - } - } - - self.delegatePrompt(request, typesInfo, function onCallback() { - request.requester.onVisibilityChange = null; - }); - } - }); - - }, - - cancelPrompt: function(request, typesInfo) { - this.sendToBrowserWindow("cancel-permission-prompt", request, - typesInfo); - }, - - delegatePrompt: function(request, typesInfo, callback) { - this.sendToBrowserWindow("permission-prompt", request, typesInfo, - function(type, remember, choices) { - if (type == "permission-allow") { - rememberPermission(typesInfo, request.principal, !remember); - if (callback) { - callback(); - } - request.allow(choices); - return; - } - - let addDenyPermission = function(type) { - debug("add " + type.permission + - " to permission manager with DENY_ACTION"); - if (remember) { - Services.perms.addFromPrincipal(request.principal, type.access, - Ci.nsIPermissionManager.DENY_ACTION); - } else if (PERMISSION_NO_SESSION.indexOf(type.access) < 0) { - Services.perms.addFromPrincipal(request.principal, type.access, - Ci.nsIPermissionManager.DENY_ACTION, - Ci.nsIPermissionManager.EXPIRE_SESSION, - 0); - } - } - try { - // This will trow if we are canceling because the remote process died. - // Just eat the exception and call the callback that will cleanup the - // visibility event listener. - typesInfo.forEach(addDenyPermission); - } catch(e) { } - - if (callback) { - callback(); - } - - try { - request.cancel(); - } catch(e) { } - }); - }, - - sendToBrowserWindow: function(type, request, typesInfo, callback) { - let requestId = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator).generateUUID().toString(); - if (callback) { - SystemAppProxy.addEventListener("mozContentEvent", function contentEvent(evt) { - let detail = evt.detail; - if (detail.id != requestId) - return; - SystemAppProxy.removeEventListener("mozContentEvent", contentEvent); - - callback(detail.type, detail.remember, detail.choices); - }) - } - - let principal = request.principal; - let isApp = principal.appStatus != Ci.nsIPrincipal.APP_STATUS_NOT_INSTALLED; - let remember = (principal.appStatus == Ci.nsIPrincipal.APP_STATUS_PRIVILEGED || - principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED) - ? true - : request.remember; - let isGranted = typesInfo.every(function(type) { - return type.action == Ci.nsIPermissionManager.ALLOW_ACTION; - }); - let permissions = {}; - for (let i in typesInfo) { - debug("prompt " + typesInfo[i].permission); - permissions[typesInfo[i].permission] = typesInfo[i].options; - } - - let details = { - type: type, - permissions: permissions, - id: requestId, - // This system app uses the origin from permission events to - // compare against the mozApp.origin of app windows, so we - // are not concerned with origin suffixes here (appId, etc). - origin: principal.originNoSuffix, - isApp: isApp, - remember: remember, - isGranted: isGranted, - }; - - if (isApp) { - details.manifestURL = DOMApplicationRegistry.getManifestURLByLocalId(principal.appId); - } - - // request.element is defined for OOP content, while request.window - // is defined for In-Process content. - // In both cases the message needs to be dispatched to the top-level - // <iframe mozbrowser> container in the system app. - // So the above code iterates over window.realFrameElement in order - // to crosss mozbrowser iframes boundaries and find the top-level - // one in the system app. - // window.realFrameElement will be |null| if the code try to cross - // content -> chrome boundaries. - let targetElement = request.element; - let targetWindow = request.window || targetElement.ownerDocument.defaultView; - while (targetWindow.realFrameElement) { - targetElement = targetWindow.realFrameElement; - targetWindow = targetElement.ownerDocument.defaultView; - } - - SystemAppProxy.dispatchEvent(details, targetElement); - }, - - classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]) -}; - -(function() { - // Do not allow GetUserMedia while in call. - permissionSpecificChecker["audio-capture"] = function(request) { - let forbid = false; - - if (forbid) { - request.cancel(); - } - - return forbid; - }; -})(); - -//module initialization -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]); diff --git a/b2g/components/ContentRequestHelper.jsm b/b2g/components/ContentRequestHelper.jsm deleted file mode 100644 index 14d8d250b..000000000 --- a/b2g/components/ContentRequestHelper.jsm +++ /dev/null @@ -1,68 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["ContentRequestHelper"]; - -const { interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "uuidgen", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -function debug(msg) { - // dump("ContentRequestHelper ** " + msg + "\n"); -} - -this.ContentRequestHelper = function() { -} - -ContentRequestHelper.prototype = { - - contentRequest: function(aContentEventName, aChromeEventName, - aInternalEventName, aData) { - let deferred = Promise.defer(); - - let id = uuidgen.generateUUID().toString(); - - SystemAppProxy.addEventListener(aContentEventName, - function onContentEvent(result) { - SystemAppProxy.removeEventListener(aContentEventName, - onContentEvent); - let msg = result.detail; - if (!msg || !msg.id || msg.id != id) { - deferred.reject("InternalErrorWrongContentEvent " + - JSON.stringify(msg)); - SystemAppProxy.removeEventListener(aContentEventName, - onContentEvent); - return; - } - - debug("Got content event " + JSON.stringify(msg)); - - if (msg.error) { - deferred.reject(msg.error); - } else { - deferred.resolve(msg.result); - } - }); - - let detail = { - eventName: aInternalEventName, - id: id, - data: aData - }; - debug("Send chrome event " + JSON.stringify(detail)); - SystemAppProxy._sendCustomEvent(aChromeEventName, detail); - - return deferred.promise; - } -}; diff --git a/b2g/components/DebuggerActors.js b/b2g/components/DebuggerActors.js deleted file mode 100644 index 318c46e68..000000000 --- a/b2g/components/DebuggerActors.js +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- / -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* 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/. */ - -"use strict"; - -const { Cu } = require("chrome"); -const DevToolsUtils = require("devtools/shared/DevToolsUtils"); -const promise = require("promise"); -const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm"); -const { BrowserTabList } = require("devtools/server/actors/webbrowser"); - -XPCOMUtils.defineLazyGetter(this, "Frames", function() { - const { Frames } = - Cu.import("resource://gre/modules/Frames.jsm", {}); - return Frames; -}); - -/** - * Unlike the original BrowserTabList which iterates over XUL windows, we - * override many portions to refer to Frames for the info needed here. - */ -function B2GTabList(connection) { - BrowserTabList.call(this, connection); - this._listening = false; -} - -B2GTabList.prototype = Object.create(BrowserTabList.prototype); - -B2GTabList.prototype._getBrowsers = function() { - return Frames.list().filter(frame => { - // Ignore app frames - return !frame.getAttribute("mozapp"); - }); -}; - -B2GTabList.prototype._getSelectedBrowser = function() { - return this._getBrowsers().find(frame => { - // Find the one visible browser (if any) - return !frame.classList.contains("hidden"); - }); -}; - -B2GTabList.prototype._checkListening = function() { - // The conditions from BrowserTabList are merged here, since we must listen to - // all events with our observer design. - this._listenForEventsIf(this._onListChanged && this._mustNotify || - this._actorByBrowser.size > 0); -}; - -B2GTabList.prototype._listenForEventsIf = function(shouldListen) { - if (this._listening != shouldListen) { - let op = shouldListen ? "addObserver" : "removeObserver"; - Frames[op](this); - this._listening = shouldListen; - } -}; - -B2GTabList.prototype.onFrameCreated = function(frame) { - let mozapp = frame.getAttribute("mozapp"); - if (mozapp) { - // Ignore app frames - return; - } - this._notifyListChanged(); - this._checkListening(); -}; - -B2GTabList.prototype.onFrameDestroyed = function(frame) { - let mozapp = frame.getAttribute("mozapp"); - if (mozapp) { - // Ignore app frames - return; - } - let actor = this._actorByBrowser.get(frame); - if (actor) { - this._handleActorClose(actor, frame); - } -}; - -exports.B2GTabList = B2GTabList; diff --git a/b2g/components/DirectoryProvider.js b/b2g/components/DirectoryProvider.js deleted file mode 100644 index a7dccd0c9..000000000 --- a/b2g/components/DirectoryProvider.js +++ /dev/null @@ -1,295 +0,0 @@ -/* 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/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -const XRE_OS_UPDATE_APPLY_TO_DIR = "OSUpdApplyToD" -const UPDATE_ARCHIVE_DIR = "UpdArchD" -const LOCAL_DIR = "/data/local"; -const UPDATES_DIR = "updates/0"; -const FOTA_DIR = "updates/fota"; -const COREAPPSDIR_PREF = "b2g.coreappsdir" - -XPCOMUtils.defineLazyServiceGetter(Services, "env", - "@mozilla.org/process/environment;1", - "nsIEnvironment"); - -XPCOMUtils.defineLazyServiceGetter(Services, "um", - "@mozilla.org/updates/update-manager;1", - "nsIUpdateManager"); - -XPCOMUtils.defineLazyServiceGetter(Services, "volumeService", - "@mozilla.org/telephony/volume-service;1", - "nsIVolumeService"); - -XPCOMUtils.defineLazyServiceGetter(this, "cpmm", - "@mozilla.org/childprocessmessagemanager;1", - "nsISyncMessageSender"); - -XPCOMUtils.defineLazyGetter(this, "gExtStorage", function dp_gExtStorage() { - return Services.env.get("EXTERNAL_STORAGE"); -}); - -// This exists to mark the affected code for bug 828858. -const gUseSDCard = true; - -const VERBOSE = 1; -var log = - VERBOSE ? - function log_dump(msg) { dump("DirectoryProvider: " + msg + "\n"); } : - function log_noop(msg) { }; - -function DirectoryProvider() { -} - -DirectoryProvider.prototype = { - classID: Components.ID("{9181eb7c-6f87-11e1-90b1-4f59d80dd2e5}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIDirectoryServiceProvider]), - _xpcom_factory: XPCOMUtils.generateSingletonFactory(DirectoryProvider), - - _profD: null, - - getFile: function(prop, persistent) { - if (AppConstants.platform === "gonk") { - return this.getFileOnGonk(prop, persistent); - } - return this.getFileNotGonk(prop, persistent); - }, - - getFileOnGonk: function(prop, persistent) { - let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir", - "permissionDBPDir", "UpdRootD"]; - if (localProps.indexOf(prop) != -1) { - let file = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsILocalFile) - file.initWithPath(LOCAL_DIR); - persistent.value = true; - return file; - } - if (prop == "ProfD") { - let dir = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsILocalFile); - dir.initWithPath(LOCAL_DIR+"/tests/profile"); - if (dir.exists()) { - persistent.value = true; - return dir; - } - } - if (prop == "coreAppsDir") { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) - file.initWithPath("/system/b2g"); - persistent.value = true; - return file; - } - if (prop == UPDATE_ARCHIVE_DIR) { - // getUpdateDir will set persistent to false since it may toggle between - // /data/local/ and /mnt/sdcard based on free space and/or availability - // of the sdcard. - // before download, check if free space is 2.1 times of update.mar - return this.getUpdateDir(persistent, UPDATES_DIR, 2.1); - } - if (prop == XRE_OS_UPDATE_APPLY_TO_DIR) { - // getUpdateDir will set persistent to false since it may toggle between - // /data/local/ and /mnt/sdcard based on free space and/or availability - // of the sdcard. - // before apply, check if free space is 1.1 times of update.mar - return this.getUpdateDir(persistent, FOTA_DIR, 1.1); - } - return null; - }, - - getFileNotGonk: function(prop, persistent) { - // In desktop builds, coreAppsDir is the same as the profile - // directory unless otherwise specified. We just need to get the - // path from the parent, and it is then used to build - // jar:remoteopenfile:// uris. - if (prop == "coreAppsDir") { - let coreAppsDirPref; - try { - coreAppsDirPref = Services.prefs.getCharPref(COREAPPSDIR_PREF); - } catch (e) { - // coreAppsDirPref may not exist if we're on an older version - // of gaia, so just fail silently. - } - let appsDir; - // If pref doesn't exist or isn't set, default to old value - if (!coreAppsDirPref || coreAppsDirPref == "") { - appsDir = Services.dirsvc.get("ProfD", Ci.nsIFile); - appsDir.append("webapps"); - } else { - appsDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) - appsDir.initWithPath(coreAppsDirPref); - } - persistent.value = true; - return appsDir; - } else if (prop == "ProfD") { - let inParent = Cc["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULRuntime) - .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; - if (inParent) { - // Just bail out to use the default from toolkit. - return null; - } - if (!this._profD) { - this._profD = cpmm.sendSyncMessage("getProfD", {})[0]; - } - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - file.initWithPath(this._profD); - persistent.value = true; - return file; - } - return null; - }, - - // The VolumeService only exists on the device, and not on desktop - volumeHasFreeSpace: function dp_volumeHasFreeSpace(volumePath, requiredSpace) { - if (!volumePath) { - return false; - } - if (!Services.volumeService) { - return false; - } - let volume = Services.volumeService.createOrGetVolumeByPath(volumePath); - if (!volume || volume.state !== Ci.nsIVolume.STATE_MOUNTED) { - return false; - } - let stat = volume.getStats(); - if (!stat) { - return false; - } - return requiredSpace <= stat.freeBytes; - }, - - findUpdateDirWithFreeSpace: function dp_findUpdateDirWithFreeSpace(requiredSpace, subdir) { - if (!Services.volumeService) { - return this.createUpdatesDir(LOCAL_DIR, subdir); - } - - let activeUpdate = Services.um.activeUpdate; - if (gUseSDCard) { - if (this.volumeHasFreeSpace(gExtStorage, requiredSpace)) { - let extUpdateDir = this.createUpdatesDir(gExtStorage, subdir); - if (extUpdateDir !== null) { - return extUpdateDir; - } - log("Warning: " + gExtStorage + " has enough free space for update " + - activeUpdate.name + ", but is not writable"); - } - } - - if (this.volumeHasFreeSpace(LOCAL_DIR, requiredSpace)) { - let localUpdateDir = this.createUpdatesDir(LOCAL_DIR, subdir); - if (localUpdateDir !== null) { - return localUpdateDir; - } - log("Warning: " + LOCAL_DIR + " has enough free space for update " + - activeUpdate.name + ", but is not writable"); - } - - return null; - }, - - getUpdateDir: function dp_getUpdateDir(persistent, subdir, multiple) { - let defaultUpdateDir = this.getDefaultUpdateDir(); - persistent.value = false; - - let activeUpdate = Services.um.activeUpdate; - if (!activeUpdate) { - log("Warning: No active update found, using default update dir: " + - defaultUpdateDir); - return defaultUpdateDir; - } - - let selectedPatch = activeUpdate.selectedPatch; - if (!selectedPatch) { - log("Warning: No selected patch, using default update dir: " + - defaultUpdateDir); - return defaultUpdateDir; - } - - let requiredSpace = selectedPatch.size * multiple; - let updateDir = this.findUpdateDirWithFreeSpace(requiredSpace, subdir); - if (updateDir) { - return updateDir; - } - - // If we've gotten this far, there isn't enough free space to download the patch - // on either external storage or /data/local. All we can do is report the - // error and let upstream code handle it more gracefully. - log("Error: No volume found with " + requiredSpace + " bytes for downloading"+ - " update " + activeUpdate.name); - activeUpdate.errorCode = Cr.NS_ERROR_FILE_TOO_BIG; - return null; - }, - - createUpdatesDir: function dp_createUpdatesDir(root, subdir) { - let dir = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsILocalFile); - dir.initWithPath(root); - if (!dir.isWritable()) { - log("Error: " + dir.path + " isn't writable"); - return null; - } - dir.appendRelativePath(subdir); - if (dir.exists()) { - if (dir.isDirectory() && dir.isWritable()) { - return dir; - } - // subdir is either a file or isn't writable. In either case we - // can't use it. - log("Error: " + dir.path + " is a file or isn't writable"); - return null; - } - // subdir doesn't exist, and the parent is writable, so try to - // create it. This can fail if a file named updates exists. - try { - dir.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt('0770', 8)); - } catch (e) { - // The create failed for some reason. We can't use it. - log("Error: " + dir.path + " unable to create directory"); - return null; - } - return dir; - }, - - getDefaultUpdateDir: function dp_getDefaultUpdateDir() { - let path = gExtStorage; - if (!path) { - path = LOCAL_DIR; - } - - if (Services.volumeService) { - let extVolume = Services.volumeService.createOrGetVolumeByPath(path); - if (!extVolume) { - path = LOCAL_DIR; - } - } - - let dir = Cc["@mozilla.org/file/local;1"] - .createInstance(Ci.nsILocalFile) - dir.initWithPath(path); - - if (!dir.exists() && path != LOCAL_DIR) { - // Fallback to LOCAL_DIR if we didn't fallback earlier - dir.initWithPath(LOCAL_DIR); - - if (!dir.exists()) { - throw Cr.NS_ERROR_FILE_NOT_FOUND; - } - } - - dir.appendRelativePath("updates"); - return dir; - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DirectoryProvider]); diff --git a/b2g/components/ErrorPage.jsm b/b2g/components/ErrorPage.jsm deleted file mode 100644 index 2c0c64c21..000000000 --- a/b2g/components/ErrorPage.jsm +++ /dev/null @@ -1,187 +0,0 @@ -/* 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/. */ - -'use strict'; - -this.EXPORTED_SYMBOLS = ['ErrorPage']; - -const Cu = Components.utils; -const Cc = Components.classes; -const Ci = Components.interfaces; -const kErrorPageFrameScript = 'chrome://b2g/content/ErrorPage.js'; - -Cu.import('resource://gre/modules/Services.jsm'); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyGetter(this, "CertOverrideService", function () { - return Cc["@mozilla.org/security/certoverride;1"] - .getService(Ci.nsICertOverrideService); -}); - -/** - * A class to add exceptions to override SSL certificate problems. - * The functionality itself is borrowed from exceptionDialog.js. - */ -function SSLExceptions(aCallback, aUri, aWindow) { - this._finishCallback = aCallback; - this._uri = aUri; - this._window = aWindow; -}; - -SSLExceptions.prototype = { - _finishCallback: null, - _window: null, - _uri: null, - _temporary: null, - _sslStatus: null, - - getInterface: function SSLE_getInterface(aIID) { - return this.QueryInterface(aIID); - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2]), - - /** - * To collect the SSL status we intercept the certificate error here - * and store the status for later use. - */ - notifyCertProblem: function SSLE_notifyCertProblem(aSocketInfo, - aSslStatus, - aTargetHost) { - this._sslStatus = aSslStatus.QueryInterface(Ci.nsISSLStatus); - Services.tm.currentThread.dispatch({ - run: this._addOverride.bind(this) - }, Ci.nsIThread.DISPATCH_NORMAL); - return true; // suppress error UI - }, - - /** - * Attempt to download the certificate for the location specified to get - * the SSLState for the certificate and the errors. - */ - _checkCert: function SSLE_checkCert() { - this._sslStatus = null; - if (!this._uri) { - return; - } - let req = new this._window.XMLHttpRequest(); - try { - req.open("GET", this._uri.prePath, true); - req.channel.notificationCallbacks = this; - let xhrHandler = (function() { - req.removeEventListener("load", xhrHandler); - req.removeEventListener("error", xhrHandler); - if (!this._sslStatus) { - // Got response from server without an SSL error. - if (this._finishCallback) { - this._finishCallback(); - } - } - }).bind(this); - req.addEventListener("load", xhrHandler); - req.addEventListener("error", xhrHandler); - req.send(null); - } catch (e) { - // We *expect* exceptions if there are problems with the certificate - // presented by the site. Log it, just in case, but we can proceed here, - // with appropriate sanity checks - Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " + - "This results in a (mostly harmless) exception being thrown. " + - "Logged for information purposes only: " + e); - } - }, - - /** - * Internal method to create an override. - */ - _addOverride: function SSLE_addOverride() { - let SSLStatus = this._sslStatus; - let uri = this._uri; - let flags = 0; - - if (SSLStatus.isUntrusted) { - flags |= Ci.nsICertOverrideService.ERROR_UNTRUSTED; - } - if (SSLStatus.isDomainMismatch) { - flags |= Ci.nsICertOverrideService.ERROR_MISMATCH; - } - if (SSLStatus.isNotValidAtThisTime) { - flags |= Ci.nsICertOverrideService.ERROR_TIME; - } - - CertOverrideService.rememberValidityOverride( - uri.asciiHost, - uri.port, - SSLStatus.serverCert, - flags, - this._temporary); - - if (this._finishCallback) { - this._finishCallback(); - } - }, - - /** - * Creates a permanent exception to override all overridable errors for - * the given URL. - */ - addException: function SSLE_addException(aTemporary) { - this._temporary = aTemporary; - this._checkCert(); - } -}; - -var ErrorPage = { - _addCertException: function(aMessage) { - let frameLoaderOwner = aMessage.target.QueryInterface(Ci.nsIFrameLoaderOwner); - let win = frameLoaderOwner.ownerDocument.defaultView; - let mm = frameLoaderOwner.frameLoader.messageManager; - - let uri = Services.io.newURI(aMessage.data.url, null, null); - let sslExceptions = new SSLExceptions((function() { - mm.sendAsyncMessage('ErrorPage:ReloadPage'); - }).bind(this), uri, win); - try { - sslExceptions.addException(!aMessage.data.isPermanent); - } catch (e) { - dump("Failed to set cert exception: " + e + "\n"); - } - }, - - _listenError: function(frameLoader) { - let self = this; - let frameElement = frameLoader.ownerElement; - let injectErrorPageScript = function() { - let mm = frameLoader.messageManager; - try { - mm.loadFrameScript(kErrorPageFrameScript, true, true); - } catch (e) { - dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n'); - } - mm.addMessageListener('ErrorPage:AddCertException', self._addCertException.bind(self)); - frameElement.removeEventListener('mozbrowsererror', injectErrorPageScript, true); - }; - - frameElement.addEventListener('mozbrowsererror', - injectErrorPageScript, - true // use capture - ); - }, - - init: function errorPageInit() { - Services.obs.addObserver(this, 'inprocess-browser-shown', false); - Services.obs.addObserver(this, 'remote-browser-shown', false); - }, - - observe: function errorPageObserve(aSubject, aTopic, aData) { - let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader); - // Ignore notifications that aren't from a BrowserOrApp - if (!frameLoader.ownerIsMozBrowserOrAppFrame) { - return; - } - this._listenError(frameLoader); - } -}; - -ErrorPage.init(); diff --git a/b2g/components/FilePicker.js b/b2g/components/FilePicker.js deleted file mode 100644 index 803eef681..000000000 --- a/b2g/components/FilePicker.js +++ /dev/null @@ -1,223 +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/. */ - -/* - * No magic constructor behaviour, as is de rigeur for XPCOM. - * If you must perform some initialization, and it could possibly fail (even - * due to an out-of-memory condition), you should use an Init method, which - * can convey failure appropriately (thrown exception in JS, - * NS_FAILED(nsresult) return in C++). - * - * In JS, you can actually cheat, because a thrown exception will cause the - * CreateInstance call to fail in turn, but not all languages are so lucky. - * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code - * for portability reasons -- and even when you're building completely - * platform-specific code, you can't throw across an XPCOM method boundary.) - */ - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -// FIXME: improve this list of filters. -const IMAGE_FILTERS = ['image/gif', 'image/jpeg', 'image/pjpeg', - 'image/png', 'image/svg+xml', 'image/tiff', - 'image/vnd.microsoft.icon']; -const VIDEO_FILTERS = ['video/mpeg', 'video/mp4', 'video/ogg', - 'video/quicktime', 'video/webm', 'video/x-matroska', - 'video/x-ms-wmv', 'video/x-flv']; -const AUDIO_FILTERS = ['audio/basic', 'audio/L24', 'audio/mp4', - 'audio/mpeg', 'audio/ogg', 'audio/vorbis', - 'audio/vnd.rn-realaudio', 'audio/vnd.wave', - 'audio/webm']; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, 'cpmm', - '@mozilla.org/childprocessmessagemanager;1', - 'nsIMessageSender'); - -function FilePicker() { -} - -FilePicker.prototype = { - classID: Components.ID('{436ff8f9-0acc-4b11-8ec7-e293efba3141}'), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]), - - /* members */ - - mParent: undefined, - mExtraProps: undefined, - mFilterTypes: undefined, - mFileEnumerator: undefined, - mFilePickerShownCallback: undefined, - - /* methods */ - - init: function(parent, title, mode) { - this.mParent = parent; - this.mExtraProps = {}; - this.mFilterTypes = []; - this.mMode = mode; - - if (mode != Ci.nsIFilePicker.modeOpen && - mode != Ci.nsIFilePicker.modeOpenMultiple) { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - } - }, - - /* readonly attribute nsILocalFile file - not implemented; */ - /* readonly attribute nsISimpleEnumerator files - not implemented; */ - /* readonly attribute nsIURI fileURL - not implemented; */ - - get domFileOrDirectoryEnumerator() { - return this.mFilesEnumerator; - }, - - // We don't support directory selection yet. - get domFileOrDirectory() { - return this.mFilesEnumerator ? this.mFilesEnumerator.mFiles[0] : null; - }, - - get mode() { - return this.mMode; - }, - - appendFilters: function(filterMask) { - // Ci.nsIFilePicker.filterHTML is not supported - // Ci.nsIFilePicker.filterText is not supported - - if (filterMask & Ci.nsIFilePicker.filterImages) { - this.mFilterTypes = this.mFilterTypes.concat(IMAGE_FILTERS); - // This property is needed for the gallery app pick activity. - this.mExtraProps['nocrop'] = true; - } - - // Ci.nsIFilePicker.filterXML is not supported - // Ci.nsIFilePicker.filterXUL is not supported - // Ci.nsIFilePicker.filterApps is not supported - // Ci.nsIFilePicker.filterAllowURLs is not supported - - if (filterMask & Ci.nsIFilePicker.filterVideo) { - this.mFilterTypes = this.mFilterTypes.concat(VIDEO_FILTERS); - } - - if (filterMask & Ci.nsIFilePicker.filterAudio) { - this.mFilterTypes = this.mFilterTypes.concat(AUDIO_FILTERS); - } - - if (filterMask & Ci.nsIFilePicker.filterAll) { - // This property is needed for the gallery app pick activity. - this.mExtraProps['nocrop'] = true; - } - }, - - appendFilter: function(title, extensions) { - // pick activity doesn't support extensions - }, - - open: function(aFilePickerShownCallback) { - this.mFilePickerShownCallback = aFilePickerShownCallback; - - cpmm.addMessageListener('file-picked', this); - - let detail = {}; - if (this.mFilterTypes) { - detail.type = this.mFilterTypes; - } - - for (let prop in this.mExtraProps) { - if (!(prop in detail)) { - detail[prop] = this.mExtraProps[prop]; - } - } - - cpmm.sendAsyncMessage('file-picker', detail); - }, - - fireSuccess: function(file) { - this.mFilesEnumerator = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]), - - mFiles: [file], - mIndex: 0, - - hasMoreElements: function() { - return (this.mIndex < this.mFiles.length); - }, - - getNext: function() { - if (this.mIndex >= this.mFiles.length) { - throw Components.results.NS_ERROR_FAILURE; - } - return this.mFiles[this.mIndex++]; - } - }; - - if (this.mFilePickerShownCallback) { - this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnOK); - this.mFilePickerShownCallback = null; - } - }, - - fireError: function() { - if (this.mFilePickerShownCallback) { - this.mFilePickerShownCallback.done(Ci.nsIFilePicker.returnCancel); - this.mFilePickerShownCallback = null; - } - }, - - receiveMessage: function(message) { - if (message.name !== 'file-picked') { - return; - } - - cpmm.removeMessageListener('file-picked', this); - - let data = message.data; - if (!data.success || !data.result.blob) { - this.fireError(); - return; - } - - // The name to be shown can be part of the message, or can be taken from - // the File (if the blob is a File). - let name = data.result.name; - if (!name && - (data.result.blob instanceof this.mParent.File) && - data.result.blob.name) { - name = data.result.blob.name; - } - - // Let's try to remove the full path and take just the filename. - if (name) { - let names = OS.Path.split(name); - name = names.components[names.components.length - 1]; - } - - // the fallback is a filename composed by 'blob' + extension. - if (!name) { - name = 'blob'; - if (data.result.blob.type) { - let mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); - let mimeInfo = mimeSvc.getFromTypeAndExtension(data.result.blob.type, ''); - if (mimeInfo) { - name += '.' + mimeInfo.primaryExtension; - } - } - } - - let file = new this.mParent.File([data.result.blob], - name, - { type: data.result.blob.type }); - - if (file) { - this.fireSuccess(file); - } else { - this.fireError(); - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FilePicker]); diff --git a/b2g/components/Frames.jsm b/b2g/components/Frames.jsm deleted file mode 100644 index 0eb00cb4c..000000000 --- a/b2g/components/Frames.jsm +++ /dev/null @@ -1,146 +0,0 @@ -/* 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/. */ - -'use strict'; - -this.EXPORTED_SYMBOLS = ['Frames']; - -const Cu = Components.utils; -const Ci = Components.interfaces; - -Cu.import('resource://gre/modules/Services.jsm'); -Cu.import('resource://gre/modules/SystemAppProxy.jsm'); - -const listeners = []; - -const Observer = { - // Save a map of (MessageManager => Frame) to be able to dispatch - // the FrameDestroyed event with a frame reference. - _frames: new Map(), - - // Also save current number of iframes opened by app - _apps: new Map(), - - start: function () { - Services.obs.addObserver(this, 'remote-browser-shown', false); - Services.obs.addObserver(this, 'inprocess-browser-shown', false); - Services.obs.addObserver(this, 'message-manager-close', false); - - SystemAppProxy.getFrames().forEach(frame => { - let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager; - this._frames.set(mm, frame); - let mozapp = frame.getAttribute('mozapp'); - if (mozapp) { - this._apps.set(mozapp, (this._apps.get(mozapp) || 0) + 1); - } - }); - }, - - stop: function () { - Services.obs.removeObserver(this, 'remote-browser-shown'); - Services.obs.removeObserver(this, 'inprocess-browser-shown'); - Services.obs.removeObserver(this, 'message-manager-close'); - this._frames.clear(); - this._apps.clear(); - }, - - observe: function (subject, topic, data) { - switch(topic) { - - // Listen for frame creation in OOP (device) as well as in parent process (b2g desktop) - case 'remote-browser-shown': - case 'inprocess-browser-shown': - let frameLoader = subject; - - // get a ref to the app <iframe> - frameLoader.QueryInterface(Ci.nsIFrameLoader); - let frame = frameLoader.ownerElement; - let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager; - this.onMessageManagerCreated(mm, frame); - break; - - // Every time an iframe is destroyed, its message manager also is - case 'message-manager-close': - this.onMessageManagerDestroyed(subject); - break; - } - }, - - onMessageManagerCreated: function (mm, frame) { - this._frames.set(mm, frame); - - let isFirstAppFrame = null; - let mozapp = frame.getAttribute('mozapp'); - if (mozapp) { - let count = (this._apps.get(mozapp) || 0) + 1; - this._apps.set(mozapp, count); - isFirstAppFrame = (count === 1); - } - - listeners.forEach(function (listener) { - try { - listener.onFrameCreated(frame, isFirstAppFrame); - } catch(e) { - dump('Exception while calling Frames.jsm listener:' + e + '\n' + - e.stack + '\n'); - } - }); - }, - - onMessageManagerDestroyed: function (mm) { - let frame = this._frames.get(mm); - if (!frame) { - // We received an event for an unknown message manager - return; - } - - this._frames.delete(mm); - - let isLastAppFrame = null; - let mozapp = frame.getAttribute('mozapp'); - if (mozapp) { - let count = (this._apps.get(mozapp) || 0) - 1; - this._apps.set(mozapp, count); - isLastAppFrame = (count === 0); - } - - listeners.forEach(function (listener) { - try { - listener.onFrameDestroyed(frame, isLastAppFrame); - } catch(e) { - dump('Exception while calling Frames.jsm listener:' + e + '\n' + - e.stack + '\n'); - } - }); - } - -}; - -var Frames = this.Frames = { - - list: () => SystemAppProxy.getFrames(), - - addObserver: function (listener) { - if (listeners.indexOf(listener) !== -1) { - return; - } - - listeners.push(listener); - if (listeners.length == 1) { - Observer.start(); - } - }, - - removeObserver: function (listener) { - let idx = listeners.indexOf(listener); - if (idx !== -1) { - listeners.splice(idx, 1); - } - if (listeners.length === 0) { - Observer.stop(); - } - } - -}; - diff --git a/b2g/components/FxAccountsMgmtService.jsm b/b2g/components/FxAccountsMgmtService.jsm deleted file mode 100644 index e51f46ed7..000000000 --- a/b2g/components/FxAccountsMgmtService.jsm +++ /dev/null @@ -1,173 +0,0 @@ -/* 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/. */ - -/** - * Some specific (certified) apps need to get access to certain Firefox Accounts - * functionality that allows them to manage accounts (this is mostly sign up, - * sign in, logout and delete) and get information about the currently existing - * ones. - * - * This service listens for requests coming from these apps, triggers the - * appropriate Fx Accounts flows and send reponses back to the UI. - * - * The communication mechanism is based in mozFxAccountsContentEvent (for - * messages coming from the UI) and mozFxAccountsChromeEvent (for messages - * sent from the chrome side) custom events. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["FxAccountsMgmtService"]; - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/FxAccountsCommon.js"); - -XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager", - "resource://gre/modules/FxAccountsManager.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -this.FxAccountsMgmtService = { - _onFulfill: function(aMsgId, aData) { - SystemAppProxy._sendCustomEvent("mozFxAccountsChromeEvent", { - id: aMsgId, - data: aData ? aData : null - }); - }, - - _onReject: function(aMsgId, aReason) { - SystemAppProxy._sendCustomEvent("mozFxAccountsChromeEvent", { - id: aMsgId, - error: aReason ? aReason : null - }); - }, - - init: function() { - Services.obs.addObserver(this, ONLOGIN_NOTIFICATION, false); - Services.obs.addObserver(this, ONVERIFIED_NOTIFICATION, false); - Services.obs.addObserver(this, ONLOGOUT_NOTIFICATION, false); - SystemAppProxy.addEventListener("mozFxAccountsContentEvent", - FxAccountsMgmtService); - }, - - observe: function(aSubject, aTopic, aData) { - log.debug("Observed " + aTopic); - switch (aTopic) { - case ONLOGIN_NOTIFICATION: - case ONVERIFIED_NOTIFICATION: - case ONLOGOUT_NOTIFICATION: - // FxAccounts notifications have the form of fxaccounts:* - SystemAppProxy._sendCustomEvent("mozFxAccountsUnsolChromeEvent", { - eventName: aTopic.substring(aTopic.indexOf(":") + 1) - }); - break; - } - }, - - handleEvent: function(aEvent) { - let msg = aEvent.detail; - log.debug("MgmtService got content event: " + JSON.stringify(msg)); - let self = FxAccountsMgmtService; - - if (!msg.id) { - return; - } - - if (msg.error) { - self._onReject(msg.id, msg.error); - return; - } - - let data = msg.data; - if (!data) { - return; - } - // Backwards compatibility: handle accountId coming from Gaia - if (data.accountId && typeof(data.email === "undefined")) { - data.email = data.accountId; - delete data.accountId; - } - - // Bug 1202450 dirty hack because Gaia is sending getAccounts. - if (data.method == "getAccounts") { - data.method = "getAccount"; - } - - switch(data.method) { - case "getAssertion": - let principal = Services.scriptSecurityManager.getSystemPrincipal(); - let audience = data.audience || principal.originNoSuffix; - FxAccountsManager.getAssertion(audience, principal, { - silent: msg.silent || false - }).then(result => { - self._onFulfill(msg.id, result); - }, reason => { - self._onReject(msg.id, reason); - }); - break; - case "getAccount": - case "getKeys": - FxAccountsManager[data.method]().then( - result => { - // For the getAccounts case, we only expose the email and - // verification status so far. - self._onFulfill(msg.id, result); - }, - reason => { - self._onReject(msg.id, reason); - } - ).then(null, Components.utils.reportError); - break; - case "logout": - FxAccountsManager.signOut().then( - () => { - self._onFulfill(msg.id); - }, - reason => { - self._onReject(msg.id, reason); - } - ).then(null, Components.utils.reportError); - break; - case "queryAccount": - FxAccountsManager.queryAccount(data.email).then( - result => { - self._onFulfill(msg.id, result); - }, - reason => { - self._onReject(msg.id, reason); - } - ).then(null, Components.utils.reportError); - break; - case "resendVerificationEmail": - FxAccountsManager.resendVerificationEmail().then( - () => { - self._onFulfill(msg.id); - }, - reason => { - self._onReject(msg.id, reason); - } - ).then(null, Components.utils.reportError); - break; - case "signIn": - case "signUp": - case "refreshAuthentication": - FxAccountsManager[data.method](data.email, data.password, - data.fetchKeys).then( - user => { - self._onFulfill(msg.id, user); - }, - reason => { - self._onReject(msg.id, reason); - } - ).then(null, Components.utils.reportError); - break; - } - } -}; - -FxAccountsMgmtService.init(); diff --git a/b2g/components/FxAccountsUIGlue.js b/b2g/components/FxAccountsUIGlue.js deleted file mode 100644 index d62a7d14f..000000000 --- a/b2g/components/FxAccountsUIGlue.js +++ /dev/null @@ -1,39 +0,0 @@ -/* 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/. */ - -"use strict" - -const { interfaces: Ci, utils: Cu } = Components; - -Cu.import("resource://gre/modules/FxAccountsCommon.js"); -Cu.import("resource://gre/modules/ContentRequestHelper.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -function FxAccountsUIGlue() { -} - -FxAccountsUIGlue.prototype = { - - __proto__: ContentRequestHelper.prototype, - - signInFlow: function() { - return this.contentRequest("mozFxAccountsRPContentEvent", - "mozFxAccountsUnsolChromeEvent", - "openFlow"); - }, - - refreshAuthentication: function(aEmail) { - return this.contentRequest("mozFxAccountsRPContentEvent", - "mozFxAccountsUnsolChromeEvent", - "refreshAuthentication", { - email: aEmail - }); - }, - - classID: Components.ID("{51875c14-91d7-4b8c-b65d-3549e101228c}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIFxAccountsUIGlue]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FxAccountsUIGlue]); diff --git a/b2g/components/GaiaChrome.cpp b/b2g/components/GaiaChrome.cpp deleted file mode 100644 index 2b53750c2..000000000 --- a/b2g/components/GaiaChrome.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* 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/. */ - -#include "GaiaChrome.h" - -#include "nsAppDirectoryServiceDefs.h" -#include "nsChromeRegistry.h" -#include "nsDirectoryServiceDefs.h" -#include "nsLocalFile.h" -#include "nsXULAppAPI.h" - -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/ModuleUtils.h" -#include "mozilla/Services.h" -#include "mozilla/FileLocation.h" - -#define NS_GAIACHROME_CID \ - { 0x83f8f999, 0x6b87, 0x4dd8, { 0xa0, 0x93, 0x72, 0x0b, 0xfb, 0x67, 0x4d, 0x38 } } - -using namespace mozilla; - -StaticRefPtr<GaiaChrome> gGaiaChrome; - -NS_IMPL_ISUPPORTS(GaiaChrome, nsIGaiaChrome) - -GaiaChrome::GaiaChrome() - : mPackageName(NS_LITERAL_CSTRING("gaia")) - , mAppsDir(NS_LITERAL_STRING("apps")) - , mDataRoot(NS_LITERAL_STRING("/data/local")) - , mSystemRoot(NS_LITERAL_STRING("/system/b2g")) -{ - MOZ_ASSERT(NS_IsMainThread()); - - GetProfileDir(); - Register(); -} - -//virtual -GaiaChrome::~GaiaChrome() -{ -} - -nsresult -GaiaChrome::GetProfileDir() -{ - nsCOMPtr<nsIFile> profDir; - nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, - getter_AddRefs(profDir)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = profDir->Clone(getter_AddRefs(mProfDir)); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -nsresult -GaiaChrome::ComputeAppsPath(nsIFile* aPath) -{ -#if defined(MOZ_MULET) - aPath->InitWithFile(mProfDir); -#elif defined(MOZ_WIDGET_GONK) - nsCOMPtr<nsIFile> locationDetection = new nsLocalFile(); - locationDetection->InitWithPath(mSystemRoot); - locationDetection->Append(mAppsDir); - bool appsInSystem = EnsureIsDirectory(locationDetection); - locationDetection->InitWithPath(mDataRoot); - locationDetection->Append(mAppsDir); - bool appsInData = EnsureIsDirectory(locationDetection); - - if (!appsInData && !appsInSystem) { - printf_stderr("!!! NO root directory with apps found\n"); - MOZ_ASSERT(false); - return NS_ERROR_UNEXPECTED; - } - - aPath->InitWithPath(appsInData ? mDataRoot : mSystemRoot); -#else - return NS_ERROR_UNEXPECTED; -#endif - - aPath->Append(mAppsDir); - aPath->Append(NS_LITERAL_STRING(".")); - - nsresult rv = EnsureValidPath(aPath); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; -} - -bool -GaiaChrome::EnsureIsDirectory(nsIFile* aPath) -{ - bool isDir = false; - aPath->IsDirectory(&isDir); - return isDir; -} - -nsresult -GaiaChrome::EnsureValidPath(nsIFile* appsDir) -{ - // Ensure there is a valid "apps/system" directory - nsCOMPtr<nsIFile> systemAppDir = new nsLocalFile(); - systemAppDir->InitWithFile(appsDir); - systemAppDir->Append(NS_LITERAL_STRING("system")); - - bool hasSystemAppDir = EnsureIsDirectory(systemAppDir); - if (!hasSystemAppDir) { - nsCString path; appsDir->GetNativePath(path); - // We don't want to continue if the apps path does not exists ... - printf_stderr("!!! Gaia chrome package is not a directory: %s\n", path.get()); - return NS_ERROR_UNEXPECTED; - } - - return NS_OK; -} - -NS_IMETHODIMP -GaiaChrome::Register() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(nsChromeRegistry::gChromeRegistry != nullptr); - - nsCOMPtr<nsIFile> aPath = new nsLocalFile(); - nsresult rv = ComputeAppsPath(aPath); - NS_ENSURE_SUCCESS(rv, rv); - - FileLocation appsLocation(aPath); - nsCString uri; - appsLocation.GetURIString(uri); - - char* argv[2]; - argv[0] = (char*)mPackageName.get(); - argv[1] = (char*)uri.get(); - - nsChromeRegistry::ManifestProcessingContext cx(NS_APP_LOCATION, appsLocation); - nsChromeRegistry::gChromeRegistry->ManifestContent(cx, 0, argv, 0); - - return NS_OK; -} - -already_AddRefed<GaiaChrome> -GaiaChrome::FactoryCreate() -{ - if (!XRE_IsParentProcess()) { - return nullptr; - } - - MOZ_ASSERT(NS_IsMainThread()); - - if (!gGaiaChrome) { - gGaiaChrome = new GaiaChrome(); - ClearOnShutdown(&gGaiaChrome); - } - - RefPtr<GaiaChrome> service = gGaiaChrome.get(); - return service.forget(); -} - -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GaiaChrome, - GaiaChrome::FactoryCreate) - -NS_DEFINE_NAMED_CID(NS_GAIACHROME_CID); - -static const mozilla::Module::CIDEntry kGaiaChromeCIDs[] = { - { &kNS_GAIACHROME_CID, false, nullptr, GaiaChromeConstructor }, - { nullptr } -}; - -static const mozilla::Module::ContractIDEntry kGaiaChromeContracts[] = { - { "@mozilla.org/b2g/gaia-chrome;1", &kNS_GAIACHROME_CID }, - { nullptr } -}; - -static const mozilla::Module::CategoryEntry kGaiaChromeCategories[] = { - { "profile-after-change", "Gaia Chrome Registration", GAIACHROME_CONTRACTID }, - { nullptr } -}; - -static const mozilla::Module kGaiaChromeModule = { - mozilla::Module::kVersion, - kGaiaChromeCIDs, - kGaiaChromeContracts, - kGaiaChromeCategories -}; - -NSMODULE_DEFN(GaiaChromeModule) = &kGaiaChromeModule; diff --git a/b2g/components/GaiaChrome.h b/b2g/components/GaiaChrome.h deleted file mode 100644 index 290613b81..000000000 --- a/b2g/components/GaiaChrome.h +++ /dev/null @@ -1,44 +0,0 @@ -/* 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/. */ - -#ifndef __GAIACHROME_H__ -#define __GAIACHROME_H__ - -#include "nsIGaiaChrome.h" - -#include "nsIFile.h" - -#include "nsCOMPtr.h" -#include "nsString.h" - -using namespace mozilla; - -class GaiaChrome final : public nsIGaiaChrome -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIGAIACHROME - - static already_AddRefed<GaiaChrome> - FactoryCreate(); - -private: - nsCString mPackageName; - - nsAutoString mAppsDir; - nsAutoString mDataRoot; - nsAutoString mSystemRoot; - - nsCOMPtr<nsIFile> mProfDir; - - GaiaChrome(); - ~GaiaChrome(); - - nsresult ComputeAppsPath(nsIFile*); - bool EnsureIsDirectory(nsIFile*); - nsresult EnsureValidPath(nsIFile*); - nsresult GetProfileDir(); -}; - -#endif // __GAIACHROME_H__ diff --git a/b2g/components/GlobalSimulatorScreen.jsm b/b2g/components/GlobalSimulatorScreen.jsm deleted file mode 100644 index 2895aef96..000000000 --- a/b2g/components/GlobalSimulatorScreen.jsm +++ /dev/null @@ -1,90 +0,0 @@ -/* 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/. */ - -this.EXPORTED_SYMBOLS = [ 'GlobalSimulatorScreen' ]; - -const Cu = Components.utils; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/Services.jsm'); - -this.GlobalSimulatorScreen = { - mozOrientationLocked: false, - - // Actual orientation of apps - mozOrientation: 'portrait', - - // The restricted list of actual orientation that can be used - // if mozOrientationLocked is true - lockedOrientation: [], - - // The faked screen orientation - // if screenOrientation doesn't match mozOrientation due - // to lockedOrientation restriction, the app will be displayed - // on the side on desktop - screenOrientation: 'portrait', - - // Updated by screen.js - width: 0, height: 0, - - lock: function(orientation) { - this.mozOrientationLocked = true; - - // Normalize to portrait or landscape, - // i.e. the possible values of screenOrientation - function normalize(str) { - if (str.match(/^portrait/)) { - return 'portrait'; - } else if (str.match(/^landscape/)) { - return 'landscape'; - } else { - return 'portrait'; - } - } - this.lockedOrientation = orientation.map(normalize); - - this.updateOrientation(); - }, - - unlock: function() { - this.mozOrientationLocked = false; - this.updateOrientation(); - }, - - updateOrientation: function () { - let orientation = this.screenOrientation; - - // If the orientation is locked, we have to ensure ending up with a value - // of lockedOrientation. If none of lockedOrientation values matches - // the screen orientation we just choose the first locked orientation. - // This will be the precise scenario where the app is displayed on the - // side on desktop! - if (this.mozOrientationLocked && - this.lockedOrientation.indexOf(this.screenOrientation) == -1) { - orientation = this.lockedOrientation[0]; - } - - // If the actual orientation changed, - // we have to fire mozorientation DOM events - if (this.mozOrientation != orientation) { - this.mozOrientation = orientation; - - // Notify each app screen object to fire the event - Services.obs.notifyObservers(null, 'simulator-orientation-change', null); - } - - // Finally, in any case, we update the window size and orientation - // (Use wrappedJSObject trick to be able to pass a raw JS object) - Services.obs.notifyObservers({wrappedJSObject:this}, 'simulator-adjust-window-size', null); - }, - - flipScreen: function() { - if (this.screenOrientation == 'portrait') { - this.screenOrientation = 'landscape'; - } else if (this.screenOrientation == 'landscape') { - this.screenOrientation = 'portrait'; - } - this.updateOrientation(); - } -} diff --git a/b2g/components/HelperAppDialog.js b/b2g/components/HelperAppDialog.js deleted file mode 100644 index 3709833e1..000000000 --- a/b2g/components/HelperAppDialog.js +++ /dev/null @@ -1,115 +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/. */ - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", - "resource://gre/modules/Downloads.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -// ----------------------------------------------------------------------- -// HelperApp Launcher Dialog -// -// For now on b2g we never prompt and just download to the default -// location. -// -// ----------------------------------------------------------------------- - -function HelperAppLauncherDialog() { } - -HelperAppLauncherDialog.prototype = { - classID: Components.ID("{710322af-e6ae-4b0c-b2c9-1474a87b077e}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog]), - - show: function(aLauncher, aContext, aReason) { - aLauncher.MIMEInfo.preferredAction = Ci.nsIMIMEInfo.saveToDisk; - aLauncher.saveToDisk(null, false); - }, - - promptForSaveToFileAsync: function(aLauncher, - aContext, - aDefaultFile, - aSuggestedFileExt, - aForcePrompt) { - // Retrieve the user's default download directory. - Task.spawn(function*() { - let file = null; - try { - let defaultFolder = yield Downloads.getPreferredDownloadsDirectory(); - let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - dir.initWithPath(defaultFolder); - file = this.validateLeafName(dir, aDefaultFile, aSuggestedFileExt); - } catch(e) { } - aLauncher.saveDestinationAvailable(file); - }.bind(this)).then(null, Cu.reportError); - }, - - validateLeafName: function(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(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 makeFileUnique: " + 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(aDirectory) { - return aDirectory.exists() && - aDirectory.isDirectory() && - aDirectory.isWritable(); - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([HelperAppLauncherDialog]); diff --git a/b2g/components/LogCapture.jsm b/b2g/components/LogCapture.jsm deleted file mode 100644 index 803028d57..000000000 --- a/b2g/components/LogCapture.jsm +++ /dev/null @@ -1,221 +0,0 @@ -/* 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/. */ -/* jshint moz: true */ -/* global Uint8Array, Components, dump */ - -"use strict"; - -const Cu = Components.utils; -const Ci = Components.interfaces; -const Cc = Components.classes; - -Cu.importGlobalProperties(['FileReader']); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Screenshot", "resource://gre/modules/Screenshot.jsm"); - -this.EXPORTED_SYMBOLS = ["LogCapture"]; - -const SYSTEM_PROPERTY_KEY_MAX = 32; -const SYSTEM_PROPERTY_VALUE_MAX = 92; - -function debug(msg) { - dump("LogCapture.jsm: " + msg + "\n"); -} - -var LogCapture = { - ensureLoaded: function() { - if (!this.ctypes) { - this.load(); - } - }, - - load: function() { - // load in everything on first use - Cu.import("resource://gre/modules/ctypes.jsm", this); - - this.libc = this.ctypes.open(this.ctypes.libraryName("c")); - - this.read = this.libc.declare("read", - this.ctypes.default_abi, - this.ctypes.int, // bytes read (out) - this.ctypes.int, // file descriptor (in) - this.ctypes.voidptr_t, // buffer to read into (in) - this.ctypes.size_t // size_t size of buffer (in) - ); - - this.open = this.libc.declare("open", - this.ctypes.default_abi, - this.ctypes.int, // file descriptor (returned) - this.ctypes.char.ptr, // path - this.ctypes.int // flags - ); - - this.close = this.libc.declare("close", - this.ctypes.default_abi, - this.ctypes.int, // error code (returned) - this.ctypes.int // file descriptor - ); - - this.getpid = this.libc.declare("getpid", - this.ctypes.default_abi, - this.ctypes.int // PID - ); - - this.property_find_nth = - this.libc.declare("__system_property_find_nth", - this.ctypes.default_abi, - this.ctypes.voidptr_t, // return value: nullable prop_info* - this.ctypes.unsigned_int); // n: the index of the property to return - - this.property_read = - this.libc.declare("__system_property_read", - this.ctypes.default_abi, - this.ctypes.void_t, // return: none - this.ctypes.voidptr_t, // non-null prop_info* - this.ctypes.char.ptr, // key - this.ctypes.char.ptr); // value - - this.key_buf = this.ctypes.char.array(SYSTEM_PROPERTY_KEY_MAX)(); - this.value_buf = this.ctypes.char.array(SYSTEM_PROPERTY_VALUE_MAX)(); - }, - - cleanup: function() { - this.libc.close(); - - this.read = null; - this.open = null; - this.close = null; - this.property_find_nth = null; - this.property_read = null; - this.key_buf = null; - this.value_buf = null; - - this.libc = null; - this.ctypes = null; - }, - - /** - * readLogFile - * Read in /dev/log/{{log}} in nonblocking mode, which will return -1 if - * reading would block the thread. - * - * @param log {String} The log from which to read. Must be present in /dev/log - * @return {Uint8Array} Raw log data - */ - readLogFile: function(logLocation) { - this.ensureLoaded(); - - const O_READONLY = 0; - const O_NONBLOCK = 1 << 11; - - const BUF_SIZE = 2048; - - let BufType = this.ctypes.ArrayType(this.ctypes.char); - let buf = new BufType(BUF_SIZE); - let logArray = []; - - let logFd = this.open(logLocation, O_READONLY | O_NONBLOCK); - if (logFd === -1) { - return null; - } - - let readStart = Date.now(); - let readCount = 0; - while (true) { - let count = this.read(logFd, buf, BUF_SIZE); - readCount += 1; - - if (count <= 0) { - // log has return due to being nonblocking or running out of things - break; - } - for(let i = 0; i < count; i++) { - logArray.push(buf[i]); - } - } - - let logTypedArray = new Uint8Array(logArray); - - this.close(logFd); - - return logTypedArray; - }, - - /** - * Get all system properties as a dict with keys mapping to values - */ - readProperties: function() { - this.ensureLoaded(); - let n = 0; - let propertyDict = {}; - - while(true) { - let prop_info = this.property_find_nth(n); - if(prop_info.isNull()) { - break; - } - - // read the prop_info into the key and value buffers - this.property_read(prop_info, this.key_buf, this.value_buf); - let key = this.key_buf.readString();; - let value = this.value_buf.readString() - - propertyDict[key] = value; - n++; - } - - return propertyDict; - }, - - /** - * Dumping about:memory to a file in /data/local/tmp/, returning a Promise. - * Will be resolved with the dumped file name. - */ - readAboutMemory: function() { - this.ensureLoaded(); - let deferred = Promise.defer(); - - // Perform the dump - let dumper = Cc["@mozilla.org/memory-info-dumper;1"] - .getService(Ci.nsIMemoryInfoDumper); - - let file = "/data/local/tmp/logshake-about_memory-" + this.getpid() + ".json.gz"; - dumper.dumpMemoryReportsToNamedFile(file, function() { - deferred.resolve(file); - }, null, false); - - return deferred.promise; - }, - - /** - * Dumping screenshot, returning a Promise. Will be resolved with the content - * as an ArrayBuffer. - */ - getScreenshot: function() { - let deferred = Promise.defer(); - try { - this.ensureLoaded(); - - let fr = new FileReader(); - fr.onload = function(evt) { - deferred.resolve(new Uint8Array(evt.target.result)); - }; - - fr.onerror = function(evt) { - deferred.reject(evt); - }; - - fr.readAsArrayBuffer(Screenshot.get()); - } catch(e) { - // We pass any errors through to the deferred Promise - deferred.reject(e); - } - - return deferred.promise; - } -}; - -this.LogCapture = LogCapture; diff --git a/b2g/components/LogParser.jsm b/b2g/components/LogParser.jsm deleted file mode 100644 index c40db9767..000000000 --- a/b2g/components/LogParser.jsm +++ /dev/null @@ -1,257 +0,0 @@ -/* jshint esnext: true */ -/* global DataView */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["LogParser"]; - -/** - * Parse an array read from a /dev/log/ file. Format taken from - * kernel/drivers/staging/android/logger.h and system/core/logcat/logcat.cpp - * - * @param array {Uint8Array} Array read from /dev/log/ file - * @return {Array} List of log messages - */ -function parseLogArray(array) { - let data = new DataView(array.buffer); - let byteString = String.fromCharCode.apply(null, array); - - // Length of bytes that precede the payload of a log message - // From the 5 Uint32 and 1 Uint8 reads - const HEADER_LENGTH = 21; - - let logMessages = []; - let pos = 0; - - while (pos + HEADER_LENGTH < byteString.length) { - // Parse a single log entry - - // Track current offset from global position - let offset = 0; - - // Length of the entry, discarded - let length = data.getUint32(pos + offset, true); - offset += 4; - // Id of the process which generated the message - let processId = data.getUint32(pos + offset, true); - offset += 4; - // Id of the thread which generated the message - let threadId = data.getUint32(pos + offset, true); - offset += 4; - // Seconds since epoch when this message was logged - let seconds = data.getUint32(pos + offset, true); - offset += 4; - // Nanoseconds since the last second - let nanoseconds = data.getUint32(pos + offset, true); - offset += 4; - - // Priority in terms of the ANDROID_LOG_* constants (see below) - // This is where the length field begins counting - let priority = data.getUint8(pos + offset); - - // Reset pos and offset to count from here - pos += offset; - offset = 0; - offset += 1; - - // Read the tag and message, represented as null-terminated c-style strings - let tag = ""; - while (byteString[pos + offset] != "\0") { - tag += byteString[pos + offset]; - offset ++; - } - offset ++; - - let message = ""; - // The kernel log driver may have cut off the null byte (logprint.c) - while (byteString[pos + offset] != "\0" && offset < length) { - message += byteString[pos + offset]; - offset ++; - } - - // Un-skip the missing null terminator - if (offset === length) { - offset --; - } - - offset ++; - - pos += offset; - - // Log messages are occasionally delimited by newlines, but are also - // sometimes followed by newlines as well - if (message.charAt(message.length - 1) === "\n") { - message = message.substring(0, message.length - 1); - } - - // Add an aditional time property to mimic the milliseconds since UTC - // expected by Date - let time = seconds * 1000.0 + nanoseconds/1000000.0; - - // Log messages with interleaved newlines are considered to be separate log - // messages by logcat - for (let lineMessage of message.split("\n")) { - logMessages.push({ - processId: processId, - threadId: threadId, - seconds: seconds, - nanoseconds: nanoseconds, - time: time, - priority: priority, - tag: tag, - message: lineMessage + "\n" - }); - } - } - - return logMessages; -} - -/** - * Get a thread-time style formatted string from time - * @param time {Number} Milliseconds since epoch - * @return {String} Formatted time string - */ -function getTimeString(time) { - let date = new Date(time); - function pad(number) { - if ( number < 10 ) { - return "0" + number; - } - return number; - } - return pad( date.getMonth() + 1 ) + - "-" + pad( date.getDate() ) + - " " + pad( date.getHours() ) + - ":" + pad( date.getMinutes() ) + - ":" + pad( date.getSeconds() ) + - "." + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5); -} - -/** - * Pad a string using spaces on the left - * @param str {String} String to pad - * @param width {Number} Desired string length - */ -function padLeft(str, width) { - while (str.length < width) { - str = " " + str; - } - return str; -} - -/** - * Pad a string using spaces on the right - * @param str {String} String to pad - * @param width {Number} Desired string length - */ -function padRight(str, width) { - while (str.length < width) { - str = str + " "; - } - return str; -} - -/** Constant values taken from system/core/liblog */ -const ANDROID_LOG_UNKNOWN = 0; -const ANDROID_LOG_DEFAULT = 1; -const ANDROID_LOG_VERBOSE = 2; -const ANDROID_LOG_DEBUG = 3; -const ANDROID_LOG_INFO = 4; -const ANDROID_LOG_WARN = 5; -const ANDROID_LOG_ERROR = 6; -const ANDROID_LOG_FATAL = 7; -const ANDROID_LOG_SILENT = 8; - -/** - * Map a priority number to its abbreviated string equivalent - * @param priorityNumber {Number} Log-provided priority number - * @return {String} Priority number's abbreviation - */ -function getPriorityString(priorityNumber) { - switch (priorityNumber) { - case ANDROID_LOG_VERBOSE: - return "V"; - case ANDROID_LOG_DEBUG: - return "D"; - case ANDROID_LOG_INFO: - return "I"; - case ANDROID_LOG_WARN: - return "W"; - case ANDROID_LOG_ERROR: - return "E"; - case ANDROID_LOG_FATAL: - return "F"; - case ANDROID_LOG_SILENT: - return "S"; - default: - return "?"; - } -} - - -/** - * Mimic the logcat "threadtime" format, generating a formatted string from a - * log message object. - * @param logMessage {Object} A log message from the list returned by parseLogArray - * @return {String} threadtime formatted summary of the message - */ -function formatLogMessage(logMessage) { - // MM-DD HH:MM:SS.ms pid tid priority tag: message - // from system/core/liblog/logprint.c: - return getTimeString(logMessage.time) + - " " + padLeft(""+logMessage.processId, 5) + - " " + padLeft(""+logMessage.threadId, 5) + - " " + getPriorityString(logMessage.priority) + - " " + padRight(logMessage.tag, 8) + - ": " + logMessage.message; -} - -/** - * Convert a string to a utf-8 Uint8Array - * @param {String} str - * @return {Uint8Array} - */ -function textEncode(str) { - return new TextEncoder("utf-8").encode(str); -} - -/** - * Pretty-print an array of bytes read from a log file by parsing then - * threadtime formatting its entries. - * @param array {Uint8Array} Array of a log file's bytes - * @return {Uint8Array} Pretty-printed log - */ -function prettyPrintLogArray(array) { - let logMessages = parseLogArray(array); - return textEncode(logMessages.map(formatLogMessage).join("")); -} - -/** - * Pretty-print an array read from the list of propreties. - * @param {Object} Object representing the properties - * @return {Uint8Array} Human-readable string of property name: property value - */ -function prettyPrintPropertiesArray(properties) { - let propertiesString = ""; - for(let propName in properties) { - propertiesString += "[" + propName + "]: [" + properties[propName] + "]\n"; - } - return textEncode(propertiesString); -} - -/** - * Pretty-print a normal array. Does nothing. - * @param array {Uint8Array} Input array - * @return {Uint8Array} The same array - */ -function prettyPrintArray(array) { - return array; -} - -this.LogParser = { - parseLogArray: parseLogArray, - prettyPrintArray: prettyPrintArray, - prettyPrintLogArray: prettyPrintLogArray, - prettyPrintPropertiesArray: prettyPrintPropertiesArray -}; diff --git a/b2g/components/LogShake.jsm b/b2g/components/LogShake.jsm deleted file mode 100644 index 6426c21de..000000000 --- a/b2g/components/LogShake.jsm +++ /dev/null @@ -1,588 +0,0 @@ -/* 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/. */ - -/** - * LogShake is a module which listens for log requests sent by Gaia. In - * response to a sufficiently large acceleration (a shake), it will save log - * files to an arbitrary directory which it will then return on a - * 'capture-logs-success' event with detail.logFilenames representing each log - * file's name and detail.logPaths representing the patch to each log file or - * the path to the archive. - * If an error occurs it will instead produce a 'capture-logs-error' event. - * We send a capture-logs-start events to notify the system app and the user, - * since dumping can be a bit long sometimes. - */ - -/* enable Mozilla javascript extensions and global strictness declaration, - * disable valid this checking */ -/* jshint moz: true, esnext: true */ -/* jshint -W097 */ -/* jshint -W040 */ -/* global Services, Components, dump, LogCapture, LogParser, - OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -// Constants for creating zip file taken from toolkit/webapps/tests/head.js -const PR_RDWR = 0x04; -const PR_CREATE_FILE = 0x08; -const PR_TRUNCATE = 0x20; - -XPCOMUtils.defineLazyModuleGetter(this, "LogCapture", "resource://gre/modules/LogCapture.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "LogParser", "resource://gre/modules/LogParser.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService", - "@mozilla.org/power/powermanagerservice;1", - "nsIPowerManagerService"); - -XPCOMUtils.defineLazyServiceGetter(this, "volumeService", - "@mozilla.org/telephony/volume-service;1", - "nsIVolumeService"); - -this.EXPORTED_SYMBOLS = ["LogShake"]; - -function debug(msg) { - dump("LogShake.jsm: "+msg+"\n"); -} - -/** - * An empirically determined amount of acceleration corresponding to a - * shake. - */ -const EXCITEMENT_THRESHOLD = 500; -/** - * The maximum fraction to update the excitement value per frame. This - * corresponds to requiring shaking for approximately 10 motion events (1.6 - * seconds) - */ -const EXCITEMENT_FILTER_ALPHA = 0.2; -const DEVICE_MOTION_EVENT = "devicemotion"; -const SCREEN_CHANGE_EVENT = "screenchange"; -const CAPTURE_LOGS_CONTENT_EVENT = "requestSystemLogs"; -const CAPTURE_LOGS_START_EVENT = "capture-logs-start"; -const CAPTURE_LOGS_ERROR_EVENT = "capture-logs-error"; -const CAPTURE_LOGS_SUCCESS_EVENT = "capture-logs-success"; - -var LogShake = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]), - - /** - * If LogShake is in QA Mode, which bundles all files into a compressed archive - */ - qaModeEnabled: false, - - /** - * If LogShake is listening for device motion events. Required due to lag - * between HAL layer of device motion events and listening for device motion - * events. - */ - deviceMotionEnabled: false, - - /** - * We only listen to motion events when the screen is enabled, keep track - * of its state. - */ - screenEnabled: true, - - /** - * Flag monitoring if the preference to enable shake to capture is - * enabled in gaia. - */ - listenToDeviceMotion: true, - - /** - * If a capture has been requested and is waiting for reads/parsing. Used for - * debouncing. - */ - captureRequested: false, - - /** - * The current excitement (movement) level - */ - excitement: 0, - - /** - * Map of files which have log-type information to their parsers - */ - LOGS_WITH_PARSERS: { - "/dev/log/main": LogParser.prettyPrintLogArray, - "/dev/log/system": LogParser.prettyPrintLogArray, - "/dev/log/radio": LogParser.prettyPrintLogArray, - "/dev/log/events": LogParser.prettyPrintLogArray, - "/proc/cmdline": LogParser.prettyPrintArray, - "/proc/kmsg": LogParser.prettyPrintArray, - "/proc/last_kmsg": LogParser.prettyPrintArray, - "/proc/meminfo": LogParser.prettyPrintArray, - "/proc/uptime": LogParser.prettyPrintArray, - "/proc/version": LogParser.prettyPrintArray, - "/proc/vmallocinfo": LogParser.prettyPrintArray, - "/proc/vmstat": LogParser.prettyPrintArray, - "/system/b2g/application.ini": LogParser.prettyPrintArray, - "/cache/recovery/last_install": LogParser.prettyPrintArray, - "/cache/recovery/last_kmsg": LogParser.prettyPrintArray, - "/cache/recovery/last_log": LogParser.prettyPrintArray - }, - - /** - * Start existing, observing motion events if the screen is turned on. - */ - init: function() { - // TODO: no way of querying screen state from power manager - // this.handleScreenChangeEvent({ detail: { - // screenEnabled: powerManagerService.screenEnabled - // }}); - - // However, the screen is always on when we are being enabled because it is - // either due to the phone starting up or a user enabling us directly. - this.handleScreenChangeEvent({ detail: { - screenEnabled: true - }}); - - // Reset excitement to clear residual motion - this.excitement = 0; - - SystemAppProxy.addEventListener(CAPTURE_LOGS_CONTENT_EVENT, this, false); - SystemAppProxy.addEventListener(SCREEN_CHANGE_EVENT, this, false); - - Services.obs.addObserver(this, "xpcom-shutdown", false); - }, - - /** - * Handle an arbitrary event, passing it along to the proper function - */ - handleEvent: function(event) { - switch (event.type) { - case DEVICE_MOTION_EVENT: - if (!this.deviceMotionEnabled) { - return; - } - this.handleDeviceMotionEvent(event); - break; - - case SCREEN_CHANGE_EVENT: - this.handleScreenChangeEvent(event); - break; - - case CAPTURE_LOGS_CONTENT_EVENT: - this.startCapture(); - break; - } - }, - - /** - * Handle an observation from Services.obs - */ - observe: function(subject, topic) { - if (topic === "xpcom-shutdown") { - this.uninit(); - } - }, - - enableQAMode: function() { - debug("Enabling QA Mode"); - this.qaModeEnabled = true; - }, - - disableQAMode: function() { - debug("Disabling QA Mode"); - this.qaModeEnabled = false; - }, - - enableDeviceMotionListener: function() { - this.listenToDeviceMotion = true; - this.startDeviceMotionListener(); - }, - - disableDeviceMotionListener: function() { - this.listenToDeviceMotion = false; - this.stopDeviceMotionListener(); - }, - - startDeviceMotionListener: function() { - if (!this.deviceMotionEnabled && - this.listenToDeviceMotion && - this.screenEnabled) { - SystemAppProxy.addEventListener(DEVICE_MOTION_EVENT, this, false); - this.deviceMotionEnabled = true; - } - }, - - stopDeviceMotionListener: function() { - SystemAppProxy.removeEventListener(DEVICE_MOTION_EVENT, this, false); - this.deviceMotionEnabled = false; - }, - - /** - * Handle a motion event, keeping track of "excitement", the magnitude - * of the device"s acceleration. - */ - handleDeviceMotionEvent: function(event) { - // There is a lag between disabling the event listener and event arrival - // ceasing. - if (!this.deviceMotionEnabled) { - return; - } - - let acc = event.accelerationIncludingGravity; - - // Updates excitement by a factor of at most alpha, ignoring sudden device - // motion. See bug #1101994 for more information. - let newExcitement = acc.x * acc.x + acc.y * acc.y + acc.z * acc.z; - this.excitement += (newExcitement - this.excitement) * EXCITEMENT_FILTER_ALPHA; - - if (this.excitement > EXCITEMENT_THRESHOLD) { - this.startCapture(); - } - }, - - startCapture: function() { - if (this.captureRequested) { - return; - } - this.captureRequested = true; - SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_START_EVENT, {}); - this.captureLogs().then(logResults => { - // On resolution send the success event to the requester - SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_SUCCESS_EVENT, { - logPaths: logResults.logPaths, - logFilenames: logResults.logFilenames - }); - this.captureRequested = false; - }, error => { - // On an error send the error event - SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_ERROR_EVENT, {error: error}); - this.captureRequested = false; - }); - }, - - handleScreenChangeEvent: function(event) { - this.screenEnabled = event.detail.screenEnabled; - if (this.screenEnabled) { - this.startDeviceMotionListener(); - } else { - this.stopDeviceMotionListener(); - } - }, - - /** - * Captures and saves the current device logs, returning a promise that will - * resolve to an array of log filenames. - */ - captureLogs: function() { - return this.readLogs().then(logArrays => { - return this.saveLogs(logArrays); - }); - }, - - /** - * Read in all log files, returning their formatted contents - * @return {Promise<Array>} - */ - readLogs: function() { - let logArrays = {}; - let readPromises = []; - - try { - logArrays["properties"] = - LogParser.prettyPrintPropertiesArray(LogCapture.readProperties()); - } catch (ex) { - Cu.reportError("Unable to get device properties: " + ex); - } - - // Let Gecko perfom the dump to a file, and just collect it - let readAboutMemoryPromise = new Promise(resolve => { - // Wrap the readAboutMemory promise to make it infallible - LogCapture.readAboutMemory().then(aboutMemory => { - let file = OS.Path.basename(aboutMemory); - let logArray; - try { - logArray = LogCapture.readLogFile(aboutMemory); - if (!logArray) { - debug("LogCapture.readLogFile() returned nothing for about:memory"); - } - // We need to remove the dumped file, now that we have it in memory - OS.File.remove(aboutMemory); - } catch (ex) { - Cu.reportError("Unable to handle about:memory dump: " + ex); - } - logArrays[file] = LogParser.prettyPrintArray(logArray); - resolve(); - }, ex => { - Cu.reportError("Unable to get about:memory dump: " + ex); - resolve(); - }); - }); - readPromises.push(readAboutMemoryPromise); - - // Wrap the promise to make it infallible - let readScreenshotPromise = new Promise(resolve => { - LogCapture.getScreenshot().then(screenshot => { - logArrays["screenshot.png"] = screenshot; - resolve(); - }, ex => { - Cu.reportError("Unable to get screenshot dump: " + ex); - resolve(); - }); - }); - readPromises.push(readScreenshotPromise); - - for (let loc in this.LOGS_WITH_PARSERS) { - let logArray; - try { - logArray = LogCapture.readLogFile(loc); - if (!logArray) { - debug("LogCapture.readLogFile() returned nothing for: " + loc); - continue; - } - } catch (ex) { - Cu.reportError("Unable to LogCapture.readLogFile('" + loc + "'): " + ex); - continue; - } - - try { - logArrays[loc] = this.LOGS_WITH_PARSERS[loc](logArray); - } catch (ex) { - Cu.reportError("Unable to parse content of '" + loc + "': " + ex); - continue; - } - } - - // Because the promises we depend upon can't fail this means that the - // blocking log reads will always be honored. - return Promise.all(readPromises).then(() => { - return logArrays; - }); - }, - - /** - * Save the formatted arrays of log files to an sdcard if available - */ - saveLogs: function(logArrays) { - if (!logArrays || Object.keys(logArrays).length === 0) { - return Promise.reject("Zero logs saved"); - } - - if (this.qaModeEnabled) { - return makeBaseLogsDirectory().then(writeLogArchive(logArrays), - rejectFunction("Error making base log directory")); - } else { - return makeBaseLogsDirectory().then(makeLogsDirectory, - rejectFunction("Error making base log directory")) - .then(writeLogFiles(logArrays), - rejectFunction("Error creating log directory")); - } - }, - - /** - * Stop logshake, removing all listeners - */ - uninit: function() { - this.stopDeviceMotionListener(); - SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false); - Services.obs.removeObserver(this, "xpcom-shutdown"); - } -}; - -function getLogFilename(logLocation) { - // sanitize the log location - let logName = logLocation.replace(/\//g, "-"); - if (logName[0] === "-") { - logName = logName.substring(1); - } - - // If no extension is provided, default to forcing .log - let extension = ".log"; - let logLocationExt = logLocation.split("."); - if (logLocationExt.length > 1) { - // otherwise, just append nothing - extension = ""; - } - - return logName + extension; -} - -function getSdcardPrefix() { - return volumeService.getVolumeByName("sdcard").mountPoint; -} - -function getLogDirectoryRoot() { - return "logs"; -} - -function getLogIdentifier() { - let d = new Date(); - d = new Date(d.getTime() - d.getTimezoneOffset() * 60000); - let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, "-"); - return timestamp; -} - -function rejectFunction(message) { - return function(err) { - debug(message + ": " + err); - return Promise.reject(err); - }; -} - -function makeBaseLogsDirectory() { - let sdcardPrefix; - try { - sdcardPrefix = getSdcardPrefix(); - } catch(e) { - // Handles missing sdcard - return Promise.reject(e); - } - - let dirNameRoot = getLogDirectoryRoot(); - - let logsRoot = OS.Path.join(sdcardPrefix, dirNameRoot); - - debug("Creating base log directory at root " + sdcardPrefix); - - return OS.File.makeDir(logsRoot, {from: sdcardPrefix}).then( - function() { - return { - sdcardPrefix: sdcardPrefix, - basePrefix: dirNameRoot - }; - } - ); -} - -function makeLogsDirectory({sdcardPrefix, basePrefix}) { - let dirName = getLogIdentifier(); - - let logsRoot = OS.Path.join(sdcardPrefix, basePrefix); - let logsDir = OS.Path.join(logsRoot, dirName); - - debug("Creating base log directory at root " + sdcardPrefix); - debug("Final created directory will be " + logsDir); - - return OS.File.makeDir(logsDir, {ignoreExisting: false}).then( - function() { - debug("Created: " + logsDir); - return { - logPrefix: OS.Path.join(basePrefix, dirName), - sdcardPrefix: sdcardPrefix - }; - }, - rejectFunction("Error at OS.File.makeDir for " + logsDir) - ); -} - -function getFile(filename) { - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - file.initWithPath(filename); - return file; -} - -/** - * Make a zip file - * @param {String} absoluteZipFilename - Fully qualified desired location of the zip file - * @param {Map<String, Uint8Array>} logArrays - Map from log location to log data - * @return {Array<String>} Paths of entries in the archive - */ -function makeZipFile(absoluteZipFilename, logArrays) { - let logFilenames = []; - let zipWriter = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter); - let zipFile = getFile(absoluteZipFilename); - zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); - - for (let logLocation in logArrays) { - let logArray = logArrays[logLocation]; - let logFilename = getLogFilename(logLocation); - logFilenames.push(logFilename); - - debug("Adding " + logFilename + " to the zip"); - let logArrayStream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"] - .createInstance(Ci.nsIArrayBufferInputStream); - // Set data to be copied, default offset to 0 because it is not present on - // ArrayBuffer objects - logArrayStream.setData(logArray.buffer, logArray.byteOffset || 0, - logArray.byteLength); - - zipWriter.addEntryStream(logFilename, Date.now(), - Ci.nsIZipWriter.COMPRESSION_DEFAULT, - logArrayStream, false); - } - zipWriter.close(); - - return logFilenames; -} - -function writeLogArchive(logArrays) { - return function({sdcardPrefix, basePrefix}) { - // Now the directory is guaranteed to exist, save the logs into their - // archive file - - let zipFilename = getLogIdentifier() + "-logs.zip"; - let zipPath = OS.Path.join(basePrefix, zipFilename); - let zipPrefix = OS.Path.dirname(zipPath); - let absoluteZipPath = OS.Path.join(sdcardPrefix, zipPath); - - debug("Creating zip file at " + zipPath); - let logFilenames = []; - try { - logFilenames = makeZipFile(absoluteZipPath, logArrays); - } catch(e) { - return Promise.reject(e); - } - debug("Zip file created"); - - return { - logFilenames: logFilenames, - logPaths: [zipPath], - compressed: true - }; - }; -} - -function writeLogFiles(logArrays) { - return function({sdcardPrefix, logPrefix}) { - // Now the directory is guaranteed to exist, save the logs - let logFilenames = []; - let logPaths = []; - let saveRequests = []; - - for (let logLocation in logArrays) { - debug("Requesting save of " + logLocation); - let logArray = logArrays[logLocation]; - let logFilename = getLogFilename(logLocation); - // The local pathrepresents the relative path within the SD card, not the - // absolute path because Gaia will refer to it using the DeviceStorage - // API - let localPath = OS.Path.join(logPrefix, logFilename); - - logFilenames.push(logFilename); - logPaths.push(localPath); - - let absolutePath = OS.Path.join(sdcardPrefix, localPath); - let saveRequest = OS.File.writeAtomic(absolutePath, logArray); - saveRequests.push(saveRequest); - } - - return Promise.all(saveRequests).then( - function() { - return { - logFilenames: logFilenames, - logPaths: logPaths, - compressed: false - }; - }, - rejectFunction("Error at some save request") - ); - }; -} - -LogShake.init(); -this.LogShake = LogShake; diff --git a/b2g/components/MailtoProtocolHandler.js b/b2g/components/MailtoProtocolHandler.js deleted file mode 100644 index 500fb9112..000000000 --- a/b2g/components/MailtoProtocolHandler.js +++ /dev/null @@ -1,46 +0,0 @@ -/* 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/. */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/ActivityChannel.jsm'); - -function MailtoProtocolHandler() { -} - -MailtoProtocolHandler.prototype = { - - scheme: "mailto", - defaultPort: -1, - protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE | - Ci.nsIProtocolHandler.URI_NOAUTH | - Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE | - Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA, - allowPort: () => false, - - newURI: function Proto_newURI(aSpec, aOriginCharset) { - let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI); - uri.spec = aSpec; - return uri; - }, - - newChannel2: function Proto_newChannel2(aURI, aLoadInfo) { - return new ActivityChannel(aURI, aLoadInfo, - "mail-handler", - { URI: aURI.spec, - type: "mail" }); - }, - - newChannel: function Proto_newChannel(aURI) { - return this.newChannel2(aURI, null); - }, - - classID: Components.ID("{50777e53-0331-4366-a191-900999be386c}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([MailtoProtocolHandler]); diff --git a/b2g/components/OMAContentHandler.js b/b2g/components/OMAContentHandler.js deleted file mode 100644 index 56c87a3b2..000000000 --- a/b2g/components/OMAContentHandler.js +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyGetter(this, "cpmm", function() { - return Cc["@mozilla.org/childprocessmessagemanager;1"] - .getService(Ci.nsIMessageSender); -}); - -function debug(aMsg) { - //dump("--*-- OMAContentHandler: " + aMsg + "\n"); -} - -const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001; - -function OMAContentHandler() { -} - -OMAContentHandler.prototype = { - classID: Components.ID("{a6b2ab13-9037-423a-9897-dde1081be323}"), - - _xpcom_factory: { - createInstance: function createInstance(outer, iid) { - if (outer != null) { - throw Cr.NS_ERROR_NO_AGGREGATION; - } - return new OMAContentHandler().QueryInterface(iid); - } - }, - - handleContent: function handleContent(aMimetype, aContext, aRequest) { - if (!(aRequest instanceof Ci.nsIChannel)) { - throw NS_ERROR_WONT_HANDLE_CONTENT; - } - - let detail = { - "type": aMimetype, - "url": aRequest.URI.spec - }; - cpmm.sendAsyncMessage("content-handler", detail); - - aRequest.cancel(Cr.NS_BINDING_ABORTED); - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler]) -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([OMAContentHandler]); diff --git a/b2g/components/OopCommandLine.js b/b2g/components/OopCommandLine.js deleted file mode 100644 index 658bbdde5..000000000 --- a/b2g/components/OopCommandLine.js +++ /dev/null @@ -1,46 +0,0 @@ -/* 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/. */ - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); - -function oopCommandlineHandler() { -} - -oopCommandlineHandler.prototype = { - handle: function(cmdLine) { - let oopFlag = cmdLine.handleFlag("oop", false); - if (oopFlag) { - /** - * Manipulate preferences by adding to the *default* branch. Adding - * to the default branch means the changes we make won"t get written - * back to user preferences. - */ - let prefs = Services.prefs - let branch = prefs.getDefaultBranch(""); - - try { - // Turn on all OOP services, making desktop run similar to phone - // environment - branch.setBoolPref("dom.ipc.tabs.disabled", false); - branch.setBoolPref("layers.acceleration.disabled", false); - branch.setBoolPref("layers.offmainthreadcomposition.async-animations", true); - branch.setBoolPref("layers.async-video.enabled", true); - branch.setBoolPref("layers.async-pan-zoom.enabled", true); - branch.setCharPref("gfx.content.azure.backends", "cairo"); - } catch (e) { } - - } - if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) { - cmdLine.preventDefault = true; - } - }, - - helpInfo: " --oop Use out-of-process model in B2G\n", - classID: Components.ID("{e30b0e13-2d12-4cb0-bc4c-4e617a1bf76e}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]), -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([oopCommandlineHandler]); diff --git a/b2g/components/OrientationChangeHandler.jsm b/b2g/components/OrientationChangeHandler.jsm deleted file mode 100644 index 5007b70e0..000000000 --- a/b2g/components/OrientationChangeHandler.jsm +++ /dev/null @@ -1,70 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = []; - -const Cu = Components.utils; -Cu.import("resource://gre/modules/Services.jsm"); - -var window = Services.wm.getMostRecentWindow("navigator:browser"); -var system = window.document.getElementById("systemapp"); - -var OrientationChangeHandler = { - // Clockwise orientations, looping - orientations: ["portrait-primary", "landscape-secondary", - "portrait-secondary", "landscape-primary", - "portrait-primary"], - - lastOrientation: "portrait-primary", - - init: function() { - window.screen.addEventListener("mozorientationchange", this, true); - }, - - handleEvent: function(evt) { - let newOrientation = window.screen.mozOrientation; - let orientationIndex = this.orientations.indexOf(this.lastOrientation); - let nextClockwiseOrientation = this.orientations[orientationIndex + 1]; - let fullSwitch = (newOrientation.split("-")[0] == - this.lastOrientation.split("-")[0]); - - this.lastOrientation = newOrientation; - - let angle, xFactor, yFactor; - if (fullSwitch) { - angle = 180; - xFactor = 1; - } else { - angle = (nextClockwiseOrientation == newOrientation) ? 90 : -90; - xFactor = window.innerWidth / window.innerHeight; - } - yFactor = 1 / xFactor; - - system.style.transition = ""; - system.style.transform = "rotate(" + angle + "deg)" + - "scale(" + xFactor + ", " + yFactor + ")"; - - function trigger() { - system.style.transition = "transform .25s cubic-bezier(.15, .7, .6, .9)"; - - system.style.opacity = ""; - system.style.transform = ""; - } - - // 180deg rotation, no resize - if (fullSwitch) { - window.setTimeout(trigger); - return; - } - - window.addEventListener("resize", function waitForResize(e) { - window.removeEventListener("resize", waitForResize); - trigger(); - }); - } -}; - -OrientationChangeHandler.init(); diff --git a/b2g/components/PresentationRequestUIGlue.js b/b2g/components/PresentationRequestUIGlue.js deleted file mode 100644 index 5c50401de..000000000 --- a/b2g/components/PresentationRequestUIGlue.js +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -"use strict" - -function debug(aMsg) { - // dump("-*- PresentationRequestUIGlue: " + aMsg + "\n"); -} - -const { interfaces: Ci, utils: Cu, classes: Cc } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -function PresentationRequestUIGlue() { } - -PresentationRequestUIGlue.prototype = { - - sendRequest: function(aUrl, aSessionId, aDevice) { - let localDevice; - try { - localDevice = aDevice.QueryInterface(Ci.nsIPresentationLocalDevice); - } catch (e) {} - - if (localDevice) { - return this.sendTo1UA(aUrl, aSessionId, localDevice.windowId); - } else { - return this.sendTo2UA(aUrl, aSessionId); - } - }, - - // For 1-UA scenario - sendTo1UA: function(aUrl, aSessionId, aWindowId) { - return new Promise((aResolve, aReject) => { - let handler = (evt) => { - if (evt.type === "unload") { - SystemAppProxy.removeEventListenerWithId(aWindowId, - "unload", - handler); - SystemAppProxy.removeEventListenerWithId(aWindowId, - "mozPresentationContentEvent", - handler); - aReject(); - } - if (evt.type === "mozPresentationContentEvent" && - evt.detail.id == aSessionId) { - SystemAppProxy.removeEventListenerWithId(aWindowId, - "unload", - handler); - SystemAppProxy.removeEventListenerWithId(aWindowId, - "mozPresentationContentEvent", - handler); - this.appLaunchCallback(evt.detail, aResolve, aReject); - } - }; - // If system(-remote) app is closed. - SystemAppProxy.addEventListenerWithId(aWindowId, - "unload", - handler); - // Listen to the result for the opened iframe from front-end. - SystemAppProxy.addEventListenerWithId(aWindowId, - "mozPresentationContentEvent", - handler); - SystemAppProxy.sendCustomEventWithId(aWindowId, - "mozPresentationChromeEvent", - { type: "presentation-launch-receiver", - url: aUrl, - id: aSessionId }); - }); - }, - - // For 2-UA scenario - sendTo2UA: function(aUrl, aSessionId) { - return new Promise((aResolve, aReject) => { - let handler = (evt) => { - if (evt.type === "mozPresentationContentEvent" && - evt.detail.id == aSessionId) { - SystemAppProxy.removeEventListener("mozPresentationContentEvent", - handler); - this.appLaunchCallback(evt.detail, aResolve, aReject); - } - }; - - // Listen to the result for the opened iframe from front-end. - SystemAppProxy.addEventListener("mozPresentationContentEvent", - handler); - SystemAppProxy._sendCustomEvent("mozPresentationChromeEvent", - { type: "presentation-launch-receiver", - url: aUrl, - id: aSessionId }); - }); - }, - - appLaunchCallback: function(aDetail, aResolve, aReject) { - switch(aDetail.type) { - case "presentation-receiver-launched": - aResolve(aDetail.frame); - break; - case "presentation-receiver-permission-denied": - aReject(); - break; - } - }, - - classID: Components.ID("{ccc8a839-0b64-422b-8a60-fb2af0e376d0}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationRequestUIGlue]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PresentationRequestUIGlue]); diff --git a/b2g/components/ProcessGlobal.js b/b2g/components/ProcessGlobal.js deleted file mode 100644 index 94326ad50..000000000 --- a/b2g/components/ProcessGlobal.js +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- / -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* 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/. */ - -'use strict'; - -/** - * This code exists to be a "grab bag" of global code that needs to be - * loaded per B2G process, but doesn't need to directly interact with - * web content. - * - * (It's written as an XPCOM service because it needs to watch - * app-startup.) - */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -Cu.import('resource://gre/modules/Services.jsm'); -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); - -XPCOMUtils.defineLazyServiceGetter(this, "settings", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -function debug(msg) { - log(msg); -} -function log(msg) { - // This file implements console.log(), so use dump(). - //dump('ProcessGlobal: ' + msg + '\n'); -} - -function formatStackFrame(aFrame) { - let functionName = aFrame.functionName || '<anonymous>'; - return ' at ' + functionName + - ' (' + aFrame.filename + ':' + aFrame.lineNumber + - ':' + aFrame.columnNumber + ')'; -} - -function ConsoleMessage(aMsg, aLevel) { - this.timeStamp = Date.now(); - this.msg = aMsg; - - switch (aLevel) { - case 'error': - case 'assert': - this.logLevel = Ci.nsIConsoleMessage.error; - break; - case 'warn': - this.logLevel = Ci.nsIConsoleMessage.warn; - break; - case 'log': - case 'info': - this.logLevel = Ci.nsIConsoleMessage.info; - break; - default: - this.logLevel = Ci.nsIConsoleMessage.debug; - break; - } -} - -function toggleUnrestrictedDevtools(unrestricted) { - Services.prefs.setBoolPref("devtools.debugger.forbid-certified-apps", - !unrestricted); - Services.prefs.setBoolPref("dom.apps.developer_mode", unrestricted); - // TODO: Remove once bug 1125916 is fixed. - Services.prefs.setBoolPref("network.disable.ipc.security", unrestricted); - Services.prefs.setBoolPref("dom.webcomponents.enabled", unrestricted); - let lock = settings.createLock(); - lock.set("developer.menu.enabled", unrestricted, null); - lock.set("devtools.unrestricted", unrestricted, null); -} - -ConsoleMessage.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleMessage]), - toString: function() { return this.msg; } -}; - -const gFactoryResetFile = "__post_reset_cmd__"; - -function ProcessGlobal() {} -ProcessGlobal.prototype = { - classID: Components.ID('{1a94c87a-5ece-4d11-91e1-d29c29f21b28}'), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsISupportsWeakReference]), - - wipeDir: function(path) { - log("wipeDir " + path); - let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - dir.initWithPath(path); - if (!dir.exists() || !dir.isDirectory()) { - return; - } - let entries = dir.directoryEntries; - while (entries.hasMoreElements()) { - let file = entries.getNext().QueryInterface(Ci.nsIFile); - log("Deleting " + file.path); - try { - file.remove(true); - } catch(e) {} - } - }, - - processCommandsFile: function(text) { - log("processCommandsFile " + text); - let lines = text.split("\n"); - lines.forEach((line) => { - log(line); - let params = line.split(" "); - switch (params[0]) { - case "root": - log("unrestrict devtools"); - toggleUnrestrictedDevtools(true); - break; - case "wipe": - this.wipeDir(params[1]); - case "normal": - log("restrict devtools"); - toggleUnrestrictedDevtools(false); - break; - } - }); - }, - - cleanupAfterFactoryReset: function() { - log("cleanupAfterWipe start"); - - Cu.import("resource://gre/modules/osfile.jsm"); - let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - dir.initWithPath("/persist"); - var postResetFile = dir.exists() ? - OS.Path.join("/persist", gFactoryResetFile): - OS.Path.join("/cache", gFactoryResetFile); - let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - file.initWithPath(postResetFile); - if (!file.exists()) { - debug("No additional command.") - return; - } - - let promise = OS.File.read(postResetFile); - promise.then( - (array) => { - file.remove(false); - let decoder = new TextDecoder(); - this.processCommandsFile(decoder.decode(array)); - }, - function onError(error) { - debug("Error: " + error); - } - ); - - log("cleanupAfterWipe end."); - }, - - observe: function pg_observe(subject, topic, data) { - switch (topic) { - case 'app-startup': { - Services.obs.addObserver(this, 'console-api-log-event', false); - let inParent = Cc["@mozilla.org/xre/app-info;1"] - .getService(Ci.nsIXULRuntime) - .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; - if (inParent) { - Services.ppmm.addMessageListener("getProfD", function(message) { - return Services.dirsvc.get("ProfD", Ci.nsIFile).path; - }); - - this.cleanupAfterFactoryReset(); - } - break; - } - case 'console-api-log-event': { - // Pipe `console` log messages to the nsIConsoleService which - // writes them to logcat on Gonk. - let message = subject.wrappedJSObject; - let args = message.arguments; - let stackTrace = ''; - - if (message.stacktrace && - (message.level == 'assert' || message.level == 'error' || message.level == 'trace')) { - stackTrace = Array.map(message.stacktrace, formatStackFrame).join('\n'); - } else { - stackTrace = formatStackFrame(message); - } - - if (stackTrace) { - args.push('\n' + stackTrace); - } - - let msg = 'Content JS ' + message.level.toUpperCase() + ': ' + Array.join(args, ' '); - Services.console.logMessage(new ConsoleMessage(msg, message.level)); - break; - } - } - }, -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProcessGlobal]); diff --git a/b2g/components/RecoveryService.js b/b2g/components/RecoveryService.js deleted file mode 100644 index 493763e6d..000000000 --- a/b2g/components/RecoveryService.js +++ /dev/null @@ -1,160 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* 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/. */ -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/ctypes.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -const RECOVERYSERVICE_CID = Components.ID("{b3caca5d-0bb0-48c6-912b-6be6cbf08832}"); -const RECOVERYSERVICE_CONTRACTID = "@mozilla.org/recovery-service;1"; - -function log(msg) { - dump("-*- RecoveryService: " + msg + "\n"); -} - -const isGonk = AppConstants.platform === 'gonk'; - -if (isGonk) { - var librecovery = (function() { - let library; - try { - library = ctypes.open("librecovery.so"); - } catch (e) { - log("Unable to open librecovery.so"); - throw Cr.NS_ERROR_FAILURE; - } - // Bug 1163956, modify updatePath from ctyps.char.ptr to ctype.char.array(4096) - // align with librecovery.h. 4096 comes from PATH_MAX - let FotaUpdateStatus = new ctypes.StructType("FotaUpdateStatus", [ - { result: ctypes.int }, - { updatePath: ctypes.char.array(4096) } - ]); - - return { - factoryReset: library.declare("factoryReset", - ctypes.default_abi, - ctypes.int), - installFotaUpdate: library.declare("installFotaUpdate", - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr, - ctypes.int), - - FotaUpdateStatus: FotaUpdateStatus, - getFotaUpdateStatus: library.declare("getFotaUpdateStatus", - ctypes.default_abi, - ctypes.int, - FotaUpdateStatus.ptr) - }; - })(); - -} - -const gFactoryResetFile = "__post_reset_cmd__"; - -function RecoveryService() {} - -RecoveryService.prototype = { - classID: RECOVERYSERVICE_CID, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIRecoveryService]), - classInfo: XPCOMUtils.generateCI({ - classID: RECOVERYSERVICE_CID, - contractID: RECOVERYSERVICE_CONTRACTID, - interfaces: [Ci.nsIRecoveryService], - classDescription: "B2G Recovery Service" - }), - - factoryReset: function RS_factoryReset(reason) { - if (!isGonk) { - Cr.NS_ERROR_FAILURE; - } - - function doReset() { - // If this succeeds, then the device reboots and this never returns - if (librecovery.factoryReset() != 0) { - log("Error: Factory reset failed. Trying again after clearing cache."); - } - let cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Ci.nsICacheStorageService); - cache.clear(); - if (librecovery.factoryReset() != 0) { - log("Error: Factory reset failed again"); - } - } - - log("factoryReset " + reason); - let commands = []; - if (reason == "wipe") { - let volumeService = Cc["@mozilla.org/telephony/volume-service;1"] - .getService(Ci.nsIVolumeService); - let volNames = volumeService.getVolumeNames(); - log("Found " + volNames.length + " volumes"); - - for (let i = 0; i < volNames.length; i++) { - let name = volNames.queryElementAt(i, Ci.nsISupportsString); - let volume = volumeService.getVolumeByName(name.data); - log("Got volume: " + name.data + " at " + volume.mountPoint); - commands.push("wipe " + volume.mountPoint); - } - } else if (reason == "root") { - commands.push("root"); - } - - if (commands.length > 0) { - Cu.import("resource://gre/modules/osfile.jsm"); - let dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); - dir.initWithPath("/persist"); - var postResetFile = dir.exists() ? - OS.Path.join("/persist", gFactoryResetFile): - OS.Path.join("/cache", gFactoryResetFile); - let encoder = new TextEncoder(); - let text = commands.join("\n"); - let array = encoder.encode(text); - let promise = OS.File.writeAtomic(postResetFile, array, - { tmpPath: postResetFile + ".tmp" }); - - promise.then(doReset, function onError(error) { - log("Error: " + error); - }); - } else { - doReset(); - } - }, - - installFotaUpdate: function RS_installFotaUpdate(updatePath) { - if (!isGonk) { - throw Cr.NS_ERROR_FAILURE; - } - - // If this succeeds, then the device reboots and this never returns - if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) { - log("Error: FOTA install failed. Trying again after clearing cache."); - } - var cache = Cc["@mozilla.org/netwerk/cache-storage-service;1"].getService(Ci.nsICacheStorageService); - cache.clear(); - if (librecovery.installFotaUpdate(updatePath, updatePath.length) != 0) { - log("Error: FOTA install failed again"); - } - }, - - getFotaUpdateStatus: function RS_getFotaUpdateStatus() { - let status = Ci.nsIRecoveryService.FOTA_UPDATE_UNKNOWN; - - if (isGonk) { - let cStatus = librecovery.FotaUpdateStatus(); - - if (librecovery.getFotaUpdateStatus(cStatus.address()) == 0) { - status = cStatus.result; - } - } - return status; - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RecoveryService]); diff --git a/b2g/components/SafeMode.jsm b/b2g/components/SafeMode.jsm deleted file mode 100644 index 9f9342f67..000000000 --- a/b2g/components/SafeMode.jsm +++ /dev/null @@ -1,150 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["SafeMode"]; - -const Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -const kSafeModePref = "b2g.safe_mode"; -const kSafeModePage = "safe_mode.html"; - -function debug(aStr) { - //dump("-*- SafeMode: " + aStr + "\n"); -} - -// This module is responsible for checking whether we want to start in safe -// mode or not. The flow is as follow: -// - wait for the `b2g.safe_mode` preference to be set to something different -// than `unset` by nsAppShell -// - If it's set to `no`, just start normally. -// - If it's set to `yes`, we load a stripped down system app from safe_mode.html" -// - This page is responsible to dispatch a mozContentEvent to us. -// - If the user choose SafeMode, we disable all add-ons. -// - We go on with startup. - -this.SafeMode = { - // Returns a promise that resolves when nsAppShell has set the - // b2g.safe_mode_state_ready preference to `true`. - _waitForPref: function() { - debug("waitForPref"); - try { - let currentMode = Services.prefs.getCharPref(kSafeModePref); - debug("current mode: " + currentMode); - if (currentMode !== "unset") { - return Promise.resolve(); - } - } catch(e) { debug("No current mode available!"); } - - // Wait for the preference to toggle. - return new Promise((aResolve, aReject) => { - let observer = function(aSubject, aTopic, aData) { - if (Services.prefs.getCharPref(kSafeModePref)) { - Services.prefs.removeObserver(kSafeModePref, observer, false); - aResolve(); - } - } - - Services.prefs.addObserver(kSafeModePref, observer, false); - }); - }, - - // Resolves once the user has decided how to start. - // Note that all the actions happen here, so there is no other action from - // consumers than to go on. - _waitForUser: function() { - debug("waitForUser"); - let isSafeMode = Services.prefs.getCharPref(kSafeModePref) === "yes"; - if (!isSafeMode) { - return Promise.resolve(); - } - debug("Starting in Safe Mode!"); - - // Load $system_app/safe_mode.html as a full screen iframe, and wait for - // the user to make a choice. - let shell = SafeMode.window.shell; - let document = SafeMode.window.document; - SafeMode.window.screen.mozLockOrientation("portrait"); - - let url = Services.io.newURI(shell.homeURL, null, null) - .resolve(kSafeModePage); - debug("Registry is ready, loading " + url); - let frame = document.createElementNS("http://www.w3.org/1999/xhtml", "html:iframe"); - frame.setAttribute("mozbrowser", "true"); - frame.setAttribute("mozapp", shell.manifestURL); - frame.setAttribute("id", "systemapp"); // To keep screen.js happy. - let contentBrowser = document.body.appendChild(frame); - - return new Promise((aResolve, aReject) => { - let content = contentBrowser.contentWindow; - - // Stripped down version of the system app bootstrap. - function handleEvent(e) { - switch(e.type) { - case "mozbrowserloadstart": - if (content.document.location == "about:blank") { - contentBrowser.addEventListener("mozbrowserlocationchange", handleEvent, true); - contentBrowser.removeEventListener("mozbrowserloadstart", handleEvent, true); - return; - } - - notifyContentStart(); - break; - case "mozbrowserlocationchange": - if (content.document.location == "about:blank") { - return; - } - - contentBrowser.removeEventListener("mozbrowserlocationchange", handleEvent, true); - notifyContentStart(); - break; - case "mozContentEvent": - content.removeEventListener("mozContentEvent", handleEvent, true); - contentBrowser.parentNode.removeChild(contentBrowser); - - if (e.detail == "safemode-yes") { - // Really starting in safe mode, let's disable add-ons first. - // TODO: disable add-ons - aResolve(); - } else { - aResolve(); - } - break; - } - } - - function notifyContentStart() { - let window = SafeMode.window; - window.shell.sendEvent(window, "SafeModeStart"); - contentBrowser.setVisible(true); - - // browser-ui-startup-complete is used by the AppShell to stop the - // boot animation and start gecko rendering. - Services.obs.notifyObservers(null, "browser-ui-startup-complete", ""); - content.addEventListener("mozContentEvent", handleEvent, true); - } - - contentBrowser.addEventListener("mozbrowserloadstart", handleEvent, true); - contentBrowser.src = url; - }); - }, - - // Returns a Promise that resolves once we have decided to run in safe mode - // or not. All the safe mode switching actions happen before resolving the - // promise. - check: function(aWindow) { - debug("check"); - this.window = aWindow; - if (AppConstants.platform !== "gonk") { - // For now we only have gonk support. - return Promise.resolve(); - } - - return this._waitForPref().then(this._waitForUser); - } -} diff --git a/b2g/components/Screenshot.jsm b/b2g/components/Screenshot.jsm deleted file mode 100644 index e6f809375..000000000 --- a/b2g/components/Screenshot.jsm +++ /dev/null @@ -1,43 +0,0 @@ -/* 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/. */ - -'use strict'; - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", "resource://gre/modules/SystemAppProxy.jsm"); - -this.EXPORTED_SYMBOLS = ['Screenshot']; - -var Screenshot = { - get: function screenshot_get() { - let systemAppFrame = SystemAppProxy.getFrame(); - let window = systemAppFrame.ownerDocument.defaultView; - let document = window.document; - - var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); - var docRect = document.body.getBoundingClientRect(); - var width = docRect.width; - var height = docRect.height; - - // Convert width and height from CSS pixels (potentially fractional) - // to device pixels (integer). - var scale = window.devicePixelRatio; - canvas.setAttribute('width', Math.round(width * scale)); - canvas.setAttribute('height', Math.round(height * scale)); - - var context = canvas.getContext('2d'); - var flags = - context.DRAWWINDOW_DRAW_CARET | - context.DRAWWINDOW_DRAW_VIEW | - context.DRAWWINDOW_USE_WIDGET_LAYERS; - context.scale(scale, scale); - context.drawWindow(window, 0, 0, width, height, 'rgb(255,255,255)', flags); - - return canvas.mozGetAsFile('screenshot', 'image/png'); - } -}; -this.Screenshot = Screenshot; diff --git a/b2g/components/SignInToWebsite.jsm b/b2g/components/SignInToWebsite.jsm deleted file mode 100644 index fd1349d46..000000000 --- a/b2g/components/SignInToWebsite.jsm +++ /dev/null @@ -1,444 +0,0 @@ -/* 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/. */ - -/* - * SignInToWebsite.jsm - UX Controller and means for accessing identity - * cookies on behalf of relying parties. - * - * Currently, the b2g security architecture isolates web applications - * so that each window has access only to a local cookie jar: - * - * To prevent Web apps from interfering with one another, each one is - * hosted on a separate domain, and therefore may only access the - * resources associated with its domain. These resources include - * things such as IndexedDB databases, cookies, offline storage, - * and so forth. - * - * -- https://developer.mozilla.org/en-US/docs/Mozilla/Firefox_OS/Security/Security_model - * - * As a result, an authentication system like Persona cannot share its - * cookie jar with multiple relying parties, and so would require a - * fresh login request in every window. This would not be a good - * experience. - * - * - * In order for navigator.id.request() to maintain state in a single - * cookie jar, we cause all Persona interactions to take place in a - * content context that is launched by the system application, with the - * result that Persona has a single cookie jar that all Relying - * Parties can use. Since of course those Relying Parties cannot - * reach into the system cookie jar, the Controller in this module - * provides a way to get messages and data to and fro between the - * Relying Party in its window context, and the Persona internal api - * in its context. - * - * On the Relying Party's side, say a web page invokes - * navigator.id.watch(), to register callbacks, and then - * navigator.id.request() to request an assertion. The navigator.id - * calls are provided by nsDOMIdentity. nsDOMIdentity messages down - * to the privileged DOMIdentity code (using cpmm and ppmm message - * managers). DOMIdentity stores the state of Relying Party flows - * using an Identity service (MinimalIdentity.jsm), and emits messages - * requesting Persona functions (doWatch, doReady, doLogout). - * - * The Identity service sends these observer messages to the - * Controller in this module, which in turn triggers content to open a - * window to host the Persona js. If user interaction is required, - * content will open the trusty UI. If user interaction is not required, - * and we only need to get to Persona functions, content will open a - * hidden iframe. In either case, a window is opened into which the - * controller causes the script identity.js to be injected. This - * script provides the glue between the in-page javascript and the - * pipe back down to the Controller, translating navigator.internal - * function callbacks into messages sent back to the Controller. - * - * As a result, a navigator.internal function in the hosted popup or - * iframe can call back to the injected identity.js (doReady, doLogin, - * or doLogout). identity.js callbacks send messages back through the - * pipe to the Controller. The controller invokes the corresponding - * function on the Identity Service (doReady, doLogin, or doLogout). - * The IdentityService calls the corresponding callback for the - * correct Relying Party, which causes DOMIdentity to send a message - * up to the Relying Party through nsDOMIdentity - * (Identity:RP:Watch:OnLogin etc.), and finally, nsDOMIdentity - * receives these messages and calls the original callback that the - * Relying Party registered (navigator.id.watch(), - * navigator.id.request(), or navigator.id.logout()). - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["SignInToWebsiteController"]; - -const Ci = Components.interfaces; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "getRandomId", - "resource://gre/modules/identity/IdentityUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "IdentityService", - "resource://gre/modules/identity/MinimalIdentity.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Logger", - "resource://gre/modules/identity/LogUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -// The default persona uri; can be overwritten with toolkit.identity.uri pref. -// Do this if you want to repoint to a different service for testing. -// There's no point in setting up an observer to monitor the pref, as b2g prefs -// can only be overwritten when the profie is recreated. So just get the value -// on start-up. -var kPersonaUri = "https://firefoxos.persona.org"; -try { - kPersonaUri = Services.prefs.getCharPref("toolkit.identity.uri"); -} catch(noSuchPref) { - // stick with the default value -} - -// JS shim that contains the callback functions that -// live within the identity UI provisioning frame. -const kIdentityShimFile = "chrome://b2g/content/identity.js"; - -// Type of MozChromeEvents to handle id dialogs. -const kOpenIdentityDialog = "id-dialog-open"; -const kDoneIdentityDialog = "id-dialog-done"; -const kCloseIdentityDialog = "id-dialog-close-iframe"; - -// Observer messages to communicate to shim -const kIdentityDelegateWatch = "identity-delegate-watch"; -const kIdentityDelegateRequest = "identity-delegate-request"; -const kIdentityDelegateLogout = "identity-delegate-logout"; -const kIdentityDelegateFinished = "identity-delegate-finished"; -const kIdentityDelegateReady = "identity-delegate-ready"; - -const kIdentityControllerDoMethod = "identity-controller-doMethod"; - -function log(...aMessageArgs) { - Logger.log.apply(Logger, ["SignInToWebsiteController"].concat(aMessageArgs)); -} - -log("persona uri =", kPersonaUri); - -function sendChromeEvent(details) { - details.uri = kPersonaUri; - SystemAppProxy.dispatchEvent(details); -} - -function Pipe() { - this._watchers = []; -} - -Pipe.prototype = { - init: function pipe_init() { - Services.obs.addObserver(this, "identity-child-process-shutdown", false); - Services.obs.addObserver(this, "identity-controller-unwatch", false); - }, - - uninit: function pipe_uninit() { - Services.obs.removeObserver(this, "identity-child-process-shutdown"); - Services.obs.removeObserver(this, "identity-controller-unwatch"); - }, - - observe: function Pipe_observe(aSubject, aTopic, aData) { - let options = {}; - if (aSubject) { - options = aSubject.wrappedJSObject; - } - switch (aTopic) { - case "identity-child-process-shutdown": - log("pipe removing watchers by message manager"); - this._removeWatchers(null, options.messageManager); - break; - - case "identity-controller-unwatch": - log("unwatching", options.id); - this._removeWatchers(options.id, options.messageManager); - break; - } - }, - - _addWatcher: function Pipe__addWatcher(aId, aMm) { - log("Adding watcher with id", aId); - for (let i = 0; i < this._watchers.length; ++i) { - let watcher = this._watchers[i]; - if (this._watcher.id === aId) { - watcher.count++; - return; - } - } - this._watchers.push({id: aId, count: 1, mm: aMm}); - }, - - _removeWatchers: function Pipe__removeWatcher(aId, aMm) { - let checkId = aId !== null; - let index = -1; - for (let i = 0; i < this._watchers.length; ++i) { - let watcher = this._watchers[i]; - if (watcher.mm === aMm && - (!checkId || (checkId && watcher.id === aId))) { - index = i; - break; - } - } - - if (index !== -1) { - if (checkId) { - if (--(this._watchers[index].count) === 0) { - this._watchers.splice(index, 1); - } - } else { - this._watchers.splice(index, 1); - } - } - - if (this._watchers.length === 0) { - log("No more watchers; clean up persona host iframe"); - let detail = { - type: kCloseIdentityDialog - }; - log('telling content to close the dialog'); - // tell content to close the dialog - sendChromeEvent(detail); - } - }, - - communicate: function(aRpOptions, aContentOptions, aMessageCallback) { - let rpID = aRpOptions.id; - let rpMM = aRpOptions.mm; - if (rpMM) { - this._addWatcher(rpID, rpMM); - } - - log("RP options:", aRpOptions, "\n content options:", aContentOptions); - - // This content variable is injected into the scope of - // kIdentityShimFile, where it is used to access the BrowserID object - // and its internal API. - let mm = null; - let uuid = getRandomId(); - let self = this; - - function removeMessageListeners() { - if (mm) { - mm.removeMessageListener(kIdentityDelegateFinished, identityDelegateFinished); - mm.removeMessageListener(kIdentityControllerDoMethod, aMessageCallback); - } - } - - function identityDelegateFinished() { - removeMessageListeners(); - - let detail = { - type: kDoneIdentityDialog, - showUI: aContentOptions.showUI || false, - id: kDoneIdentityDialog + "-" + uuid, - requestId: aRpOptions.id - }; - log('received delegate finished; telling content to close the dialog'); - sendChromeEvent(detail); - self._removeWatchers(rpID, rpMM); - } - - SystemAppProxy.addEventListener("mozContentEvent", function getAssertion(evt) { - let msg = evt.detail; - if (!msg.id.match(uuid)) { - return; - } - - switch (msg.id) { - case kOpenIdentityDialog + '-' + uuid: - if (msg.type === 'cancel') { - // The user closed the dialog. Clean up and call cancel. - SystemAppProxy.removeEventListener("mozContentEvent", getAssertion); - removeMessageListeners(); - aMessageCallback({json: {method: "cancel"}}); - } else { - // The window has opened. Inject the identity shim file containing - // the callbacks in the content script. This could be either the - // visible popup that the user interacts with, or it could be an - // invisible frame. - let frame = evt.detail.frame; - let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader; - mm = frameLoader.messageManager; - try { - mm.loadFrameScript(kIdentityShimFile, true, true); - log("Loaded shim", kIdentityShimFile); - } catch (e) { - log("Error loading", kIdentityShimFile, "as a frame script:", e); - } - - // There are two messages that the delegate can send back: a "do - // method" event, and a "finished" event. We pass the do-method - // events straight to the caller for interpretation and handling. - // If we receive a "finished" event, then the delegate is done, so - // we shut down the pipe and clean up. - mm.addMessageListener(kIdentityControllerDoMethod, aMessageCallback); - mm.addMessageListener(kIdentityDelegateFinished, identityDelegateFinished); - - mm.sendAsyncMessage(aContentOptions.message, aRpOptions); - } - break; - - case kDoneIdentityDialog + '-' + uuid: - // Received our assertion. The message manager callbacks will handle - // communicating back to the IDService. All we have to do is remove - // this listener. - SystemAppProxy.removeEventListener("mozContentEvent", getAssertion); - break; - - default: - log("ERROR - Unexpected message: id=" + msg.id + ", type=" + msg.type + ", errorMsg=" + msg.errorMsg); - break; - } - - }); - - // Tell content to open the identity iframe or trusty popup. The parameter - // showUI signals whether user interaction is needed. If it is, content will - // open a dialog; if not, a hidden iframe. In each case, BrowserID is - // available in the context. - let detail = { - type: kOpenIdentityDialog, - showUI: aContentOptions.showUI || false, - id: kOpenIdentityDialog + "-" + uuid, - requestId: aRpOptions.id - }; - - sendChromeEvent(detail); - } - -}; - -/* - * The controller sits between the IdentityService used by DOMIdentity - * and a content process launches an (invisible) iframe or (visible) - * trusty UI. Using an injected js script (identity.js), the - * controller enables the content window to access the persona identity - * storage in the system cookie jar and send events back via the - * controller into IdentityService and DOM, and ultimately up to the - * Relying Party, which is open in a different window context. - */ -this.SignInToWebsiteController = { - - /* - * Initialize the controller. To use a different content communication pipe, - * such as when mocking it in tests, pass aOptions.pipe. - */ - init: function SignInToWebsiteController_init(aOptions) { - aOptions = aOptions || {}; - this.pipe = aOptions.pipe || new Pipe(); - Services.obs.addObserver(this, "identity-controller-watch", false); - Services.obs.addObserver(this, "identity-controller-request", false); - Services.obs.addObserver(this, "identity-controller-logout", false); - }, - - uninit: function SignInToWebsiteController_uninit() { - Services.obs.removeObserver(this, "identity-controller-watch"); - Services.obs.removeObserver(this, "identity-controller-request"); - Services.obs.removeObserver(this, "identity-controller-logout"); - }, - - observe: function SignInToWebsiteController_observe(aSubject, aTopic, aData) { - log("observe: received", aTopic, "with", aData, "for", aSubject); - let options = null; - if (aSubject) { - options = aSubject.wrappedJSObject; - } - switch (aTopic) { - case "identity-controller-watch": - this.doWatch(options); - break; - case "identity-controller-request": - this.doRequest(options); - break; - case "identity-controller-logout": - this.doLogout(options); - break; - default: - Logger.reportError("SignInToWebsiteController", "Unknown observer notification:", aTopic); - break; - } - }, - - /* - * options: method required - name of method to invoke - * assertion optional - */ - _makeDoMethodCallback: function SignInToWebsiteController__makeDoMethodCallback(aRpId) { - return function SignInToWebsiteController_methodCallback(aOptions) { - let message = aOptions.json; - if (typeof message === 'string') { - message = JSON.parse(message); - } - - switch (message.method) { - case "ready": - IdentityService.doReady(aRpId); - break; - - case "login": - if (message._internalParams) { - IdentityService.doLogin(aRpId, message.assertion, message._internalParams); - } else { - IdentityService.doLogin(aRpId, message.assertion); - } - break; - - case "logout": - IdentityService.doLogout(aRpId); - break; - - case "cancel": - IdentityService.doCancel(aRpId); - break; - - default: - log("WARNING: wonky method call:", message.method); - break; - } - }; - }, - - doWatch: function SignInToWebsiteController_doWatch(aRpOptions) { - // dom prevents watch from being called twice - let contentOptions = { - message: kIdentityDelegateWatch, - showUI: false - }; - this.pipe.communicate(aRpOptions, contentOptions, - this._makeDoMethodCallback(aRpOptions.id)); - }, - - /** - * The website is requesting login so the user must choose an identity to use. - */ - doRequest: function SignInToWebsiteController_doRequest(aRpOptions) { - log("doRequest", aRpOptions); - let contentOptions = { - message: kIdentityDelegateRequest, - showUI: true - }; - this.pipe.communicate(aRpOptions, contentOptions, - this._makeDoMethodCallback(aRpOptions.id)); - }, - - /* - * - */ - doLogout: function SignInToWebsiteController_doLogout(aRpOptions) { - log("doLogout", aRpOptions); - let contentOptions = { - message: kIdentityDelegateLogout, - showUI: false - }; - this.pipe.communicate(aRpOptions, contentOptions, - this._makeDoMethodCallback(aRpOptions.id)); - } - -}; diff --git a/b2g/components/SimulatorScreen.js b/b2g/components/SimulatorScreen.js deleted file mode 100644 index 18d8f5cc4..000000000 --- a/b2g/components/SimulatorScreen.js +++ /dev/null @@ -1,117 +0,0 @@ -/* 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/. */ - -var Ci = Components.interfaces; -var Cu = Components.utils; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/Services.jsm'); -Cu.import('resource://gre/modules/DOMRequestHelper.jsm'); - -XPCOMUtils.defineLazyModuleGetter(this, 'GlobalSimulatorScreen', - 'resource://gre/modules/GlobalSimulatorScreen.jsm'); - -var DEBUG_PREFIX = 'SimulatorScreen.js - '; -function debug() { - //dump(DEBUG_PREFIX + Array.slice(arguments) + '\n'); -} - -function fireOrientationEvent(window) { - let e = new window.Event('mozorientationchange'); - window.screen.dispatchEvent(e); -} - -function hookScreen(window) { - let nodePrincipal = window.document.nodePrincipal; - let origin = nodePrincipal.origin; - if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) { - // Only inject screen mock for apps - return; - } - - let screen = window.wrappedJSObject.screen; - - screen.mozLockOrientation = function (orientation) { - debug('mozLockOrientation:', orientation, 'from', origin); - - // Normalize and do some checks against orientation input - if (typeof(orientation) == 'string') { - orientation = [orientation]; - } - - function isInvalidOrientationString(str) { - return typeof(str) != 'string' || - !str.match(/^default$|^(portrait|landscape)(-(primary|secondary))?$/); - } - if (!Array.isArray(orientation) || - orientation.some(isInvalidOrientationString)) { - Cu.reportError('Invalid orientation "' + orientation + '"'); - return false; - } - - GlobalSimulatorScreen.lock(orientation); - - return true; - }; - - screen.mozUnlockOrientation = function() { - debug('mozOrientationUnlock from', origin); - GlobalSimulatorScreen.unlock(); - return true; - }; - - Object.defineProperty(screen, 'width', { - get: () => GlobalSimulatorScreen.width - }); - Object.defineProperty(screen, 'height', { - get: () => GlobalSimulatorScreen.height - }); - Object.defineProperty(screen, 'mozOrientation', { - get: () => GlobalSimulatorScreen.mozOrientation - }); -} - -function SimulatorScreen() {} -SimulatorScreen.prototype = { - classID: Components.ID('{c83c02c0-5d43-4e3e-987f-9173b313e880}'), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, - Ci.nsISupportsWeakReference]), - _windows: new Map(), - - observe: function (subject, topic, data) { - let windows = this._windows; - switch (topic) { - case 'profile-after-change': - Services.obs.addObserver(this, 'document-element-inserted', false); - Services.obs.addObserver(this, 'simulator-orientation-change', false); - Services.obs.addObserver(this, 'inner-window-destroyed', false); - break; - - case 'document-element-inserted': - let window = subject.defaultView; - if (!window) { - return; - } - - hookScreen(window); - - var id = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .currentInnerWindowID; - windows.set(id, window); - break; - - case 'inner-window-destroyed': - var id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; - windows.delete(id); - break; - - case 'simulator-orientation-change': - windows.forEach(fireOrientationEvent); - break; - } - } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SimulatorScreen]); diff --git a/b2g/components/SmsProtocolHandler.js b/b2g/components/SmsProtocolHandler.js deleted file mode 100644 index c54018fcf..000000000 --- a/b2g/components/SmsProtocolHandler.js +++ /dev/null @@ -1,74 +0,0 @@ -/* 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/. */ - -/** - * SmsProtocolHandle.js - * - * This file implements the URLs for SMS - * https://www.rfc-editor.org/rfc/rfc5724.txt - */ - -"use strict"; - - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import("resource:///modules/TelURIParser.jsm"); -Cu.import('resource://gre/modules/ActivityChannel.jsm'); - -function SmsProtocolHandler() { -} - -SmsProtocolHandler.prototype = { - - scheme: "sms", - defaultPort: -1, - protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE | - Ci.nsIProtocolHandler.URI_NOAUTH | - Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE | - Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA, - allowPort: () => false, - - newURI: function Proto_newURI(aSpec, aOriginCharset) { - let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI); - uri.spec = aSpec; - return uri; - }, - - newChannel2: function Proto_newChannel2(aURI, aLoadInfo) { - let number = TelURIParser.parseURI('sms', aURI.spec); - let body = ""; - let query = aURI.spec.split("?")[1]; - - if (query) { - let params = query.split("&"); - params.forEach(function(aParam) { - let [name, value] = aParam.split("="); - if (name === "body") { - body = decodeURIComponent(value); - } - }) - } - - if (number || body) { - return new ActivityChannel(aURI, aLoadInfo, - "sms-handler", - { number: number || "", - type: "websms/sms", - body: body }); - } - - throw Components.results.NS_ERROR_ILLEGAL_VALUE; - }, - - newChannel: function Proto_newChannel(aURI) { - return this.newChannel2(aURI, null); - }, - - classID: Components.ID("{81ca20cb-0dad-4e32-8566-979c8998bd73}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsProtocolHandler]); diff --git a/b2g/components/SystemAppProxy.jsm b/b2g/components/SystemAppProxy.jsm deleted file mode 100644 index b3d5843fc..000000000 --- a/b2g/components/SystemAppProxy.jsm +++ /dev/null @@ -1,377 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- / -/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ -/* 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/. */ - -'use strict'; - -const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import('resource://gre/modules/Services.jsm'); - -this.EXPORTED_SYMBOLS = ['SystemAppProxy']; - -const kMainSystemAppId = 'main'; - -var SystemAppProxy = { - _frameInfoMap: new Map(), - _pendingLoadedEvents: [], - _pendingReadyEvents: [], - _pendingListeners: [], - - // To call when a main system app iframe is created - // Only used for main system app. - registerFrame: function systemApp_registerFrame(frame) { - this.registerFrameWithId(kMainSystemAppId, frame); - }, - - // To call when a new system(-remote) app iframe is created with ID - registerFrameWithId: function systemApp_registerFrameWithId(frameId, - frame) { - // - Frame ID of main system app is predefined as 'main'. - // - Frame ID of system-remote app is defined themselves. - // - // frameInfo = { - // isReady: ..., - // isLoaded: ..., - // frame: ... - // } - - let frameInfo = { frameId: frameId, - isReady: false, - isLoaded: false, - frame: frame }; - - this._frameInfoMap.set(frameId, frameInfo); - - // Register all DOM event listeners added before we got a ref to - // this system app iframe. - this._pendingListeners - .forEach(args => { - if (args[0] === frameInfo.frameId) { - this.addEventListenerWithId.apply(this, args); - } - }); - // Removed registered event listeners. - this._pendingListeners = - this._pendingListeners - .filter(args => { return args[0] != frameInfo.frameId; }); - }, - - unregisterFrameWithId: function systemApp_unregisterFrameWithId(frameId) { - this._frameInfoMap.delete(frameId); - // remove all pending event listener to the deleted system(-remote) app - this._pendingListeners = this._pendingListeners.filter( - args => { return args[0] != frameId; }); - this._pendingReadyEvents = this._pendingReadyEvents.filter( - ([evtFrameId]) => { return evtFrameId != frameId }); - this._pendingLoadedEvents = this._pendingLoadedEvents.filter( - ([evtFrameId]) => { return evtFrameId != frameId }); - }, - - // Get the main system app frame - _getMainSystemAppInfo: function systemApp_getMainSystemAppInfo() { - return this._frameInfoMap.get(kMainSystemAppId); - }, - - // Get the main system app frame - // Only used for the main system app. - getFrame: function systemApp_getFrame() { - return this.getFrameWithId(kMainSystemAppId); - }, - - // Get the frame of the specific system app - getFrameWithId: function systemApp_getFrameWithId(frameId) { - let frameInfo = this._frameInfoMap.get(frameId); - - if (!frameInfo) { - throw new Error('no frame ID is ' + frameId); - } - if (!frameInfo.frame) { - throw new Error('no content window'); - } - return frameInfo.frame; - }, - - // To call when the load event of the main system app document is triggered. - // i.e. everything that is not lazily loaded are run and done. - // Only used for the main system app. - setIsLoaded: function systemApp_setIsLoaded() { - this.setIsLoadedWithId(kMainSystemAppId); - }, - - // To call when the load event of the specific system app document is - // triggered. i.e. everything that is not lazily loaded are run and done. - setIsLoadedWithId: function systemApp_setIsLoadedWithId(frameId) { - let frameInfo = this._frameInfoMap.get(frameId); - if (!frameInfo) { - throw new Error('no frame ID is ' + frameId); - } - - if (frameInfo.isLoaded) { - if (frameInfo.frameId === kMainSystemAppId) { - Cu.reportError('SystemApp has already been declared as being loaded.'); - } - else { - Cu.reportError('SystemRemoteApp (ID: ' + frameInfo.frameId + ') ' + - 'has already been declared as being loaded.'); - } - } - - frameInfo.isLoaded = true; - - // Dispatch all events being queued while the system app was still loading - this._pendingLoadedEvents - .forEach(([evtFrameId, evtType, evtDetails]) => { - if (evtFrameId === frameInfo.frameId) { - this.sendCustomEventWithId(evtFrameId, evtType, evtDetails, true); - } - }); - // Remove sent events. - this._pendingLoadedEvents = - this._pendingLoadedEvents - .filter(([evtFrameId]) => { return evtFrameId != frameInfo.frameId }); - }, - - // To call when the main system app is ready to receive events - // i.e. when system-message-listener-ready mozContentEvent is sent. - // Only used for the main system app. - setIsReady: function systemApp_setIsReady() { - this.setIsReadyWithId(kMainSystemAppId); - }, - - // To call when the specific system(-remote) app is ready to receive events - // i.e. when system-message-listener-ready mozContentEvent is sent. - setIsReadyWithId: function systemApp_setIsReadyWithId(frameId) { - let frameInfo = this._frameInfoMap.get(frameId); - if (!frameInfo) { - throw new Error('no frame ID is ' + frameId); - } - - if (!frameInfo.isLoaded) { - Cu.reportError('SystemApp.setIsLoaded() should be called before setIsReady().'); - } - - if (frameInfo.isReady) { - Cu.reportError('SystemApp has already been declared as being ready.'); - } - - frameInfo.isReady = true; - - // Dispatch all events being queued while the system app was still not ready - this._pendingReadyEvents - .forEach(([evtFrameId, evtType, evtDetails]) => { - if (evtFrameId === frameInfo.frameId) { - this.sendCustomEventWithId(evtFrameId, evtType, evtDetails); - } - }); - - // Remove sent events. - this._pendingReadyEvents = - this._pendingReadyEvents - .filter(([evtFrameId]) => { return evtFrameId != frameInfo.frameId }); - }, - - /* - * Common way to send an event to the main system app. - * Only used for the main system app. - * - * // In gecko code: - * SystemAppProxy.sendCustomEvent('foo', { data: 'bar' }); - * // In system app: - * window.addEventListener('foo', function (event) { - * event.details == 'bar' - * }); - * - * @param type The custom event type. - * @param details The event details. - * @param noPending Set to true to emit this event even before the system - * app is ready. - * Event is always pending if the app is not loaded yet. - * @param target The element who dispatch this event. - * - * @returns event? Dispatched event, or null if the event is pending. - */ - _sendCustomEvent: function systemApp_sendCustomEvent(type, - details, - noPending, - target) { - let args = Array.prototype.slice.call(arguments); - return this.sendCustomEventWithId - .apply(this, [kMainSystemAppId].concat(args)); - }, - - /* - * Common way to send an event to the specific system app. - * - * // In gecko code (send custom event from main system app): - * SystemAppProxy.sendCustomEventWithId('main', 'foo', { data: 'bar' }); - * // In system app: - * window.addEventListener('foo', function (event) { - * event.details == 'bar' - * }); - * - * @param frameId Specify the system(-remote) app who dispatch this event. - * @param type The custom event type. - * @param details The event details. - * @param noPending Set to true to emit this event even before the system - * app is ready. - * Event is always pending if the app is not loaded yet. - * @param target The element who dispatch this event. - * - * @returns event? Dispatched event, or null if the event is pending. - */ - sendCustomEventWithId: function systemApp_sendCustomEventWithId(frameId, - type, - details, - noPending, - target) { - let frameInfo = this._frameInfoMap.get(frameId); - let content = (frameInfo && frameInfo.frame) ? - frameInfo.frame.contentWindow : null; - // If the system app isn't loaded yet, - // queue events until someone calls setIsLoaded - if (!content || !(frameInfo && frameInfo.isLoaded)) { - if (noPending) { - this._pendingLoadedEvents.push([frameId, type, details]); - } else { - this._pendingReadyEvents.push([frameId, type, details]); - } - return null; - } - - // If the system app isn't ready yet, - // queue events until someone calls setIsReady - if (!(frameInfo && frameInfo.isReady) && !noPending) { - this._pendingReadyEvents.push([frameId, type, details]); - return null; - } - - let event = content.document.createEvent('CustomEvent'); - - let payload; - // If the root object already has __exposedProps__, - // we consider the caller already wrapped (correctly) the object. - if ('__exposedProps__' in details) { - payload = details; - } else { - payload = details ? Cu.cloneInto(details, content) : {}; - } - - if ((target || content) === frameInfo.frame.contentWindow) { - dump('XXX FIXME : Dispatch a ' + type + ': ' + details.type + '\n'); - } - - event.initCustomEvent(type, true, false, payload); - (target || content).dispatchEvent(event); - - return event; - }, - - // Now deprecated, use sendCustomEvent with a custom event name - dispatchEvent: function systemApp_dispatchEvent(details, target) { - return this._sendCustomEvent('mozChromeEvent', details, false, target); - }, - - dispatchKeyboardEvent: function systemApp_dispatchKeyboardEvent(type, details) { - try { - let frameInfo = this._getMainSystemAppInfo(); - let content = (frameInfo && frameInfo.frame) ? frameInfo.frame.contentWindow - : null; - if (!content) { - throw new Error('no content window'); - } - // If we don't already have a TextInputProcessor, create one now - if (!this.TIP) { - this.TIP = Cc['@mozilla.org/text-input-processor;1'] - .createInstance(Ci.nsITextInputProcessor); - if (!this.TIP) { - throw new Error('failed to create textInputProcessor'); - } - } - - if (!this.TIP.beginInputTransactionForTests(content)) { - this.TIP = null; - throw new Error('beginInputTransaction failed'); - } - - let e = new content.KeyboardEvent('', { key: details.key, }); - - if (type === 'keydown') { - this.TIP.keydown(e); - } - else if (type === 'keyup') { - this.TIP.keyup(e); - } - else { - throw new Error('unexpected event type: ' + type); - } - } - catch(e) { - dump('dispatchKeyboardEvent: ' + e + '\n'); - } - }, - - // Listen for dom events on the main system app - addEventListener: function systemApp_addEventListener() { - let args = Array.prototype.slice.call(arguments); - this.addEventListenerWithId.apply(this, [kMainSystemAppId].concat(args)); - }, - - // Listen for dom events on the specific system app - addEventListenerWithId: function systemApp_addEventListenerWithId(frameId, - ...args) { - let frameInfo = this._frameInfoMap.get(frameId); - - if (!frameInfo) { - this._pendingListeners.push(arguments); - return false; - } - - let content = frameInfo.frame.contentWindow; - content.addEventListener.apply(content, args); - return true; - }, - - // remove the event listener from the main system app - removeEventListener: function systemApp_removeEventListener(name, listener) { - this.removeEventListenerWithId.apply(this, [kMainSystemAppId, name, listener]); - }, - - // remove the event listener from the specific system app - removeEventListenerWithId: function systemApp_removeEventListenerWithId(frameId, - name, - listener) { - let frameInfo = this._frameInfoMap.get(frameId); - - if (frameInfo) { - let content = frameInfo.frame.contentWindow; - content.removeEventListener.apply(content, [name, listener]); - } - else { - this._pendingListeners = this._pendingListeners.filter( - args => { - return args[0] != frameId || args[1] != name || args[2] != listener; - }); - } - }, - - // Get all frame in system app - getFrames: function systemApp_getFrames(frameId) { - let frameList = []; - - for (let frameId of this._frameInfoMap.keys()) { - let frameInfo = this._frameInfoMap.get(frameId); - let systemAppFrame = frameInfo.frame; - let subFrames = systemAppFrame.contentDocument.querySelectorAll('iframe'); - frameList.push(systemAppFrame); - for (let i = 0; i < subFrames.length; ++i) { - frameList.push(subFrames[i]); - } - } - return frameList; - } -}; -this.SystemAppProxy = SystemAppProxy; diff --git a/b2g/components/SystemMessageInternal.js b/b2g/components/SystemMessageInternal.js deleted file mode 100644 index 287496a50..000000000 --- a/b2g/components/SystemMessageInternal.js +++ /dev/null @@ -1,64 +0,0 @@ -/* 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/. */ - -"use strict"; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/SystemAppProxy.jsm"); - -function debug(aMsg) { - dump("-- SystemMessageInternal " + Date.now() + " : " + aMsg + "\n"); -} - -// Implementation of the component used by internal users. - -function SystemMessageInternal() { -} - -SystemMessageInternal.prototype = { - - sendMessage: function(aType, aMessage, aPageURI, aManifestURI, aExtra) { - debug(`sendMessage ${aType} ${aMessage} ${aPageURI} ${aExtra}`); - SystemAppProxy._sendCustomEvent("mozSystemMessage", { - action: "send", - type: aType, - message: aMessage, - pageURI: aPageURI, - extra: aExtra - }); - return Promise.resolve(); - }, - - broadcastMessage: function(aType, aMessage, aExtra) { - debug(`broadcastMessage ${aType} ${aMessage} ${aExtra}`); - SystemAppProxy._sendCustomEvent("mozSystemMessage", { - action: "broadcast", - type: aType, - message: aMessage, - extra: aExtra - }); - return Promise.resolve(); - }, - - registerPage: function(aType, aPageURI, aManifestURI) { - SystemAppProxy._sendCustomEvent("mozSystemMessage", { - action: "register", - type: aType, - pageURI: aPageURI - }); - debug(`registerPage ${aType} ${aPageURI} ${aManifestURI}`); - }, - - classID: Components.ID("{70589ca5-91ac-4b9e-b839-d6a88167d714}"), - - QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesInternal]) -} - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SystemMessageInternal]); diff --git a/b2g/components/TelProtocolHandler.js b/b2g/components/TelProtocolHandler.js deleted file mode 100644 index 021cbcd61..000000000 --- a/b2g/components/TelProtocolHandler.js +++ /dev/null @@ -1,60 +0,0 @@ -/* 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/. */ - -/** - * TelProtocolHandle.js - * - * This file implements the URLs for Telephone Calls - * https://www.ietf.org/rfc/rfc2806.txt - */ - -"use strict"; - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; - -Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -Cu.import("resource:///modules/TelURIParser.jsm"); -Cu.import('resource://gre/modules/ActivityChannel.jsm'); - -function TelProtocolHandler() { -} - -TelProtocolHandler.prototype = { - - scheme: "tel", - defaultPort: -1, - protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE | - Ci.nsIProtocolHandler.URI_NOAUTH | - Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE | - Ci.nsIProtocolHandler.URI_DOES_NOT_RETURN_DATA, - allowPort: () => false, - - newURI: function Proto_newURI(aSpec, aOriginCharset) { - let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI); - uri.spec = aSpec; - return uri; - }, - - newChannel2: function Proto_newChannel(aURI, aLoadInfo) { - let number = TelURIParser.parseURI('tel', aURI.spec); - - if (number) { - return new ActivityChannel(aURI, aLoadInfo, - "dial-handler", - { number: number, - type: "webtelephony/number" }); - } - - throw Components.results.NS_ERROR_ILLEGAL_VALUE; - }, - - newChannel: function Proto_newChannel(aURI) { - return this.newChannel2(aURI, null); - }, - - classID: Components.ID("{782775dd-7351-45ea-aff1-0ffa872cfdd2}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler]) -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TelProtocolHandler]); diff --git a/b2g/components/TelURIParser.jsm b/b2g/components/TelURIParser.jsm deleted file mode 100644 index 46b0bb8fd..000000000 --- a/b2g/components/TelURIParser.jsm +++ /dev/null @@ -1,120 +0,0 @@ -/* 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/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["TelURIParser"]; - -/** - * Singleton providing functionality for parsing tel: and sms: URIs - */ -this.TelURIParser = { - parseURI: function(scheme, uri) { - // https://www.ietf.org/rfc/rfc2806.txt - let subscriber = decodeURIComponent(uri.slice((scheme + ':').length)); - - if (!subscriber.length) { - return null; - } - - let number = ''; - let pos = 0; - let len = subscriber.length; - - // visual-separator - let visualSeparator = [ ' ', '-', '.', '(', ')' ]; - let digits = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ]; - let dtmfDigits = [ '*', '#', 'A', 'B', 'C', 'D' ]; - let pauseCharacter = [ 'p', 'w' ]; - - // global-phone-number - if (subscriber[pos] == '+') { - number += '+'; - for (++pos; pos < len; ++pos) { - if (visualSeparator.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else if (digits.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else { - break; - } - } - } - // local-phone-number - else { - for (; pos < len; ++pos) { - if (visualSeparator.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else if (digits.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) { - number += subscriber[pos]; - } else { - break; - } - } - - // this means error - if (!number.length) { - return null; - } - - // isdn-subaddress - if (subscriber.substring(pos, pos + 6) == ';isub=') { - let subaddress = ''; - - for (pos += 6; pos < len; ++pos) { - if (visualSeparator.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else if (digits.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else { - break; - } - } - - // FIXME: ignore subaddress - Bug 795242 - } - - // post-dial - if (subscriber.substring(pos, pos + 7) == ';postd=') { - let subaddress = ''; - - for (pos += 7; pos < len; ++pos) { - if (visualSeparator.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else if (digits.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else if (dtmfDigits.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else if (pauseCharacter.indexOf(subscriber[pos]) != -1) { - subaddress += subscriber[pos]; - } else { - break; - } - } - - // FIXME: ignore subaddress - Bug 795242 - } - - // area-specific - if (subscriber.substring(pos, pos + 15) == ';phone-context=') { - pos += 15; - - // global-network-prefix | local-network-prefix | private-prefi - number = subscriber.substring(pos, subscriber.length) + number; - } - } - - // Ignore MWI and USSD codes. See 794034. - if (number.match(/[#\*]/) && !number.match(/^[#\*]\d+$/)) { - return null; - } - - return number || null; - } -}; - diff --git a/b2g/components/UpdatePrompt.js b/b2g/components/UpdatePrompt.js deleted file mode 100644 index 1df07204c..000000000 --- a/b2g/components/UpdatePrompt.js +++ /dev/null @@ -1,783 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- - * vim: sw=2 ts=8 et : - */ -/* 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/. */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; -const Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -const VERBOSE = 1; -var log = - VERBOSE ? - function log_dump(msg) { dump("UpdatePrompt: "+ msg +"\n"); } : - function log_noop(msg) { }; - -const PREF_APPLY_PROMPT_TIMEOUT = "b2g.update.apply-prompt-timeout"; -const PREF_APPLY_IDLE_TIMEOUT = "b2g.update.apply-idle-timeout"; -const PREF_DOWNLOAD_WATCHDOG_TIMEOUT = "b2g.update.download-watchdog-timeout"; -const PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES = "b2g.update.download-watchdog-max-retries"; - -const NETWORK_ERROR_OFFLINE = 111; -const HTTP_ERROR_OFFSET = 1000; - -const STATE_DOWNLOADING = 'downloading'; - -XPCOMUtils.defineLazyServiceGetter(Services, "aus", - "@mozilla.org/updates/update-service;1", - "nsIApplicationUpdateService"); - -XPCOMUtils.defineLazyServiceGetter(Services, "um", - "@mozilla.org/updates/update-manager;1", - "nsIUpdateManager"); - -XPCOMUtils.defineLazyServiceGetter(Services, "idle", - "@mozilla.org/widget/idleservice;1", - "nsIIdleService"); - -XPCOMUtils.defineLazyServiceGetter(Services, "settings", - "@mozilla.org/settingsService;1", - "nsISettingsService"); - -XPCOMUtils.defineLazyServiceGetter(Services, 'env', - '@mozilla.org/process/environment;1', - 'nsIEnvironment'); - -function useSettings() { - // When we're running in the real phone, then we can use settings. - // But when we're running as part of xpcshell, there is no settings database - // and trying to use settings in this scenario causes lots of weird - // assertions at shutdown time. - if (typeof useSettings.result === "undefined") { - useSettings.result = !Services.env.get("XPCSHELL_TEST_PROFILE_DIR"); - } - return useSettings.result; -} - -XPCOMUtils.defineLazyModuleGetter(this, "SystemAppProxy", - "resource://gre/modules/SystemAppProxy.jsm"); - -function UpdateCheckListener(updatePrompt) { - this._updatePrompt = updatePrompt; -} - -UpdateCheckListener.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateCheckListener]), - - _updatePrompt: null, - - onCheckComplete: function UCL_onCheckComplete(request, updates, updateCount) { - if (Services.um.activeUpdate) { - // We're actively downloading an update, that's the update the user should - // see, even if a newer update is available. - this._updatePrompt.setUpdateStatus("active-update"); - this._updatePrompt.showUpdateAvailable(Services.um.activeUpdate); - return; - } - - if (updateCount == 0) { - this._updatePrompt.setUpdateStatus("no-updates"); - - if (this._updatePrompt._systemUpdateListener) { - this._updatePrompt._systemUpdateListener.onError("no-updates"); - } - - return; - } - - let update = Services.aus.selectUpdate(updates, updateCount); - if (!update) { - this._updatePrompt.setUpdateStatus("already-latest-version"); - - if (this._updatePrompt._systemUpdateListener) { - this._updatePrompt._systemUpdateListener.onError("already-latest-version"); - } - - return; - } - - this._updatePrompt.setUpdateStatus("check-complete"); - this._updatePrompt.showUpdateAvailable(update); - }, - - onError: function UCL_onError(request, update) { - // nsIUpdate uses a signed integer for errorCode while any platform errors - // require all 32 bits. - let errorCode = update.errorCode >>> 0; - let isNSError = (errorCode >>> 31) == 1; - let errorMsg = "check-error-"; - - if (errorCode == NETWORK_ERROR_OFFLINE) { - errorMsg = "retry-when-online"; - this._updatePrompt.setUpdateStatus(errorMsg); - } else if (isNSError) { - errorMsg = "check-error-" + errorCode; - this._updatePrompt.setUpdateStatus(errorMsg); - } else if (errorCode > HTTP_ERROR_OFFSET) { - let httpErrorCode = errorCode - HTTP_ERROR_OFFSET; - errorMsg = "check-error-http-" + httpErrorCode; - this._updatePrompt.setUpdateStatus(errorMsg); - } - - if (this._updatePrompt._systemUpdateListener) { - this._updatePrompt._systemUpdateListener.onError(errorMsg); - } - - Services.aus.QueryInterface(Ci.nsIUpdateCheckListener); - Services.aus.onError(request, update); - } -}; - -function UpdatePrompt() { - this.wrappedJSObject = this; - this._updateCheckListener = new UpdateCheckListener(this); -} - -UpdatePrompt.prototype = { - classID: Components.ID("{88b3eb21-d072-4e3b-886d-f89d8c49fe59}"), - QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt, - Ci.nsIUpdateCheckListener, - Ci.nsIRequestObserver, - Ci.nsIProgressEventSink, - Ci.nsIObserver, - Ci.nsISystemUpdateProvider]), - _xpcom_factory: XPCOMUtils.generateSingletonFactory(UpdatePrompt), - - _update: null, - _applyPromptTimer: null, - _waitingForIdle: false, - _updateCheckListner: null, - _systemUpdateListener: null, - _availableParameters: { - "deviceinfo.last_updated": null, - "gecko.updateStatus": null, - "app.update.channel": null, - "app.update.interval": null, - "app.update.url": null, - }, - _pendingUpdateAvailablePackageInfo: null, - _isPendingUpdateReady: false, - _updateErrorQueue: [ ], - _receivedUpdatePromptReady: false, - - // nsISystemUpdateProvider - checkForUpdate: function() { - this.forceUpdateCheck(); - }, - - startDownload: function() { - this.downloadUpdate(this._update); - }, - - stopDownload: function() { - this.handleDownloadCancel(); - }, - - applyUpdate: function() { - this.handleApplyPromptResult({result: "restart"}); - }, - - setParameter: function(aName, aValue) { - if (!this._availableParameters.hasOwnProperty(aName)) { - return false; - } - - this._availableParameters[aName] = aValue; - - switch (aName) { - case "app.update.channel": - case "app.update.url": - Services.prefs.setCharPref(aName, aValue); - break; - case "app.update.interval": - Services.prefs.setIntPref(aName, parseInt(aValue, 10)); - break; - } - - return true; - }, - - getParameter: function(aName) { - if (!this._availableParameters.hasOwnProperty(aName)) { - return null; - } - - return this._availableParameters[aName]; - }, - - setListener: function(aListener) { - this._systemUpdateListener = aListener; - - // If an update is available or ready, trigger the event right away at this point. - if (this._pendingUpdateAvailablePackageInfo) { - this._systemUpdateListener.onUpdateAvailable(this._pendingUpdateAvailablePackageInfo.type, - this._pendingUpdateAvailablePackageInfo.version, - this._pendingUpdateAvailablePackageInfo.description, - this._pendingUpdateAvailablePackageInfo.buildDate, - this._pendingUpdateAvailablePackageInfo.size); - // Set null when the listener is attached. - this._pendingUpdateAvailablePackageInfo = null; - } - - if (this._isPendingUpdateReady) { - this._systemUpdateListener.onUpdateReady(); - this._isPendingUpdateReady = false; - } - }, - - unsetListener: function(aListener) { - this._systemUpdateListener = null; - }, - - get applyPromptTimeout() { - return Services.prefs.getIntPref(PREF_APPLY_PROMPT_TIMEOUT); - }, - - get applyIdleTimeout() { - return Services.prefs.getIntPref(PREF_APPLY_IDLE_TIMEOUT); - }, - - handleContentStart: function UP_handleContentStart() { - SystemAppProxy.addEventListener("mozContentEvent", this); - }, - - // nsIUpdatePrompt - - // FIXME/bug 737601: we should have users opt-in to downloading - // updates when on a billed pipe. Initially, opt-in for 3g, but - // that doesn't cover all cases. - checkForUpdates: function UP_checkForUpdates() { }, - - showUpdateAvailable: function UP_showUpdateAvailable(aUpdate) { - let packageInfo = {}; - packageInfo.version = aUpdate.displayVersion; - packageInfo.description = aUpdate.statusText; - packageInfo.buildDate = aUpdate.buildID; - - let patch = aUpdate.selectedPatch; - if (!patch && aUpdate.patchCount > 0) { - // For now we just check the first patch to get size information if a - // patch hasn't been selected yet. - patch = aUpdate.getPatchAt(0); - } - - if (patch) { - packageInfo.size = patch.size; - packageInfo.type = patch.type; - } else { - log("Warning: no patches available in update"); - } - - this._pendingUpdateAvailablePackageInfo = packageInfo; - - if (this._systemUpdateListener) { - this._systemUpdateListener.onUpdateAvailable(packageInfo.type, - packageInfo.version, - packageInfo.description, - packageInfo.buildDate, - packageInfo.size); - // Set null since the event is fired. - this._pendingUpdateAvailablePackageInfo = null; - } - - if (!this.sendUpdateEvent("update-available", aUpdate)) { - - log("Unable to prompt for available update, forcing download"); - this.downloadUpdate(aUpdate); - } - }, - - showUpdateDownloaded: function UP_showUpdateDownloaded(aUpdate, aBackground) { - if (this._systemUpdateListener) { - this._systemUpdateListener.onUpdateReady(); - } else { - this._isPendingUpdateReady = true; - } - - // The update has been downloaded and staged. We send the update-downloaded - // event right away. After the user has been idle for a while, we send the - // update-prompt-restart event, increasing the chances that we can apply the - // update quietly without user intervention. - this.sendUpdateEvent("update-downloaded", aUpdate); - - if (Services.idle.idleTime >= this.applyIdleTimeout) { - this.showApplyPrompt(aUpdate); - return; - } - - let applyIdleTimeoutSeconds = this.applyIdleTimeout / 1000; - // We haven't been idle long enough, so register an observer - log("Update is ready to apply, registering idle timeout of " + - applyIdleTimeoutSeconds + " seconds before prompting."); - - this._update = aUpdate; - this.waitForIdle(); - }, - - storeUpdateError: function UP_storeUpdateError(aUpdate) { - log("Storing update error for later use"); - this._updateErrorQueue.push(aUpdate); - }, - - sendStoredUpdateError: function UP_sendStoredUpdateError() { - log("Sending stored update error"); - this._updateErrorQueue.forEach(aUpdate => { - this.sendUpdateEvent("update-error", aUpdate); - }); - this._updateErrorQueue = [ ]; - }, - - showUpdateError: function UP_showUpdateError(aUpdate) { - log("Update error, state: " + aUpdate.state + ", errorCode: " + - aUpdate.errorCode); - if (this._systemUpdateListener) { - this._systemUpdateListener.onError("update-error: " + aUpdate.errorCode + " " + aUpdate.statusText); - } - - if (!this._receivedUpdatePromptReady) { - this.storeUpdateError(aUpdate); - } else { - this.sendUpdateEvent("update-error", aUpdate); - } - - this.setUpdateStatus(aUpdate.statusText); - }, - - showUpdateHistory: function UP_showUpdateHistory(aParent) { }, - showUpdateInstalled: function UP_showUpdateInstalled() { - this.setParameter("deviceinfo.last_updated", Date.now()); - - if (useSettings()) { - let lock = Services.settings.createLock(); - lock.set("deviceinfo.last_updated", Date.now(), null, null); - } - }, - - // Custom functions - - waitForIdle: function UP_waitForIdle() { - if (this._waitingForIdle) { - return; - } - - this._waitingForIdle = true; - Services.idle.addIdleObserver(this, this.applyIdleTimeout / 1000); - Services.obs.addObserver(this, "quit-application", false); - }, - - setUpdateStatus: function UP_setUpdateStatus(aStatus) { - this.setParameter("gecko.updateStatus", aStatus); - - if (useSettings()) { - log("Setting gecko.updateStatus: " + aStatus); - - let lock = Services.settings.createLock(); - lock.set("gecko.updateStatus", aStatus, null); - } - }, - - showApplyPrompt: function UP_showApplyPrompt(aUpdate) { - // Notify update package is ready to apply - if (this._systemUpdateListener) { - this._systemUpdateListener.onUpdateReady(); - } else { - // Set the flag to true and fire the onUpdateReady event when the listener is attached. - this._isPendingUpdateReady = true; - } - - if (!this.sendUpdateEvent("update-prompt-apply", aUpdate)) { - log("Unable to prompt, forcing restart"); - this.restartProcess(); - return; - } - - if (AppConstants.MOZ_B2G_RIL) { - let window = Services.wm.getMostRecentWindow("navigator:browser"); - let pinReq = window.navigator.mozIccManager.getCardLock("pin"); - pinReq.onsuccess = function(e) { - if (e.target.result.enabled) { - // The SIM is pin locked. Don't use a fallback timer. This means that - // the user has to press Install to apply the update. If we use the - // timer, and the timer reboots the phone, then the phone will be - // unusable until the SIM is unlocked. - log("SIM is pin locked. Not starting fallback timer."); - } else { - // This means that no pin lock is enabled, so we go ahead and start - // the fallback timer. - this._applyPromptTimer = this.createTimer(this.applyPromptTimeout); - } - }.bind(this); - pinReq.onerror = function(e) { - this._applyPromptTimer = this.createTimer(this.applyPromptTimeout); - }.bind(this); - } else { - // Schedule a fallback timeout in case the UI is unable to respond or show - // a prompt for some reason. - this._applyPromptTimer = this.createTimer(this.applyPromptTimeout); - } - }, - - _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion", - "errorCode", "isOSUpdate", "platformVersion", - "previousAppVersion", "state", "statusText"], - - sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) { - let detail = {}; - for (let property of this._copyProperties) { - detail[property] = aUpdate[property]; - } - - let patch = aUpdate.selectedPatch; - if (!patch && aUpdate.patchCount > 0) { - // For now we just check the first patch to get size information if a - // patch hasn't been selected yet. - patch = aUpdate.getPatchAt(0); - } - - if (patch) { - detail.size = patch.size; - detail.updateType = patch.type; - } else { - log("Warning: no patches available in update"); - } - - this._update = aUpdate; - return this.sendChromeEvent(aType, detail); - }, - - sendChromeEvent: function UP_sendChromeEvent(aType, aDetail) { - let detail = aDetail || {}; - detail.type = aType; - - let sent = SystemAppProxy.dispatchEvent(detail); - if (!sent) { - log("Warning: Couldn't send update event " + aType + - ": no content browser. Will send again when content becomes available."); - return false; - } - return true; - }, - - handleAvailableResult: function UP_handleAvailableResult(aDetail) { - // If the user doesn't choose "download", the updater will implicitly call - // showUpdateAvailable again after a certain period of time - switch (aDetail.result) { - case "download": - this.downloadUpdate(this._update); - break; - } - }, - - handleApplyPromptResult: function UP_handleApplyPromptResult(aDetail) { - if (this._applyPromptTimer) { - this._applyPromptTimer.cancel(); - this._applyPromptTimer = null; - } - - switch (aDetail.result) { - // Battery not okay, do not wait for idle to re-prompt - case "low-battery": - break; - case "wait": - // Wait until the user is idle before prompting to apply the update - this.waitForIdle(); - break; - case "restart": - this.finishUpdate(); - this._update = null; - break; - } - }, - - downloadUpdate: function UP_downloadUpdate(aUpdate) { - if (!aUpdate) { - aUpdate = Services.um.activeUpdate; - if (!aUpdate) { - log("No active update found to download"); - return; - } - } - - let status = Services.aus.downloadUpdate(aUpdate, true); - if (status == STATE_DOWNLOADING) { - Services.aus.addDownloadListener(this); - return; - } - - // If the update has already been downloaded and applied, then - // Services.aus.downloadUpdate will return immediately and not - // call showUpdateDownloaded, so we detect this. - if (aUpdate.state == "applied" && aUpdate.errorCode == 0) { - this.showUpdateDownloaded(aUpdate, true); - return; - } - - log("Error downloading update " + aUpdate.name + ": " + aUpdate.errorCode); - let errorCode = aUpdate.errorCode >>> 0; - if (errorCode == Cr.NS_ERROR_FILE_TOO_BIG) { - aUpdate.statusText = "file-too-big"; - } - this.showUpdateError(aUpdate); - }, - - handleDownloadCancel: function UP_handleDownloadCancel() { - log("Pausing download"); - Services.aus.pauseDownload(); - }, - - finishUpdate: function UP_finishUpdate() { - if (!this._update.isOSUpdate) { - // Standard gecko+gaia updates will just need to restart the process - this.restartProcess(); - return; - } - - try { - Services.aus.applyOsUpdate(this._update); - } - catch (e) { - this._update.errorCode = Cr.NS_ERROR_FAILURE; - this.showUpdateError(this._update); - } - }, - - restartProcess: function UP_restartProcess() { - log("Update downloaded, restarting to apply it"); - - let callbackAfterSet = function() { - if (AppConstants.platform !== "gonk") { - let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] - .getService(Ci.nsIAppStartup); - appStartup.quit(appStartup.eForceQuit | appStartup.eRestart); - } else { - // NB: on Gonk, we rely on the system process manager to restart us. - let pmService = Cc["@mozilla.org/power/powermanagerservice;1"] - .getService(Ci.nsIPowerManagerService); - pmService.restart(); - } - } - - if (useSettings()) { - // Save current os version in deviceinfo.previous_os - let lock = Services.settings.createLock({ - handle: callbackAfterSet, - handleAbort: function(error) { - log("Abort callback when trying to set previous_os: " + error); - callbackAfterSet(); - } - }); - lock.get("deviceinfo.os", { - handle: function(name, value) { - log("Set previous_os to: " + value); - lock.set("deviceinfo.previous_os", value, null, null); - } - }); - } - }, - - forceUpdateCheck: function UP_forceUpdateCheck() { - log("Forcing update check"); - - let checker = Cc["@mozilla.org/updates/update-checker;1"] - .createInstance(Ci.nsIUpdateChecker); - checker.checkForUpdates(this._updateCheckListener, true); - }, - - handleEvent: function UP_handleEvent(evt) { - if (evt.type !== "mozContentEvent") { - return; - } - - let detail = evt.detail; - if (!detail) { - return; - } - - switch (detail.type) { - case "force-update-check": - this.forceUpdateCheck(); - break; - case "update-available-result": - this.handleAvailableResult(detail); - // If we started the apply prompt timer, this means that we're waiting - // for the user to press Later or Install Now. In this situation we - // don't want to clear this._update, becuase handleApplyPromptResult - // needs it. - if (this._applyPromptTimer == null && !this._waitingForIdle) { - this._update = null; - } - break; - case "update-download-cancel": - this.handleDownloadCancel(); - break; - case "update-prompt-apply-result": - this.handleApplyPromptResult(detail); - break; - case "update-prompt-ready": - this._receivedUpdatePromptReady = true; - this.sendStoredUpdateError(); - break; - } - }, - - // nsIObserver - - observe: function UP_observe(aSubject, aTopic, aData) { - switch (aTopic) { - case "idle": - this._waitingForIdle = false; - this.showApplyPrompt(this._update); - // Fall through - case "quit-application": - Services.idle.removeIdleObserver(this, this.applyIdleTimeout / 1000); - Services.obs.removeObserver(this, "quit-application"); - break; - } - }, - - // nsITimerCallback - - notify: function UP_notify(aTimer) { - if (aTimer == this._applyPromptTimer) { - log("Timed out waiting for result, restarting"); - this._applyPromptTimer = null; - this.finishUpdate(); - this._update = null; - return; - } - if (aTimer == this._watchdogTimer) { - log("Download watchdog fired"); - this._watchdogTimer = null; - this._autoRestartDownload = true; - Services.aus.pauseDownload(); - return; - } - }, - - createTimer: function UP_createTimer(aTimeoutMs) { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT); - return timer; - }, - - // nsIRequestObserver - - _startedSent: false, - - _watchdogTimer: null, - - _autoRestartDownload: false, - _autoRestartCount: 0, - - startWatchdogTimer: function UP_startWatchdogTimer() { - let watchdogTimeout = 120000; // 120 seconds - try { - watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT); - } catch (e) { - // This means that the preference doesn't exist. watchdogTimeout will - // retain its default assigned above. - } - if (watchdogTimeout <= 0) { - // 0 implies don't bother using the watchdog timer at all. - this._watchdogTimer = null; - return; - } - if (this._watchdogTimer) { - this._watchdogTimer.cancel(); - } else { - this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - } - this._watchdogTimer.initWithCallback(this, watchdogTimeout, - Ci.nsITimer.TYPE_ONE_SHOT); - }, - - stopWatchdogTimer: function UP_stopWatchdogTimer() { - if (this._watchdogTimer) { - this._watchdogTimer.cancel(); - this._watchdogTimer = null; - } - }, - - touchWatchdogTimer: function UP_touchWatchdogTimer() { - this.startWatchdogTimer(); - }, - - onStartRequest: function UP_onStartRequest(aRequest, aContext) { - // Wait until onProgress to send the update-download-started event, in case - // this request turns out to fail for some reason - this._startedSent = false; - this.startWatchdogTimer(); - }, - - onStopRequest: function UP_onStopRequest(aRequest, aContext, aStatusCode) { - this.stopWatchdogTimer(); - Services.aus.removeDownloadListener(this); - let paused = !Components.isSuccessCode(aStatusCode); - if (!paused) { - // The download was successful, no need to restart - this._autoRestartDownload = false; - } - if (this._autoRestartDownload) { - this._autoRestartDownload = false; - let watchdogMaxRetries = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_MAX_RETRIES); - this._autoRestartCount++; - if (this._autoRestartCount > watchdogMaxRetries) { - log("Download - retry count exceeded - error"); - // We exceeded the max retries. Treat the download like an error, - // which will give the user a chance to restart manually later. - this._autoRestartCount = 0; - if (Services.um.activeUpdate) { - this.showUpdateError(Services.um.activeUpdate); - } - return; - } - log("Download - restarting download - attempt " + this._autoRestartCount); - this.downloadUpdate(null); - return; - } - this._autoRestartCount = 0; - this.sendChromeEvent("update-download-stopped", { - paused: paused - }); - }, - - // nsIProgressEventSink - - onProgress: function UP_onProgress(aRequest, aContext, aProgress, - aProgressMax) { - if (this._systemUpdateListener) { - this._systemUpdateListener.onProgress(aProgress, aProgressMax); - } - - if (aProgress == aProgressMax) { - // The update.mar validation done by onStopRequest may take - // a while before the onStopRequest callback is made, so stop - // the timer now. - this.stopWatchdogTimer(); - } else { - this.touchWatchdogTimer(); - } - if (!this._startedSent) { - this.sendChromeEvent("update-download-started", { - total: aProgressMax - }); - this._startedSent = true; - } - - this.sendChromeEvent("update-download-progress", { - progress: aProgress, - total: aProgressMax - }); - }, - - onStatus: function UP_onStatus(aRequest, aUpdate, aStatus, aStatusArg) { } -}; - -this.NSGetFactory = XPCOMUtils.generateNSGetFactory([UpdatePrompt]); diff --git a/b2g/components/moz.build b/b2g/components/moz.build deleted file mode 100644 index 9290c5e2a..000000000 --- a/b2g/components/moz.build +++ /dev/null @@ -1,91 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -DIRS += ['test'] - -EXTRA_COMPONENTS += [ - 'AlertsService.js', - 'B2GAboutRedirector.js', - 'B2GAppMigrator.js', - 'B2GPresentationDevicePrompt.js', - 'BootstrapCommandLine.js', - 'ContentPermissionPrompt.js', - 'FilePicker.js', - 'FxAccountsUIGlue.js', - 'HelperAppDialog.js', - 'MailtoProtocolHandler.js', - 'OMAContentHandler.js', - 'PresentationRequestUIGlue.js', - 'ProcessGlobal.js', - 'SmsProtocolHandler.js', - 'SystemMessageInternal.js', - 'TelProtocolHandler.js', -] - -if CONFIG['OS_TARGET'] != 'Android': - EXTRA_COMPONENTS += [ - 'CommandLine.js', - 'OopCommandLine.js', - 'SimulatorScreen.js' - ] - -EXTRA_PP_COMPONENTS += [ - 'B2GComponents.manifest', -] - -if CONFIG['MOZ_B2G']: - EXTRA_COMPONENTS += [ - 'DirectoryProvider.js', - 'RecoveryService.js', - ] - -if CONFIG['MOZ_UPDATER']: - EXTRA_COMPONENTS += [ - 'UpdatePrompt.js', - ] - -EXTRA_JS_MODULES += [ - 'AboutServiceWorkers.jsm', - 'ActivityChannel.jsm', - 'AlertsHelper.jsm', - 'Bootstraper.jsm', - 'ContentRequestHelper.jsm', - 'DebuggerActors.js', - 'ErrorPage.jsm', - 'Frames.jsm', - 'FxAccountsMgmtService.jsm', - 'LogCapture.jsm', - 'LogParser.jsm', - 'LogShake.jsm', - 'OrientationChangeHandler.jsm', - 'SafeMode.jsm', - 'Screenshot.jsm', - 'SignInToWebsite.jsm', - 'SystemAppProxy.jsm', - 'TelURIParser.jsm', -] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk': - EXTRA_JS_MODULES += [ - 'GlobalSimulatorScreen.jsm' - ] - -XPIDL_SOURCES += [ - 'nsIGaiaChrome.idl', - 'nsISystemMessagesInternal.idl' -] - -XPIDL_MODULE = 'gaia_chrome' - -UNIFIED_SOURCES += [ - 'GaiaChrome.cpp' -] - -LOCAL_INCLUDES += [ - '/chrome' -] - -FINAL_LIBRARY = 'xul' diff --git a/b2g/components/nsIGaiaChrome.idl b/b2g/components/nsIGaiaChrome.idl deleted file mode 100644 index 8e66d8456..000000000 --- a/b2g/components/nsIGaiaChrome.idl +++ /dev/null @@ -1,15 +0,0 @@ -/* 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/. */ - -#include "nsISupports.idl" - -[scriptable, uuid(92a18a98-ab5d-4d02-a024-bdbb3bc89ce1)] -interface nsIGaiaChrome : nsISupports -{ - void register(); -}; - -%{ C++ -#define GAIACHROME_CONTRACTID "@mozilla.org/b2g/gaia-chrome;1" -%} diff --git a/b2g/components/nsISystemMessagesInternal.idl b/b2g/components/nsISystemMessagesInternal.idl deleted file mode 100644 index 775ce0315..000000000 --- a/b2g/components/nsISystemMessagesInternal.idl +++ /dev/null @@ -1,51 +0,0 @@ -/* 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/. */ - -#include "domstubs.idl" - -interface nsIURI; -interface nsIDOMWindow; -interface nsIMessageSender; - -// Implemented by the contract id @mozilla.org/system-message-internal;1 - -[scriptable, uuid(59b6beda-f911-4d47-a296-8c81e6abcfb9)] -interface nsISystemMessagesInternal : nsISupports -{ - /* - * Allow any internal user to send a message of a given type to a given page - * of an app. The message will be sent to all the registered pages of the app - * when |pageURI| is not specified. - * @param type The type of the message to be sent. - * @param message The message payload. - * @param pageURI The URI of the page that will be opened. Nullable. - * @param manifestURI The webapp's manifest URI. - * @param extra Extra opaque information that will be passed around in the observer - * notification to open the page. - * returns a Promise - */ - nsISupports sendMessage(in DOMString type, in jsval message, - in nsIURI pageURI, in nsIURI manifestURI, - [optional] in jsval extra); - - /* - * Allow any internal user to broadcast a message of a given type. - * The application that registers the message will be launched. - * @param type The type of the message to be sent. - * @param message The message payload. - * @param extra Extra opaque information that will be passed around in the observer - * notification to open the page. - * returns a Promise - */ - nsISupports broadcastMessage(in DOMString type, in jsval message, - [optional] in jsval extra); - - /* - * Registration of a page that wants to be notified of a message type. - * @param type The message type. - * @param pageURI The URI of the page that will be opened. - * @param manifestURI The webapp's manifest URI. - */ - void registerPage(in DOMString type, in nsIURI pageURI, in nsIURI manifestURI); -}; diff --git a/b2g/components/test/mochitest/SandboxPromptTest.html b/b2g/components/test/mochitest/SandboxPromptTest.html deleted file mode 100644 index 54f5fdd48..000000000 --- a/b2g/components/test/mochitest/SandboxPromptTest.html +++ /dev/null @@ -1,57 +0,0 @@ -<html> -<body> -<script> - -var actions = [ - { - permissions: ["video-capture"], - action: function() { - // invoke video-capture permission prompt - navigator.mozGetUserMedia({video: true}, function () {}, function () {}); - } - }, - { - permissions: ["audio-capture", "video-capture"], - action: function() { - // invoke audio-capture + video-capture permission prompt - navigator.mozGetUserMedia({audio: true, video: true}, function () {}, function () {}); - } - }, - { - permissions: ["audio-capture"], - action: function() { - // invoke audio-capture permission prompt - navigator.mozGetUserMedia({audio: true}, function () {}, function () {}); - } - }, - { - permissions: ["geolocation"], - action: function() { - // invoke geolocation permission prompt - navigator.geolocation.getCurrentPosition(function (pos) {}); - } - }, - { - permissions: ["desktop-notification"], - action: function() { - // invoke desktop-notification prompt - Notification.requestPermission(function (perm) {}); - } - }, -]; - -// The requested permissions are specified in query string. -var permissions = JSON.parse(decodeURIComponent(window.location.search.substring(1))); -for (var i = 0; i < actions.length; i++) { - if(permissions.length === actions[i].permissions.length && - permissions.every(function(permission) { - return actions[i].permissions.indexOf(permission) >= 0; - })) { - actions[i].action(); - break; - } -} - -</script> -</body> -</html> diff --git a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js b/b2g/components/test/mochitest/filepicker_path_handler_chrome.js deleted file mode 100644 index a175746cb..000000000 --- a/b2g/components/test/mochitest/filepicker_path_handler_chrome.js +++ /dev/null @@ -1,31 +0,0 @@ -/* 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/. */ - -'use strict'; - -var Cc = Components.classes; -var Ci = Components.interfaces; - -// use ppmm to handle file-picker message. -var ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1'] - .getService(Ci.nsIMessageListenerManager); - -var pickResult = null; - -function processPickMessage(message) { - let sender = message.target.QueryInterface(Ci.nsIMessageSender); - // reply FilePicker's message - sender.sendAsyncMessage('file-picked', pickResult); - // notify caller - sendAsyncMessage('file-picked-posted', { type: 'file-picked-posted' }); -} - -function updatePickResult(result) { - pickResult = result; - sendAsyncMessage('pick-result-updated', { type: 'pick-result-updated' }); -} - -ppmm.addMessageListener('file-picker', processPickMessage); -// use update-pick-result to change the expected pick result. -addMessageListener('update-pick-result', updatePickResult); diff --git a/b2g/components/test/mochitest/mochitest.ini b/b2g/components/test/mochitest/mochitest.ini deleted file mode 100644 index 97df32ea2..000000000 --- a/b2g/components/test/mochitest/mochitest.ini +++ /dev/null @@ -1,28 +0,0 @@ -[DEFAULT] -support-files = - permission_handler_chrome.js - SandboxPromptTest.html - filepicker_path_handler_chrome.js - screenshot_helper.js - systemapp_helper.js - presentation_prompt_handler_chrome.js - presentation_ui_glue_handler_chrome.js - -[test_filepicker_path.html] -skip-if = toolkit != "gonk" -[test_permission_deny.html] -skip-if = toolkit != "gonk" -[test_permission_gum_remember.html] -skip-if = true # Bug 1019572 - frequent timeouts -[test_sandbox_permission.html] -skip-if = toolkit != "gonk" -[test_screenshot.html] -skip-if = toolkit != "gonk" -[test_systemapp.html] -skip-if = toolkit != "gonk" -[test_presentation_device_prompt.html] -skip-if = toolkit != "gonk" -[test_permission_visibilitychange.html] -skip-if = toolkit != "gonk" -[test_presentation_request_ui_glue.html] -skip-if = toolkit != "gonk" diff --git a/b2g/components/test/mochitest/permission_handler_chrome.js b/b2g/components/test/mochitest/permission_handler_chrome.js deleted file mode 100644 index 9bf3e7819..000000000 --- a/b2g/components/test/mochitest/permission_handler_chrome.js +++ /dev/null @@ -1,36 +0,0 @@ -/* 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/. */ - -"use strict"; - -function debug(str) { - dump("CHROME PERMISSON HANDLER -- " + str + "\n"); -} - -var Cc = Components.classes; -var Ci = Components.interfaces; -var Cu = Components.utils; - -const { Services } = Cu.import("resource://gre/modules/Services.jsm"); -const { SystemAppProxy } = Cu.import("resource://gre/modules/SystemAppProxy.jsm"); - -var eventHandler = function(evt) { - if (!evt.detail || evt.detail.type !== "permission-prompt") { - return; - } - - sendAsyncMessage("permission-request", evt.detail); -}; - -SystemAppProxy.addEventListener("mozChromeEvent", eventHandler); - -// need to remove ChromeEvent listener after test finished. -addMessageListener("teardown", function() { - SystemAppProxy.removeEventListener("mozChromeEvent", eventHandler); -}); - -addMessageListener("permission-response", function(detail) { - SystemAppProxy._sendCustomEvent('mozContentEvent', detail); -}); - diff --git a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js b/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js deleted file mode 100644 index 4407e58d2..000000000 --- a/b2g/components/test/mochitest/presentation_prompt_handler_chrome.js +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -'use strict'; - - function debug(str) { - dump('presentation_prompt_handler_chrome: ' + str + '\n'); - } - -var { classes: Cc, interfaces: Ci, utils: Cu } = Components; -const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm'); - -const manager = Cc["@mozilla.org/presentation-device/manager;1"] - .getService(Ci.nsIPresentationDeviceManager); - -const prompt = Cc['@mozilla.org/presentation-device/prompt;1'] - .getService(Ci.nsIPresentationDevicePrompt); - -function TestPresentationDevice(options) { - this.id = options.id; - this.name = options.name; - this.type = options.type; -} - -TestPresentationDevice.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]), - establishSessionTransport: function() { - return null; - }, -}; - -function TestPresentationRequest(options) { - this.origin = options.origin; - this.requestURL = options.requestURL; -} - -TestPresentationRequest.prototype = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceRequest]), - select: function(device) { - let result = { - type: 'select', - device: { - id: device.id, - name: device.name, - type: device.type, - }, - }; - sendAsyncMessage('presentation-select-result', result); - }, - cancel: function() { - let result = { - type: 'cancel', - }; - sendAsyncMessage('presentation-select-result', result); - }, -}; - -var testDevice = null; - -addMessageListener('setup', function(device_options) { - testDevice = new TestPresentationDevice(device_options); - manager.QueryInterface(Ci.nsIPresentationDeviceListener).addDevice(testDevice); - sendAsyncMessage('setup-complete'); -}); - -var eventHandler = function(evt) { - if (!evt.detail || evt.detail.type !== 'presentation-select-device') { - return; - } - - sendAsyncMessage('presentation-select-device', evt.detail); -}; - -SystemAppProxy.addEventListener('mozChromeEvent', eventHandler); - -// need to remove ChromeEvent listener after test finished. -addMessageListener('teardown', function() { - if (testDevice) { - manager.removeDevice(testDevice); - } - SystemAppProxy.removeEventListener('mozChromeEvent', eventHandler); -}); - -addMessageListener('trigger-device-prompt', function(request_options) { - let request = new TestPresentationRequest(request_options); - prompt.promptDeviceSelection(request); -}); - -addMessageListener('presentation-select-response', function(detail) { - SystemAppProxy._sendCustomEvent('mozContentEvent', detail); -}); - diff --git a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js b/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js deleted file mode 100644 index fac16db6c..000000000 --- a/b2g/components/test/mochitest/presentation_ui_glue_handler_chrome.js +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -'use strict'; - -var { classes: Cc, interfaces: Ci, utils: Cu } = Components; -const { XPCOMUtils } = Cu.import('resource://gre/modules/XPCOMUtils.jsm'); -const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm'); - -const glue = Cc["@mozilla.org/presentation/requestuiglue;1"] - .createInstance(Ci.nsIPresentationRequestUIGlue); - -SystemAppProxy.addEventListener('mozPresentationChromeEvent', function(aEvent) { - if (!aEvent.detail || aEvent.detail.type !== 'presentation-launch-receiver') { - return; - } - sendAsyncMessage('presentation-launch-receiver', aEvent.detail); -}); - -addMessageListener('trigger-ui-glue', function(aData) { - var promise = glue.sendRequest(aData.url, aData.sessionId); - promise.then(function(aFrame) { - sendAsyncMessage('iframe-resolved', aFrame); - }).catch(function() { - sendAsyncMessage('iframe-rejected'); - }); -}); - -addMessageListener('trigger-presentation-content-event', function(aDetail) { - SystemAppProxy._sendCustomEvent('mozPresentationContentEvent', aDetail); -}); diff --git a/b2g/components/test/mochitest/screenshot_helper.js b/b2g/components/test/mochitest/screenshot_helper.js deleted file mode 100644 index 0320a14c1..000000000 --- a/b2g/components/test/mochitest/screenshot_helper.js +++ /dev/null @@ -1,40 +0,0 @@ -var Cu = Components.utils; -var Ci = Components.interfaces; - -Cu.importGlobalProperties(['File']); - -const { Services } = Cu.import("resource://gre/modules/Services.jsm"); - -// Load a duplicated copy of the jsm to prevent messing with the currently running one -var scope = {}; -Services.scriptloader.loadSubScript("resource://gre/modules/Screenshot.jsm", scope); -const { Screenshot } = scope; - -var index = -1; -function next() { - index++; - if (index >= steps.length) { - assert.ok(false, "Shouldn't get here!"); - return; - } - try { - steps[index](); - } catch(ex) { - assert.ok(false, "Caught exception: " + ex); - } -} - -var steps = [ - function getScreenshot() { - let screenshot = Screenshot.get(); - assert.ok(screenshot instanceof File, - "Screenshot.get() returns a File"); - next(); - }, - - function endOfTest() { - sendAsyncMessage("finish"); - } -]; - -next(); diff --git a/b2g/components/test/mochitest/systemapp_helper.js b/b2g/components/test/mochitest/systemapp_helper.js deleted file mode 100644 index 768b221fe..000000000 --- a/b2g/components/test/mochitest/systemapp_helper.js +++ /dev/null @@ -1,173 +0,0 @@ -var Cu = Components.utils; - -const { Services } = Cu.import("resource://gre/modules/Services.jsm"); - -// Load a duplicated copy of the jsm to prevent messing with the currently running one -var scope = {}; -Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm", scope); -const { SystemAppProxy } = scope; - -var frame; -var customEventTarget; - -var index = -1; -function next() { - index++; - if (index >= steps.length) { - assert.ok(false, "Shouldn't get here!"); - return; - } - try { - steps[index](); - } catch(ex) { - assert.ok(false, "Caught exception: " + ex); - } -} - -// Listen for events received by the system app document -// to ensure that we receive all of them, in an expected order and time -var isLoaded = false; -var isReady = false; -var n = 0; -function listener(event) { - if (!isLoaded) { - assert.ok(false, "Received event before the iframe is loaded"); - return; - } - n++; - if (n == 1) { - assert.equal(event.type, "mozChromeEvent"); - assert.equal(event.detail.name, "first"); - } else if (n == 2) { - assert.equal(event.type, "custom"); - assert.equal(event.detail.name, "second"); - - next(); // call checkEventPendingBeforeLoad - } else if (n == 3) { - if (!isReady) { - assert.ok(false, "Received event before the iframe is loaded"); - return; - } - - assert.equal(event.type, "custom"); - assert.equal(event.detail.name, "third"); - } else if (n == 4) { - if (!isReady) { - assert.ok(false, "Received event before the iframe is loaded"); - return; - } - - assert.equal(event.type, "mozChromeEvent"); - assert.equal(event.detail.name, "fourth"); - - next(); // call checkEventDispatching - } else if (n == 5) { - assert.equal(event.type, "custom"); - assert.equal(event.detail.name, "fifth"); - } else if (n === 6) { - assert.equal(event.type, "mozChromeEvent"); - assert.equal(event.detail.name, "sixth"); - } else if (n === 7) { - assert.equal(event.type, "custom"); - assert.equal(event.detail.name, "seventh"); - assert.equal(event.target, customEventTarget); - - next(); // call checkEventListening(); - } else { - assert.ok(false, "Unexpected event of type " + event.type); - } -} - - -var steps = [ - function earlyEvents() { - // Immediately try to send events - SystemAppProxy._sendCustomEvent("mozChromeEvent", { name: "first" }, true); - SystemAppProxy._sendCustomEvent("custom", { name: "second" }, true); - next(); - }, - - function createFrame() { - // Create a fake system app frame - let win = Services.wm.getMostRecentWindow("navigator:browser"); - let doc = win.document; - frame = doc.createElement("iframe"); - doc.documentElement.appendChild(frame); - - customEventTarget = frame.contentDocument.body; - - // Ensure that events are correctly sent to the frame. - // `listener` is going to call next() - frame.contentWindow.addEventListener("mozChromeEvent", listener); - frame.contentWindow.addEventListener("custom", listener); - - // Ensure that listener being registered before the system app is ready - // are correctly removed from the pending list - function removedListener() { - assert.ok(false, "Listener isn't correctly removed from the pending list"); - } - SystemAppProxy.addEventListener("mozChromeEvent", removedListener); - SystemAppProxy.removeEventListener("mozChromeEvent", removedListener); - - // Register it to the JSM - SystemAppProxy.registerFrame(frame); - assert.ok(true, "Frame created and registered"); - - frame.contentWindow.addEventListener("load", function onload() { - frame.contentWindow.removeEventListener("load", onload); - assert.ok(true, "Frame document loaded"); - - // Declare that the iframe is now loaded. - // That should dispatch early events - isLoaded = true; - SystemAppProxy.setIsLoaded(); - assert.ok(true, "Frame declared as loaded"); - - let gotFrame = SystemAppProxy.getFrame(); - assert.equal(gotFrame, frame, "getFrame returns the frame we passed"); - - // Once pending events are received, - // we will run checkEventDispatching from `listener` function - }); - - frame.setAttribute("src", "data:text/html,system app"); - }, - - function checkEventPendingBeforeLoad() { - // Frame is loaded but not ready, - // these events should queue before the System app is ready. - SystemAppProxy._sendCustomEvent("custom", { name: "third" }); - SystemAppProxy.dispatchEvent({ name: "fourth" }); - - isReady = true; - SystemAppProxy.setIsReady(); - // Once this 4th event is received, we will run checkEventDispatching - }, - - function checkEventDispatching() { - // Send events after the iframe is ready, - // they should be dispatched right away - SystemAppProxy._sendCustomEvent("custom", { name: "fifth" }); - SystemAppProxy.dispatchEvent({ name: "sixth" }); - SystemAppProxy._sendCustomEvent("custom", { name: "seventh" }, false, customEventTarget); - // Once this 7th event is received, we will run checkEventListening - }, - - function checkEventListening() { - SystemAppProxy.addEventListener("mozContentEvent", function onContentEvent(event) { - assert.equal(event.detail.name, "first-content", "received a system app event"); - SystemAppProxy.removeEventListener("mozContentEvent", onContentEvent); - - next(); - }); - let win = frame.contentWindow; - win.dispatchEvent(new win.CustomEvent("mozContentEvent", { detail: {name: "first-content"} })); - }, - - function endOfTest() { - frame.remove(); - sendAsyncMessage("finish"); - } -]; - -next(); diff --git a/b2g/components/test/mochitest/test_filepicker_path.html b/b2g/components/test/mochitest/test_filepicker_path.html deleted file mode 100644 index 92c00dc68..000000000 --- a/b2g/components/test/mochitest/test_filepicker_path.html +++ /dev/null @@ -1,130 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=949944 ---> -<head> -<meta charset="utf-8"> -<title>Permission Prompt Test</title> -<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> -<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body onload="processTestCase()"> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=949944"> [B2G][Helix][Browser][Wallpaper] use new File([blob], filename) to return a blob with filename when picking</a> -<script type="application/javascript"> - -'use strict'; - -var testCases = [ - // case 1: returns blob with name - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new Blob(['1234567890'], - { type: 'text/plain' }), - name: 'test1.txt' - } - }, - fileName: 'test1.txt' }, - // case 2: returns blob without name - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new Blob(['1234567890'], - { type: 'text/plain' }) - } - }, - fileName: 'blob.txt' }, - // case 3: returns blob with full path name - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new Blob(['1234567890'], - { type: 'text/plain' }), - name: '/full/path/test3.txt' - } - }, - fileName: 'test3.txt' }, - // case 4: returns blob relative path name - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new Blob(['1234567890'], - { type: 'text/plain' }), - name: 'relative/path/test4.txt' - } - }, - fileName: 'test4.txt' }, - // case 5: returns file with name - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new File(['1234567890'], - 'useless-name.txt', - { type: 'text/plain' }), - name: 'test5.txt' - } - }, - fileName: 'test5.txt'}, - // case 6: returns file without name. This case may fail because we - // need to make sure the File can be sent through - // sendAsyncMessage API. - { pickedResult: { success: true, - result: { - type: 'text/plain', - blob: new File(['1234567890'], - 'test6.txt', - { type: 'text/plain' }) - } - }, - fileName: 'test6.txt'} -]; - -var chromeJS = SimpleTest.getTestFileURL('filepicker_path_handler_chrome.js'); -var chromeScript = SpecialPowers.loadChromeScript(chromeJS); -var activeTestCase; - -chromeScript.addMessageListener('pick-result-updated', handleMessage); -chromeScript.addMessageListener('file-picked-posted', handleMessage); - -// handle messages returned from chromeScript -function handleMessage(data) { - var fileInput = document.getElementById('fileInput'); - switch (data.type) { - case 'pick-result-updated': - fileInput.click(); - break; - case 'file-picked-posted': - is(fileInput.value, activeTestCase.fileName, - 'File should be able to send through message.'); - processTestCase(); - break; - } -} - -function processTestCase() { - if (!testCases.length) { - SimpleTest.finish(); - return; - } - activeTestCase = testCases.shift(); - var expectedResult = activeTestCase.pickedResult; - if (navigator.userAgent.indexOf('Windows') > -1 && - expectedResult.result.name) { - // If we run at a window box, we need to translate the path from '/' to '\\' - var name = expectedResult.result.name; - name = name.replace('/', '\\'); - // If the name is an absolute path, we need to prepend drive letter. - if (name.startsWith('\\')) { - name = 'C:' + name; - } - // update the expected name. - expectedResult.result.name = name - } - chromeScript.sendAsyncMessage('update-pick-result', expectedResult); -} - -</script> -<input type="file" id="fileInput"> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_permission_deny.html b/b2g/components/test/mochitest/test_permission_deny.html deleted file mode 100644 index 29c35bdec..000000000 --- a/b2g/components/test/mochitest/test_permission_deny.html +++ /dev/null @@ -1,83 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=981113 ---> -<head> - <meta charset="utf-8"> - <title>Permission Deny Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=981113">Test Permission Deny</a> -<script type="application/javascript;version=1.8"> - -'use strict'; - -SimpleTest.waitForExplicitFinish(); - -const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION; - -var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js'); -var gScript = SpecialPowers.loadChromeScript(gUrl); -var gTests = [ - { - 'video': true, - }, - { - 'audio': true, - 'video': true, - }, - { - 'audio': true, - }, -]; - -function runNext() { - if (gTests.length > 0) { - // Put the requested permission in query string - let requestedType = gTests.shift(); - info('getUserMedia for ' + JSON.stringify(requestedType)); - navigator.mozGetUserMedia(requestedType, function success() { - ok(false, 'unexpected success, permission request should be denied'); - runNext(); - }, function failure(err) { - is(err.name, 'SecurityError', 'expected permission denied'); - runNext(); - }); - } else { - info('test finished, teardown'); - gScript.sendAsyncMessage('teardown', ''); - gScript.destroy(); - SimpleTest.finish(); - } -} - -gScript.addMessageListener('permission-request', function(detail) { - let response = { - id: detail.id, - type: 'permission-deny', - remember: false, - }; - gScript.sendAsyncMessage('permission-response', response); -}); - -// Need to change camera permission from ALLOW to PROMPT, otherwise -// MediaManager will automatically allow video-only gUM request. -SpecialPowers.pushPermissions([ - {type: 'video-capture', allow: PROMPT_ACTION, context: document}, - {type: 'audio-capture', allow: PROMPT_ACTION, context: document}, - {type: 'camera', allow: PROMPT_ACTION, context: document}, - ], function() { - SpecialPowers.pushPrefEnv({ - 'set': [ - ['media.navigator.permission.disabled', false], - ] - }, runNext); - } -); -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_permission_gum_remember.html b/b2g/components/test/mochitest/test_permission_gum_remember.html deleted file mode 100644 index 1ebfea1ca..000000000 --- a/b2g/components/test/mochitest/test_permission_gum_remember.html +++ /dev/null @@ -1,170 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=978660 ---> -<head> - <meta charset="utf-8"> - <title>gUM Remember Permission Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978660">Test remembering gUM Permission</a> -<script type="application/javascript;version=1.8"> - -'use strict'; - -SimpleTest.waitForExplicitFinish(); - -const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION; - -var gUrl = SimpleTest.getTestFileURL('permission_handler_chrome.js'); -var gScript = SpecialPowers.loadChromeScript(gUrl); -gScript.addMessageListener('permission-request', function(detail) { - ok(false, 'unexpected mozChromeEvent for permission prompt'); - let response = { - id: detail.id, - type: 'permission-deny', - remember: false, - }; - gScript.sendAsyncMessage('permission-response', response); -}); - -var gTests = [ - { - 'audio': true, - 'video': {facingMode: 'environment', required: ['facingMode']}, - }, - { - 'video': {facingMode: 'environment', required: ['facingMode']}, - }, - { - 'audio': true, - }, -]; - -function testGranted() { - info('test remember permission granted'); - return new Promise(function(resolve, reject) { - let steps = [].concat(gTests); - function nextStep() { - if (steps.length > 0) { - let requestedType = steps.shift(); - info('getUserMedia for ' + JSON.stringify(requestedType)); - navigator.mozGetUserMedia(requestedType, function success(stream) { - ok(true, 'expected gUM success'); - stream.stop(); - nextStep(); - }, function failure(err) { - ok(false, 'unexpected gUM fail: ' + err); - nextStep(); - }); - } else { - resolve(); - } - } - - SpecialPowers.pushPermissions([ - {type: 'video-capture', allow: true, context: document}, - {type: 'audio-capture', allow: true, context: document}, - ], nextStep); - }); -} - -function testDenied() { - info('test remember permission denied'); - return new Promise(function(resolve, reject) { - let steps = [].concat(gTests); - function nextStep() { - if (steps.length > 0) { - let requestedType = steps.shift(); - info('getUserMedia for ' + JSON.stringify(requestedType)); - navigator.mozGetUserMedia(requestedType, function success(stream) { - ok(false, 'unexpected gUM success'); - stream.stop(); - nextStep(); - }, function failure(err) { - ok(true, 'expected gUM fail: ' + err); - nextStep(); - }); - } else { - resolve(); - } - } - - SpecialPowers.pushPermissions([ - {type: 'video-capture', allow: false, context: document}, - {type: 'audio-capture', allow: false, context: document}, - ], nextStep); - }); -} - -function testPartialDeniedAudio() { - info('test remember permission partial denied: audio'); - return new Promise(function(resolve, reject) { - info('getUserMedia for video and audio'); - function nextStep() { - navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']}, - audio: true}, function success(stream) { - ok(false, 'unexpected gUM success'); - stream.stop(); - resolve(); - }, function failure(err) { - ok(true, 'expected gUM fail: ' + err); - resolve(); - }); - } - - SpecialPowers.pushPermissions([ - {type: 'video-capture', allow: true, context: document}, - {type: 'audio-capture', allow: false, context: document}, - ], nextStep); - }); -} - -function testPartialDeniedVideo() { - info('test remember permission partial denied: video'); - return new Promise(function(resolve, reject) { - info('getUserMedia for video and audio'); - function nextStep() { - navigator.mozGetUserMedia({video: {facingMode: 'environment', required: ['facingMode']}, - audio: true}, function success(stream) { - ok(false, 'unexpected gUM success'); - stream.stop(); - resolve(); - }, function failure(err) { - ok(true, 'expected gUM fail: ' + err); - resolve(); - }); - } - - SpecialPowers.pushPermissions([ - {type: 'video-capture', allow: false, context: document}, - {type: 'audio-capture', allow: true, context: document}, - ], nextStep); - }); -} - -function runTests() { - testGranted() - .then(testDenied) - .then(testPartialDeniedAudio) - .then(testPartialDeniedVideo) - .then(function() { - info('test finished, teardown'); - gScript.sendAsyncMessage('teardown', ''); - gScript.destroy(); - SimpleTest.finish(); - }); -} - -SpecialPowers.pushPrefEnv({ - 'set': [ - ['media.navigator.permission.disabled', false], - ] -}, runTests); -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_permission_visibilitychange.html b/b2g/components/test/mochitest/test_permission_visibilitychange.html deleted file mode 100644 index cd5694b42..000000000 --- a/b2g/components/test/mochitest/test_permission_visibilitychange.html +++ /dev/null @@ -1,57 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=951997 ---> -<head> - <meta charset="utf-8"> - <title>Permission Prompt Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1020179">Permission prompt visibilitychange test</a> -<script type="application/javascript;version=1.8"> - -"use strict"; - -var gUrl = SimpleTest.getTestFileURL("permission_handler_chrome.js"); -var gScript = SpecialPowers.loadChromeScript(gUrl); - -function testDone() { - gScript.sendAsyncMessage("teardown", ""); - gScript.destroy(); - SimpleTest.finish(); - alert("setVisible::true"); -} - -function runTest() { - navigator.geolocation.getCurrentPosition( - function (pos) { - ok(false, "unexpected success, permission request should be canceled"); - testDone(); - }, function (err) { - ok(true, "success, permission request is canceled"); - testDone(); - }); -} - -gScript.addMessageListener("permission-request", function (detail) { - info("got permission-request!!!!\n"); - alert("setVisible::false"); -}); - -// Add permissions to this app. We use ALLOW_ACTION here. The ContentPermissionPrompt -// should prompt for permission, not allow it without prompt. -SpecialPowers.pushPrefEnv({"set": [["media.navigator.permission.disabled", false]]}, - function() { - SpecialPowers.addPermission("geolocation", - SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION, document); - runTest(); - }); - -SimpleTest.waitForExplicitFinish(); -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_presentation_device_prompt.html b/b2g/components/test/mochitest/test_presentation_device_prompt.html deleted file mode 100644 index 9feeca795..000000000 --- a/b2g/components/test/mochitest/test_presentation_device_prompt.html +++ /dev/null @@ -1,145 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> -<head> - <meta charset="utf-8"> - <title>Test for Presentation Device Selection</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation Device Selection</a> -<script type="application/javascript;version=1.8"> - -'use strict'; - -SimpleTest.waitForExplicitFinish(); - -var contentEventHandler = null; - -var gUrl = SimpleTest.getTestFileURL('presentation_prompt_handler_chrome.js'); -var gScript = SpecialPowers.loadChromeScript(gUrl); - -function testSetup() { - info('setup for device selection'); - return new Promise(function(resolve, reject) { - let device = { - id: 'test-id', - name: 'test-name', - type: 'test-type', - }; - gScript.addMessageListener('setup-complete', function() { - resolve(device); - }); - gScript.sendAsyncMessage('setup', device); - }); -} - -function testSelected(device) { - info('test device selected by user'); - return new Promise(function(resolve, reject) { - let request = { - origin: 'test-origin', - requestURL: 'test-requestURL', - }; - - gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) { - gScript.removeMessageListener('presentation-select-device', contentEventHandler); - ok(true, 'receive user prompt for device selection'); - is(detail.origin, request.origin, 'expected origin'); - is(detail.requestURL, request.requestURL, 'expected requestURL'); - let response = { - id: detail.id, - type: 'presentation-select-result', - deviceId: device.id, - }; - gScript.sendAsyncMessage('presentation-select-response', response); - - gScript.addMessageListener('presentation-select-result', function resultHandler(result) { - gScript.removeMessageListener('presentation-select-result', resultHandler); - is(result.type, 'select', 'expect device selected'); - is(result.device.id, device.id, 'expected device id'); - is(result.device.name, device.name, 'expected device name'); - is(result.device.type, device.type, 'expected devcie type'); - resolve(); - }); - }); - - gScript.sendAsyncMessage('trigger-device-prompt', request); - }); -} - -function testSelectedNotExisted() { - info('test selected device doesn\'t exist'); - return new Promise(function(resolve, reject) { - gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) { - gScript.removeMessageListener('presentation-select-device', contentEventHandler); - ok(true, 'receive user prompt for device selection'); - let response = { - id: detail.id, - type: 'presentation-select-deny', - deviceId: undefined, // simulate device Id that doesn't exist - }; - gScript.sendAsyncMessage('presentation-select-response', response); - - gScript.addMessageListener('presentation-select-result', function resultHandler(result) { - gScript.removeMessageListener('presentation-select-result', resultHandler); - is(result.type, 'cancel', 'expect user cancel'); - resolve(); - }); - }); - - let request = { - origin: 'test-origin', - requestURL: 'test-requestURL', - }; - gScript.sendAsyncMessage('trigger-device-prompt', request); - }); -} - -function testDenied() { - info('test denial of device selection'); - return new Promise(function(resolve, reject) { - gScript.addMessageListener('presentation-select-device', function contentEventHandler(detail) { - gScript.removeMessageListener('presentation-select-device', contentEventHandler); - ok(true, 'receive user prompt for device selection'); - let response = { - id: detail.id, - type: 'presentation-select-deny', - }; - gScript.sendAsyncMessage('presentation-select-response', response); - - gScript.addMessageListener('presentation-select-result', function resultHandler(result) { - gScript.removeMessageListener('presentation-select-result', resultHandler); - is(result.type, 'cancel', 'expect user cancel'); - resolve(); - }); - }); - - let request = { - origin: 'test-origin', - requestURL: 'test-requestURL', - }; - gScript.sendAsyncMessage('trigger-device-prompt', request); - }); -} - -function runTests() { - testSetup() - .then(testSelected) - .then(testSelectedNotExisted) - .then(testDenied) - .then(function() { - info('test finished, teardown'); - gScript.sendAsyncMessage('teardown'); - gScript.destroy(); - SimpleTest.finish(); - }); -} - -window.addEventListener('load', runTests); -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_presentation_request_ui_glue.html b/b2g/components/test/mochitest/test_presentation_request_ui_glue.html deleted file mode 100644 index 29ac37221..000000000 --- a/b2g/components/test/mochitest/test_presentation_request_ui_glue.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> -<head> - <meta charset="utf-8"> - <title>Test for Presentation UI Glue</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Test for Presentation UI Glue</a> -<script type="application/javascript;version=1.8"> - -'use strict'; - -SimpleTest.waitForExplicitFinish(); - -var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('presentation_ui_glue_handler_chrome.js')); - -var obs = SpecialPowers.Cc["@mozilla.org/observer-service;1"] - .getService(SpecialPowers.Ci.nsIObserverService); - -var url = 'http://example.com'; -var sessionId = 'sessionId'; - -function testLaunchReceiver() { - return new Promise(function(aResolve, aReject) { - gScript.addMessageListener('presentation-launch-receiver', function launchReceiverHandler(aDetail) { - gScript.removeMessageListener('presentation-launch-receiver', launchReceiverHandler); - ok(true, "A presentation-launch-receiver mozPresentationChromeEvent should be received."); - is(aDetail.url, url, "Url should be the same."); - is(aDetail.id, sessionId, "Session ID should be the same."); - - aResolve(); - }); - - gScript.sendAsyncMessage('trigger-ui-glue', - { url: url, - sessionId : sessionId }); - }); -} - -function testReceiverLaunched() { - return new Promise(function(aResolve, aReject) { - gScript.addMessageListener('iframe-resolved', function iframeResolvedHandler(aFrame) { - gScript.removeMessageListener('iframe-resolved', iframeResolvedHandler); - ok(true, "The promise should be resolved."); - - aResolve(); - }); - - var iframe = document.createElement('iframe'); - iframe.setAttribute('remote', 'true'); - iframe.setAttribute('mozbrowser', 'true'); - iframe.setAttribute('src', 'http://example.com'); - document.body.appendChild(iframe); - - gScript.sendAsyncMessage('trigger-presentation-content-event', - { type: 'presentation-receiver-launched', - id: sessionId, - frame: iframe }); - }); -} - -function testLaunchError() { - return new Promise(function(aResolve, aReject) { - gScript.addMessageListener('presentation-launch-receiver', function launchReceiverHandler(aDetail) { - gScript.removeMessageListener('presentation-launch-receiver', launchReceiverHandler); - ok(true, "A presentation-launch-receiver mozPresentationChromeEvent should be received."); - is(aDetail.url, url, "Url should be the same."); - is(aDetail.id, sessionId, "Session ID should be the same."); - - gScript.addMessageListener('iframe-rejected', function iframeRejectedHandler() { - gScript.removeMessageListener('iframe-rejected', iframeRejectedHandler); - ok(true, "The promise should be rejected."); - aResolve(); - }); - - gScript.sendAsyncMessage('trigger-presentation-content-event', - { type: 'presentation-receiver-permission-denied', - id: sessionId }); - }); - - gScript.sendAsyncMessage('trigger-ui-glue', - { url: url, - sessionId : sessionId }); - }); -} - -function runTests() { - testLaunchReceiver() - .then(testReceiverLaunched) - .then(testLaunchError) - .then(function() { - info('test finished, teardown'); - gScript.destroy(); - SimpleTest.finish(); - }); -} - -window.addEventListener('load', runTests); -</script> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_sandbox_permission.html b/b2g/components/test/mochitest/test_sandbox_permission.html deleted file mode 100644 index cd13599a3..000000000 --- a/b2g/components/test/mochitest/test_sandbox_permission.html +++ /dev/null @@ -1,104 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=951997 ---> -<head> - <meta charset="utf-8"> - <title>Permission Prompt Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=951997">Permission prompt web content test</a> -<script type="application/javascript;version=1.8"> - -"use strict"; - -const APP_URL = "SandboxPromptTest.html"; - -var iframe; -var gUrl = SimpleTest.getTestFileURL("permission_handler_chrome.js"); -var gScript = SpecialPowers.loadChromeScript(gUrl); -var gResult = [ - { - "video-capture": ["back"], - }, - { - "audio-capture": [""], - "video-capture": ["back"], - }, - { - "audio-capture": [""], - }, - { - "geolocation": [], - }, - { - "desktop-notification": [], - } -]; - -function runNext() { - if (gResult.length > 0) { - // Put the requested permission in query string - let requestedPermission = JSON.stringify(Object.keys(gResult[0])); - info('request permissions for ' + requestedPermission); - iframe.src = APP_URL + '?' + encodeURIComponent(requestedPermission); - } else { - info('test finished, teardown'); - gScript.sendAsyncMessage("teardown", ""); - gScript.destroy(); - SimpleTest.finish(); - } -} - -// Create a sanbox iframe. -function loadBrowser() { - iframe = document.createElement("iframe"); - SpecialPowers.wrap(iframe).mozbrowser = true; - iframe.src = 'about:blank'; - document.body.appendChild(iframe); - - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad); - runNext(); - }); -} - -gScript.addMessageListener("permission-request", function (detail) { - let permissions = detail.permissions; - let expectedValue = gResult.shift(); - let permissionTypes = Object.keys(permissions); - - is(permissionTypes.length, Object.keys(expectedValue).length, "expected number of permissions"); - - for (let type of permissionTypes) { - ok(expectedValue.hasOwnProperty(type), "expected permission type"); - for (let i in permissions[type]) { - is(permissions[type][i], expectedValue[type][i], "expected permission option"); - } - } - runNext(); -}); - -// Add permissions to this app. We use ALLOW_ACTION here. The ContentPermissionPrompt -// should prompt for permission, not allow it without prompt. -SpecialPowers.pushPrefEnv({"set": [["media.navigator.permission.disabled", false]]}, - function() { - SpecialPowers.addPermission('video-capture', - SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document); - SpecialPowers.addPermission('audio-capture', - SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document); - SpecialPowers.addPermission('geolocation', - SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document); - SpecialPowers.addPermission('desktop-notification', - SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION, document); - loadBrowser(); - }); - -SimpleTest.waitForExplicitFinish(); -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_screenshot.html b/b2g/components/test/mochitest/test_screenshot.html deleted file mode 100644 index d2eeb8d48..000000000 --- a/b2g/components/test/mochitest/test_screenshot.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=1136784 ---> -<head> - <meta charset="utf-8"> - <title>Screenshot Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1136784">Screenshot.jsm</a> -<script type="application/javascript"> - -"use strict"; - -var gUrl = SimpleTest.getTestFileURL("screenshot_helper.js"); -var gScript = SpecialPowers.loadChromeScript(gUrl); - -SimpleTest.waitForExplicitFinish(); -gScript.addMessageListener("finish", function () { - SimpleTest.ok(true, "chrome test script finished"); - gScript.destroy(); - SimpleTest.finish(); -}); - -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/mochitest/test_systemapp.html b/b2g/components/test/mochitest/test_systemapp.html deleted file mode 100644 index 450094a50..000000000 --- a/b2g/components/test/mochitest/test_systemapp.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=963239 ---> -<head> - <meta charset="utf-8"> - <title>SystemAppProxy Test</title> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=963239">SystemAppProxy.jsm</a> -<script type="application/javascript"> - -"use strict"; - -var gUrl = SimpleTest.getTestFileURL("systemapp_helper.js"); -var gScript = SpecialPowers.loadChromeScript(gUrl); - -SimpleTest.waitForExplicitFinish(); -gScript.addMessageListener("finish", function () { - SimpleTest.ok(true, "chrome test script finished"); - gScript.destroy(); - SimpleTest.finish(); -}); - -</script> -</pre> -</body> -</html> diff --git a/b2g/components/test/moz.build b/b2g/components/test/moz.build deleted file mode 100644 index 387e3b811..000000000 --- a/b2g/components/test/moz.build +++ /dev/null @@ -1,8 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] -MOCHITEST_MANIFESTS += ['mochitest/mochitest.ini'] diff --git a/b2g/components/test/unit/data/test_logger_file b/b2g/components/test/unit/data/test_logger_file Binary files differdeleted file mode 100644 index b1ed7f10a..000000000 --- a/b2g/components/test/unit/data/test_logger_file +++ /dev/null diff --git a/b2g/components/test/unit/head_identity.js b/b2g/components/test/unit/head_identity.js deleted file mode 100644 index 604a77284..000000000 --- a/b2g/components/test/unit/head_identity.js +++ /dev/null @@ -1,159 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -var Ci = Components.interfaces; -var Cu = Components.utils; - -// The following boilerplate makes sure that XPCOM calls -// that use the profile directory work. - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService", - "resource://gre/modules/identity/MinimalIdentity.jsm", - "IdentityService"); - -XPCOMUtils.defineLazyModuleGetter(this, - "Logger", - "resource://gre/modules/identity/LogUtils.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, - "uuidGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - -const TEST_URL = "https://myfavoriteflan.com"; -const TEST_USER = "uumellmahaye1969@hotmail.com"; -const TEST_PRIVKEY = "i-am-a-secret"; -const TEST_CERT = "i~like~pie"; - -// The following are utility functions for Identity testing - -function log(...aMessageArgs) { - Logger.log.apply(Logger, ["test"].concat(aMessageArgs)); -} - -function partial(fn) { - let args = Array.prototype.slice.call(arguments, 1); - return function() { - return fn.apply(this, args.concat(Array.prototype.slice.call(arguments))); - }; -} - -function uuid() { - return uuidGenerator.generateUUID().toString(); -} - -// create a mock "doc" object, which the Identity Service -// uses as a pointer back into the doc object -function mockDoc(aParams, aDoFunc) { - let mockedDoc = {}; - mockedDoc.id = uuid(); - - // Properties of aParams may include loggedInUser - Object.keys(aParams).forEach(function(param) { - mockedDoc[param] = aParams[param]; - }); - - // the origin is set inside nsDOMIdentity by looking at the - // document.nodePrincipal.origin. Here we, we must satisfy - // ourselves with pretending. - mockedDoc.origin = "https://jedp.gov"; - - mockedDoc['do'] = aDoFunc; - mockedDoc.doReady = partial(aDoFunc, 'ready'); - mockedDoc.doLogin = partial(aDoFunc, 'login'); - mockedDoc.doLogout = partial(aDoFunc, 'logout'); - mockedDoc.doError = partial(aDoFunc, 'error'); - mockedDoc.doCancel = partial(aDoFunc, 'cancel'); - mockedDoc.doCoffee = partial(aDoFunc, 'coffee'); - - return mockedDoc; -} - -// create a mock "pipe" object that would normally communicate -// messages up to gaia (either the trusty ui or the hidden iframe), -// and convey messages back down from gaia to the controller through -// the message callback. - -// The mock receiving pipe simulates gaia which, after receiving messages -// through the pipe, will call back with instructions to invoke -// certain methods. It mocks what comes back from the other end of -// the pipe. -function mockReceivingPipe() { - let MockedPipe = { - communicate: function(aRpOptions, aGaiaOptions, aMessageCallback) { - switch (aGaiaOptions.message) { - case "identity-delegate-watch": - aMessageCallback({json: {method: "ready"}}); - break; - case "identity-delegate-request": - aMessageCallback({json: {method: "login", assertion: TEST_CERT}}); - break; - case "identity-delegate-logout": - aMessageCallback({json: {method: "logout"}}); - break; - default: - throw("what the what?? " + aGaiaOptions.message); - break; - } - } - }; - return MockedPipe; -} - -// The mock sending pipe lets us test what's actually getting put in the -// pipe. -function mockSendingPipe(aMessageCallback) { - let MockedPipe = { - communicate: function(aRpOptions, aGaiaOptions, aDummyCallback) { - aMessageCallback(aRpOptions, aGaiaOptions); - } - }; - return MockedPipe; -} - -// mimicking callback funtionality for ease of testing -// this observer auto-removes itself after the observe function -// is called, so this is meant to observe only ONE event. -function makeObserver(aObserveTopic, aObserveFunc) { - let observer = { - // nsISupports provides type management in C++ - // nsIObserver is to be an observer - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]), - - observe: function (aSubject, aTopic, aData) { - if (aTopic == aObserveTopic) { - Services.obs.removeObserver(observer, aObserveTopic); - aObserveFunc(aSubject, aTopic, aData); - } - } - }; - - Services.obs.addObserver(observer, aObserveTopic, false); -} - -// a hook to set up the ID service with an identity with keypair and all -// when ready, invoke callback with the identity. It's there if we need it. -function setup_test_identity(identity, cert, cb) { - cb(); -} - -// takes a list of functions and returns a function that -// when called the first time, calls the first func, -// then the next time the second, etc. -function call_sequentially() { - let numCalls = 0; - let funcs = arguments; - - return function() { - if (!funcs[numCalls]) { - let argString = Array.prototype.slice.call(arguments).join(","); - do_throw("Too many calls: " + argString); - return; - } - funcs[numCalls].apply(funcs[numCalls],arguments); - numCalls += 1; - }; -} diff --git a/b2g/components/test/unit/head_logshake_gonk.js b/b2g/components/test/unit/head_logshake_gonk.js deleted file mode 100644 index e94234f1f..000000000 --- a/b2g/components/test/unit/head_logshake_gonk.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Boostrap LogShake's tests that need gonk support. - * This is creating a fake sdcard for LogShake tests and importing LogShake and - * osfile - */ - -/* jshint moz: true */ -/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump, - do_get_profile, OS, volumeService, equal, XPCOMUtils */ -/* exported setup_logshake_mocks */ - -/* disable use strict warning */ -/* jshint -W097 */ - -"use strict"; - -var Cu = Components.utils; -var Ci = Components.interfaces; -var Cc = Components.classes; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/osfile.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "volumeService", - "@mozilla.org/telephony/volume-service;1", - "nsIVolumeService"); - -var sdcard; - -function setup_logshake_mocks() { - do_get_profile(); - setup_fs(); -} - -function setup_fs() { - OS.File.makeDir("/data/local/tmp/sdcard/", {from: "/data"}).then(function() { - setup_sdcard(); - }); -} - -function setup_sdcard() { - let volName = "sdcard"; - let mountPoint = "/data/local/tmp/sdcard"; - volumeService.createFakeVolume(volName, mountPoint); - - let vol = volumeService.getVolumeByName(volName); - ok(vol, "volume shouldn't be null"); - equal(volName, vol.name, "name"); - equal(Ci.nsIVolume.STATE_MOUNTED, vol.state, "state"); - - ensure_sdcard(); -} - -function ensure_sdcard() { - sdcard = volumeService.getVolumeByName("sdcard").mountPoint; - ok(sdcard, "Should have a valid sdcard mountpoint"); - run_next_test(); -} diff --git a/b2g/components/test/unit/test_aboutserviceworkers.js b/b2g/components/test/unit/test_aboutserviceworkers.js deleted file mode 100644 index d1a7d41aa..000000000 --- a/b2g/components/test/unit/test_aboutserviceworkers.js +++ /dev/null @@ -1,142 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "AboutServiceWorkers", - "resource://gre/modules/AboutServiceWorkers.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "gServiceWorkerManager", - "@mozilla.org/serviceworkers/manager;1", - "nsIServiceWorkerManager"); - -const CHROME_MSG = "mozAboutServiceWorkersChromeEvent"; - -const ORIGINAL_SENDRESULT = AboutServiceWorkers.sendResult; -const ORIGINAL_SENDERROR = AboutServiceWorkers.sendError; - -do_get_profile(); - -var mockSendResult = (aId, aResult) => { - let msg = { - id: aId, - result: aResult - }; - Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null); -}; - -var mockSendError = (aId, aError) => { - let msg = { - id: aId, - result: aError - }; - Services.obs.notifyObservers({wrappedJSObject: msg}, CHROME_MSG, null); -}; - -function attachMocks() { - AboutServiceWorkers.sendResult = mockSendResult; - AboutServiceWorkers.sendError = mockSendError; -} - -function restoreMocks() { - AboutServiceWorkers.sendResult = ORIGINAL_SENDRESULT; - AboutServiceWorkers.sendError = ORIGINAL_SENDERROR; -} - -do_register_cleanup(restoreMocks); - -function run_test() { - run_next_test(); -} - -/** - * "init" tests - */ -[ -// Pref disabled, no registrations -{ - prefEnabled: false, - expectedMessage: { - id: Date.now(), - result: { - enabled: false, - registrations: [] - } - } -}, -// Pref enabled, no registrations -{ - prefEnabled: true, - expectedMessage: { - id: Date.now(), - result: { - enabled: true, - registrations: [] - } - } -}].forEach(test => { - add_test(function() { - Services.prefs.setBoolPref("dom.serviceWorkers.enabled", test.prefEnabled); - - let id = test.expectedMessage.id; - - function onMessage(subject, topic, data) { - let message = subject.wrappedJSObject; - let expected = test.expectedMessage; - - do_check_true(message.id, "Message should have id"); - do_check_eq(message.id, test.expectedMessage.id, - "Id should be the expected one"); - do_check_eq(message.result.enabled, expected.result.enabled, - "Pref should be disabled"); - do_check_true(message.result.registrations, "Registrations should exist"); - do_check_eq(message.result.registrations.length, - expected.result.registrations.length, - "Registrations length should be the expected one"); - - Services.obs.removeObserver(onMessage, CHROME_MSG); - - run_next_test(); - } - - Services.obs.addObserver(onMessage, CHROME_MSG, false); - - attachMocks(); - - AboutServiceWorkers.handleEvent({ detail: { - id: id, - name: "init" - }}); - }); -}); - -/** - * ServiceWorkerManager tests. - */ - -// We cannot register a sw via ServiceWorkerManager cause chrome -// registrations are not allowed. -// All we can do for now is to test the interface of the swm. -add_test(function test_swm() { - do_check_true(gServiceWorkerManager, "SWM exists"); - do_check_true(gServiceWorkerManager.getAllRegistrations, - "SWM.getAllRegistrations exists"); - do_check_true(typeof gServiceWorkerManager.getAllRegistrations == "function", - "SWM.getAllRegistrations is a function"); - do_check_true(gServiceWorkerManager.propagateSoftUpdate, - "SWM.propagateSoftUpdate exists"); - do_check_true(typeof gServiceWorkerManager.propagateSoftUpdate == "function", - - "SWM.propagateSoftUpdate is a function"); - do_check_true(gServiceWorkerManager.propagateUnregister, - "SWM.propagateUnregister exists"); - do_check_true(typeof gServiceWorkerManager.propagateUnregister == "function", - "SWM.propagateUnregister exists"); - - run_next_test(); -}); diff --git a/b2g/components/test/unit/test_bug793310.js b/b2g/components/test/unit/test_bug793310.js deleted file mode 100644 index 2bdb8252e..000000000 --- a/b2g/components/test/unit/test_bug793310.js +++ /dev/null @@ -1,39 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function run_test() { - Components.utils.import("resource:///modules/TelURIParser.jsm") - - // global-phone-number - do_check_eq(TelURIParser.parseURI('tel', 'tel:+1234'), '+1234'); - - // global-phone-number => white space separator - do_check_eq(TelURIParser.parseURI('tel', 'tel:+123 456 789'), '+123 456 789'); - - // global-phone-number => ignored chars - do_check_eq(TelURIParser.parseURI('tel', 'tel:+1234_123'), '+1234'); - - // global-phone-number => visualSeparator + digits - do_check_eq(TelURIParser.parseURI('tel', 'tel:+-.()1234567890'), '+-.()1234567890'); - - // local-phone-number - do_check_eq(TelURIParser.parseURI('tel', 'tel:1234'), '1234'); - - // local-phone-number => visualSeparator + digits + dtmfDigits + pauseCharacter - do_check_eq(TelURIParser.parseURI('tel', 'tel:-.()1234567890ABCDpw'), '-.()1234567890ABCDpw'); - - // local-phone-number => visualSeparator + digits + dtmfDigits + pauseCharacter + ignored chars - do_check_eq(TelURIParser.parseURI('tel', 'tel:-.()1234567890ABCDpw_'), '-.()1234567890ABCDpw'); - - // local-phone-number => isdn-subaddress - do_check_eq(TelURIParser.parseURI('tel', 'tel:123;isub=123'), '123'); - - // local-phone-number => post-dial - do_check_eq(TelURIParser.parseURI('tel', 'tel:123;postd=123'), '123'); - - // local-phone-number => prefix - do_check_eq(TelURIParser.parseURI('tel', 'tel:123;phone-context=+0321'), '+0321123'); - - // local-phone-number => isdn-subaddress + post-dial + prefix - do_check_eq(TelURIParser.parseURI('tel', 'tel:123;isub=123;postd=123;phone-context=+0321'), '+0321123'); -} diff --git a/b2g/components/test/unit/test_bug832946.js b/b2g/components/test/unit/test_bug832946.js deleted file mode 100644 index 4ddbd4280..000000000 --- a/b2g/components/test/unit/test_bug832946.js +++ /dev/null @@ -1,18 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function run_test() { - Components.utils.import("resource:///modules/TelURIParser.jsm") - - // blocked numbers - do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234*'), null); - do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234#'), null); - do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234*'), null); - do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234#'), null); - do_check_eq(TelURIParser.parseURI('tel', 'tel:*#*#7780#*#*'), null); - do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234AB'), null); - - // white list - do_check_eq(TelURIParser.parseURI('tel', 'tel:*1234'), '*1234'); - do_check_eq(TelURIParser.parseURI('tel', 'tel:#1234'), '#1234'); -} diff --git a/b2g/components/test/unit/test_fxaccounts.js b/b2g/components/test/unit/test_fxaccounts.js deleted file mode 100644 index 5de0d6565..000000000 --- a/b2g/components/test/unit/test_fxaccounts.js +++ /dev/null @@ -1,212 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -var {utils: Cu} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://testing-common/httpd.js"); - -XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsMgmtService", - "resource://gre/modules/FxAccountsMgmtService.jsm", - "FxAccountsMgmtService"); - -XPCOMUtils.defineLazyModuleGetter(this, "FxAccountsManager", - "resource://gre/modules/FxAccountsManager.jsm"); - -// At end of test, restore original state -const ORIGINAL_AUTH_URI = Services.prefs.getCharPref("identity.fxaccounts.auth.uri"); -var { SystemAppProxy } = Cu.import("resource://gre/modules/FxAccountsMgmtService.jsm"); -const ORIGINAL_SENDCUSTOM = SystemAppProxy._sendCustomEvent; -do_register_cleanup(function() { - Services.prefs.setCharPref("identity.fxaccounts.auth.uri", ORIGINAL_AUTH_URI); - SystemAppProxy._sendCustomEvent = ORIGINAL_SENDCUSTOM; - Services.prefs.clearUserPref("identity.fxaccounts.skipDeviceRegistration"); -}); - -// Make profile available so that fxaccounts can store user data -do_get_profile(); - -// Mock the system app proxy; make message passing possible -var mockSendCustomEvent = function(aEventName, aMsg) { - Services.obs.notifyObservers({wrappedJSObject: aMsg}, aEventName, null); -}; - -function run_test() { - run_next_test(); -} - -add_task(function test_overall() { - // FxA device registration throws from this context - Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true); - - do_check_neq(FxAccountsMgmtService, null); -}); - -// Check that invalid email capitalization is corrected on signIn. -// https://github.com/mozilla/fxa-auth-server/blob/master/docs/api.md#post-v1accountlogin -add_test(function test_invalidEmailCase_signIn() { - do_test_pending(); - let clientEmail = "greta.garbo@gmail.com"; - let canonicalEmail = "Greta.Garbo@gmail.COM"; - let attempts = 0; - - function writeResp(response, msg) { - if (typeof msg === "object") { - msg = JSON.stringify(msg); - } - response.bodyOutputStream.write(msg, msg.length); - } - - // Mock of the fxa accounts auth server, reproducing the behavior of - // /account/login when email capitalization is incorrect on signIn. - let server = httpd_setup({ - "/account/login": function(request, response) { - response.setHeader("Content-Type", "application/json"); - attempts += 1; - - // Ensure we don't get in an endless loop - if (attempts > 2) { - response.setStatusLine(request.httpVersion, 429, "Sorry, you had your chance"); - writeResp(response, {}); - return; - } - - let body = CommonUtils.readBytesFromInputStream(request.bodyInputStream); - let jsonBody = JSON.parse(body); - let email = jsonBody.email; - - // The second time through, the accounts client will call the api with - // the correct email capitalization. - if (email == canonicalEmail) { - response.setStatusLine(request.httpVersion, 200, "Yay"); - writeResp(response, { - uid: "your-uid", - sessionToken: "your-sessionToken", - keyFetchToken: "your-keyFetchToken", - verified: true, - authAt: 1392144866, - }); - return; - } - - // If the client has the wrong case on the email, we return a 400, with - // the capitalization of the email as saved in the accounts database. - response.setStatusLine(request.httpVersion, 400, "Incorrect email case"); - writeResp(response, { - code: 400, - errno: 120, - error: "Incorrect email case", - email: canonicalEmail, - }); - return; - }, - }); - - // Point the FxAccountsClient's hawk rest request client to the mock server - Services.prefs.setCharPref("identity.fxaccounts.auth.uri", server.baseURI); - - // FxA device registration throws from this context - Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true); - - // Receive a mozFxAccountsChromeEvent message - function onMessage(subject, topic, data) { - let message = subject.wrappedJSObject; - - switch (message.id) { - // When we signed in as "Greta.Garbo", the server should have told us - // that the proper capitalization is really "greta.garbo". Call - // getAccounts to get the signed-in user and ensure that the - // capitalization is correct. - case "signIn": - FxAccountsMgmtService.handleEvent({ - detail: { - id: "getAccounts", - data: { - method: "getAccounts", - } - } - }); - break; - - // Having initially signed in as "Greta.Garbo", getAccounts should show - // us that the signed-in user has the properly-capitalized email, - // "greta.garbo". - case "getAccounts": - Services.obs.removeObserver(onMessage, "mozFxAccountsChromeEvent"); - - do_check_eq(message.data.email, canonicalEmail); - - do_test_finished(); - server.stop(run_next_test); - break; - - // We should not receive any other mozFxAccountsChromeEvent messages - default: - do_throw("wat!"); - break; - } - } - - Services.obs.addObserver(onMessage, "mozFxAccountsChromeEvent", false); - - SystemAppProxy._sendCustomEvent = mockSendCustomEvent; - - // Trigger signIn using an email with incorrect capitalization - FxAccountsMgmtService.handleEvent({ - detail: { - id: "signIn", - data: { - method: "signIn", - email: clientEmail, - password: "123456", - }, - }, - }); -}); - -add_test(function testHandleGetAssertionError_defaultCase() { - do_test_pending(); - - // FxA device registration throws from this context - Services.prefs.setBoolPref("identity.fxaccounts.skipDeviceRegistration", true); - - FxAccountsManager.getAssertion(null).then( - success => { - // getAssertion should throw with invalid audience - ok(false); - }, - reason => { - equal("INVALID_AUDIENCE", reason.error); - do_test_finished(); - run_next_test(); - } - ) -}); - -// End of tests -// Utility functions follow - -function httpd_setup (handlers, port=-1) { - let server = new HttpServer(); - for (let path in handlers) { - server.registerPathHandler(path, handlers[path]); - } - try { - server.start(port); - } catch (ex) { - dump("ERROR starting server on port " + port + ". Already a process listening?"); - do_throw(ex); - } - - // Set the base URI for convenience. - let i = server.identity; - server.baseURI = i.primaryScheme + "://" + i.primaryHost + ":" + i.primaryPort; - - return server; -} - - diff --git a/b2g/components/test/unit/test_logcapture.js b/b2g/components/test/unit/test_logcapture.js deleted file mode 100644 index 9dbe2bc77..000000000 --- a/b2g/components/test/unit/test_logcapture.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Testing non Gonk-specific code path - */ -function run_test() { - Components.utils.import("resource:///modules/LogCapture.jsm"); - run_next_test(); -} - -// Trivial test just to make sure we have no syntax error -add_test(function test_logCapture_loads() { - ok(LogCapture, "LogCapture object exists"); - run_next_test(); -}); diff --git a/b2g/components/test/unit/test_logcapture_gonk.js b/b2g/components/test/unit/test_logcapture_gonk.js deleted file mode 100644 index d80f33dd9..000000000 --- a/b2g/components/test/unit/test_logcapture_gonk.js +++ /dev/null @@ -1,70 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - - -/** - * Test that LogCapture successfully reads from the /dev/log devices, returning - * a Uint8Array of some length, including zero. This tests a few standard - * log devices - */ -function run_test() { - Components.utils.import("resource:///modules/LogCapture.jsm"); - run_next_test(); -} - -function verifyLog(log) { - // log exists - notEqual(log, null); - // log has a length and it is non-negative (is probably array-like) - ok(log.length >= 0); -} - -add_test(function test_readLogFile() { - let mainLog = LogCapture.readLogFile("/dev/log/main"); - verifyLog(mainLog); - - let meminfoLog = LogCapture.readLogFile("/proc/meminfo"); - verifyLog(meminfoLog); - - run_next_test(); -}); - -add_test(function test_readProperties() { - let propertiesLog = LogCapture.readProperties(); - notEqual(propertiesLog, null, "Properties should not be null"); - notEqual(propertiesLog, undefined, "Properties should not be undefined"); - - for (let propertyName in propertiesLog) { - equal(typeof(propertiesLog[propertyName]), "string", - "Property " + propertyName + " should be a string"); - } - - equal(propertiesLog["ro.product.locale.language"], "en", - "Locale language should be read correctly. See bug 1171577."); - - equal(propertiesLog["ro.product.locale.region"], "US", - "Locale region should be read correctly. See bug 1171577."); - - run_next_test(); -}); - -add_test(function test_readAppIni() { - let appIni = LogCapture.readLogFile("/system/b2g/application.ini"); - verifyLog(appIni); - - run_next_test(); -}); - -add_test(function test_get_about_memory() { - let memLog = LogCapture.readAboutMemory(); - - ok(memLog, "Should have returned a valid Promise object"); - - memLog.then(file => { - ok(file, "Should have returned a filename"); - run_next_test(); - }, error => { - ok(false, "Dumping about:memory promise rejected: " + error); - run_next_test(); - }); -}); diff --git a/b2g/components/test/unit/test_logparser.js b/b2g/components/test/unit/test_logparser.js deleted file mode 100644 index 624dcc6e2..000000000 --- a/b2g/components/test/unit/test_logparser.js +++ /dev/null @@ -1,75 +0,0 @@ -/* jshint moz: true */ - -var {utils: Cu, classes: Cc, interfaces: Ci} = Components; - -function debug(msg) { - var timestamp = Date.now(); - dump("LogParser: " + timestamp + ": " + msg + "\n"); -} - -function run_test() { - Cu.import("resource:///modules/LogParser.jsm"); - debug("Starting"); - run_next_test(); -} - -function makeStream(file) { - var fileStream = Cc["@mozilla.org/network/file-input-stream;1"] - .createInstance(Ci.nsIFileInputStream); - fileStream.init(file, -1, -1, 0); - var bis = Cc["@mozilla.org/binaryinputstream;1"] - .createInstance(Ci.nsIBinaryInputStream); - bis.setInputStream(fileStream); - return bis; -} - -add_test(function test_parse_logfile() { - let loggerFile = do_get_file("data/test_logger_file"); - - let loggerStream = makeStream(loggerFile); - - // Initialize arrays to hold the file contents (lengths are hardcoded) - let loggerArray = new Uint8Array(loggerStream.readByteArray(4037)); - - loggerStream.close(); - - let logMessages = LogParser.parseLogArray(loggerArray); - - ok(logMessages.length === 58, "There should be 58 messages in the log"); - - let expectedLogEntry = { - processId: 271, threadId: 271, - seconds: 790796, nanoseconds: 620000001, time: 790796620.000001, - priority: 4, tag: "Vold", - message: "Vold 2.1 (the revenge) firing up\n" - }; - - deepEqual(expectedLogEntry, logMessages[0]); - run_next_test(); -}); - -add_test(function test_print_properties() { - let properties = { - "ro.secure": "1", - "sys.usb.state": "diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb" - }; - - let logMessagesRaw = LogParser.prettyPrintPropertiesArray(properties); - let logMessages = new TextDecoder("utf-8").decode(logMessagesRaw); - let logMessagesArray = logMessages.split("\n"); - - ok(logMessagesArray.length === 3, "There should be 3 lines in the log."); - notEqual(logMessagesArray[0], "", "First line should not be empty"); - notEqual(logMessagesArray[1], "", "Second line should not be empty"); - equal(logMessagesArray[2], "", "Last line should be empty"); - - let expectedLog = [ - "[ro.secure]: [1]", - "[sys.usb.state]: [diag,serial_smd,serial_tty,rmnet_bam,mass_storage,adb]", - "" - ].join("\n"); - - deepEqual(expectedLog, logMessages); - - run_next_test(); -}); diff --git a/b2g/components/test/unit/test_logshake.js b/b2g/components/test/unit/test_logshake.js deleted file mode 100644 index cfb81b893..000000000 --- a/b2g/components/test/unit/test_logshake.js +++ /dev/null @@ -1,218 +0,0 @@ -/** - * Test the log capturing capabilities of LogShake.jsm - */ - -/* jshint moz: true */ -/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */ -/* exported run_test */ - -/* disable use strict warning */ -/* jshint -W097 */ -"use strict"; - -var Cu = Components.utils; - -Cu.import("resource://gre/modules/LogCapture.jsm"); -Cu.import("resource://gre/modules/LogShake.jsm"); - -const EVENTS_PER_SECOND = 6.25; -const GRAVITY = 9.8; - -/** - * Force logshake to handle a device motion event with given components. - * Does not use SystemAppProxy because event needs special - * accelerationIncludingGravity property. - */ -function sendDeviceMotionEvent(x, y, z) { - let event = { - type: "devicemotion", - accelerationIncludingGravity: { - x: x, - y: y, - z: z - } - }; - LogShake.handleEvent(event); -} - -/** - * Send a screen change event directly, does not use SystemAppProxy due to race - * conditions. - */ -function sendScreenChangeEvent(screenEnabled) { - let event = { - type: "screenchange", - detail: { - screenEnabled: screenEnabled - } - }; - LogShake.handleEvent(event); -} - -/** - * Mock the readLogFile function of LogCapture. - * Used to detect whether LogShake activates. - * @return {Array<String>} Locations that LogShake tries to read - */ -function mockReadLogFile() { - let readLocations = []; - - LogCapture.readLogFile = function(loc) { - readLocations.push(loc); - return null; // we don't want to provide invalid data to a parser - }; - - // Allow inspection of readLocations by caller - return readLocations; -} - -/** - * Send a series of events that corresponds to a shake - */ -function sendSustainedShake() { - // Fire a series of devicemotion events that are of shake magnitude - for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) { - sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY); - } - -} - -add_test(function test_do_log_capture_after_shaking() { - // Enable LogShake - LogShake.init(); - - let readLocations = mockReadLogFile(); - - sendSustainedShake(); - - ok(readLocations.length > 0, - "LogShake should attempt to read at least one log"); - - LogShake.uninit(); - run_next_test(); -}); - -add_test(function test_do_nothing_when_resting() { - // Enable LogShake - LogShake.init(); - - let readLocations = mockReadLogFile(); - - // Fire several devicemotion events that are relatively tiny - for (let i = 0; i < 2 * EVENTS_PER_SECOND; i++) { - sendDeviceMotionEvent(0, GRAVITY, GRAVITY); - } - - ok(readLocations.length === 0, - "LogShake should not read any logs"); - - LogShake.uninit(); - run_next_test(); -}); - -add_test(function test_do_nothing_when_disabled() { - // Disable LogShake - LogShake.uninit(); - - let readLocations = mockReadLogFile(); - - // Fire a series of events that would normally be a shake - sendSustainedShake(); - - ok(readLocations.length === 0, - "LogShake should not read any logs"); - - run_next_test(); -}); - -add_test(function test_do_nothing_when_screen_off() { - // Enable LogShake - LogShake.init(); - - // Send an event as if the screen has been turned off - sendScreenChangeEvent(false); - - let readLocations = mockReadLogFile(); - - // Fire a series of events that would normally be a shake - sendSustainedShake(); - - ok(readLocations.length === 0, - "LogShake should not read any logs"); - - // Restore the screen - sendScreenChangeEvent(true); - - LogShake.uninit(); - run_next_test(); -}); - -add_test(function test_do_log_capture_resilient_readLogFile() { - // Enable LogShake - LogShake.init(); - - let readLocations = []; - LogCapture.readLogFile = function(loc) { - readLocations.push(loc); - throw new Error("Exception during readLogFile for: " + loc); - }; - - // Fire a series of events that would normally be a shake - sendSustainedShake(); - - ok(readLocations.length > 0, - "LogShake should attempt to read at least one log"); - - LogShake.uninit(); - run_next_test(); -}); - -add_test(function test_do_log_capture_resilient_parseLog() { - // Enable LogShake - LogShake.init(); - - let readLocations = []; - LogCapture.readLogFile = function(loc) { - readLocations.push(loc); - LogShake.LOGS_WITH_PARSERS[loc] = function() { - throw new Error("Exception during LogParser for: " + loc); - }; - return null; - }; - - // Fire a series of events that would normally be a shake - sendSustainedShake(); - - ok(readLocations.length > 0, - "LogShake should attempt to read at least one log"); - - LogShake.uninit(); - run_next_test(); -}); - -add_test(function test_do_nothing_when_dropped() { - // Enable LogShake - LogShake.init(); - - let readLocations = mockReadLogFile(); - - // We want a series of spikes to be ignored by LogShake. This roughly - // corresponds to the compare_stairs_sock graph on bug #1101994 - - for (let i = 0; i < 10 * EVENTS_PER_SECOND; i++) { - // Fire a devicemotion event that is at rest - sendDeviceMotionEvent(0, 0, GRAVITY); - // Fire a spike of motion - sendDeviceMotionEvent(0, 2 * GRAVITY, 2 * GRAVITY); - } - - ok(readLocations.length === 0, - "LogShake should not read any logs"); - - LogShake.uninit(); - run_next_test(); -}); - -function run_test() { - run_next_test(); -} diff --git a/b2g/components/test/unit/test_logshake_gonk.js b/b2g/components/test/unit/test_logshake_gonk.js deleted file mode 100644 index 28de0263f..000000000 --- a/b2g/components/test/unit/test_logshake_gonk.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Test the log capturing capabilities of LogShake.jsm, checking - * for Gonk-specific parts - */ - -/* jshint moz: true, esnext: true */ -/* global Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump, - setup_logshake_mocks, OS, sdcard */ -/* exported run_test */ - -/* disable use strict warning */ -/* jshint -W097 */ - -"use strict"; - -Cu.import("resource://gre/modules/Promise.jsm"); - -function run_test() { - Cu.import("resource://gre/modules/LogShake.jsm"); - run_next_test(); -} - -add_test(setup_logshake_mocks); - -add_test(function test_logShake_captureLogs_writes() { - // Enable LogShake - LogShake.init(); - - let expectedFiles = []; - - LogShake.captureLogs().then(logResults => { - LogShake.uninit(); - - ok(logResults.logFilenames.length > 0, "Should have filenames"); - ok(logResults.logPaths.length > 0, "Should have paths"); - ok(!logResults.compressed, "Should not be compressed"); - - logResults.logPaths.forEach(f => { - let p = OS.Path.join(sdcard, f); - ok(p, "Should have a valid result path: " + p); - - let t = OS.File.exists(p).then(rv => { - ok(rv, "File exists: " + p); - }); - - expectedFiles.push(t); - }); - - Promise.all(expectedFiles).then(() => { - ok(true, "Completed all files checks"); - run_next_test(); - }); - }, - error => { - LogShake.uninit(); - - ok(false, "Should not have received error: " + error); - - run_next_test(); - }); -}); diff --git a/b2g/components/test/unit/test_logshake_gonk_compression.js b/b2g/components/test/unit/test_logshake_gonk_compression.js deleted file mode 100644 index b5af46081..000000000 --- a/b2g/components/test/unit/test_logshake_gonk_compression.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Test the log capturing capabilities of LogShake.jsm, checking - * for Gonk-specific parts - */ - -/* jshint moz: true, esnext: true */ -/* global Cc, Ci, Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump, - setup_logshake_mocks, OS, sdcard, FileUtils */ -/* exported run_test */ - -/* disable use strict warning */ -/* jshint -W097 */ - -"use strict"; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); - -function run_test() { - Cu.import("resource://gre/modules/LogShake.jsm"); - run_next_test(); -} - -add_test(setup_logshake_mocks); - -add_test(function test_logShake_captureLogs_writes_zip() { - // Enable LogShake - LogShake.init(); - - let expectedFiles = []; - - LogShake.enableQAMode(); - - LogShake.captureLogs().then(logResults => { - LogShake.uninit(); - - ok(logResults.logPaths.length === 1, "Should have zip path"); - ok(logResults.logFilenames.length >= 1, "Should have log filenames"); - ok(logResults.compressed, "Log files should be compressed"); - - let zipPath = OS.Path.join(sdcard, logResults.logPaths[0]); - ok(zipPath, "Should have a valid archive path: " + zipPath); - - let zipFile = new FileUtils.File(zipPath); - ok(zipFile, "Should have a valid archive file: " + zipFile); - - let zipReader = Cc["@mozilla.org/libjar/zip-reader;1"] - .createInstance(Ci.nsIZipReader); - zipReader.open(zipFile); - - let logFilenamesSeen = {}; - - let zipEntries = zipReader.findEntries(null); // Find all entries - while (zipEntries.hasMore()) { - let entryName = zipEntries.getNext(); - let entry = zipReader.getEntry(entryName); - logFilenamesSeen[entryName] = true; - ok(!entry.isDirectory, "Archive entry " + entryName + " should be a file"); - } - zipReader.close(); - - // TODO: Verify archive contents - logResults.logFilenames.forEach(filename => { - ok(logFilenamesSeen[filename], "File " + filename + " should be present in archive"); - }); - run_next_test(); - }, - error => { - LogShake.uninit(); - - ok(false, "Should not have received error: " + error); - - run_next_test(); - }); -}); - diff --git a/b2g/components/test/unit/test_logshake_readLog_gonk.js b/b2g/components/test/unit/test_logshake_readLog_gonk.js deleted file mode 100644 index 003723ad5..000000000 --- a/b2g/components/test/unit/test_logshake_readLog_gonk.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Test the log capturing capabilities of LogShake.jsm under conditions that - * could cause races - */ - -/* jshint moz: true, esnext: true */ -/* global Cu, LogCapture, LogShake, ok, add_test, run_next_test, dump, - XPCOMUtils, do_get_profile, OS, volumeService, Promise, equal, - setup_logshake_mocks */ -/* exported run_test */ - -/* disable use strict warning */ -/* jshint -W097 */ - -"use strict"; - -function run_test() { - Cu.import("resource://gre/modules/LogShake.jsm"); - run_next_test(); -} - -add_test(setup_logshake_mocks); - -add_test(function test_logShake_captureLogs_waits_to_read() { - // Enable LogShake - LogShake.init(); - - // Save no logs synchronously (except properties) - LogShake.LOGS_WITH_PARSERS = {}; - - LogShake.captureLogs().then(logResults => { - LogShake.uninit(); - - ok(logResults.logFilenames.length > 0, "Should have filenames"); - ok(logResults.logPaths.length > 0, "Should have paths"); - ok(!logResults.compressed, "Should not be compressed"); - - // This assumes that the about:memory reading will only fail under abnormal - // circumstances. It does not check for screenshot.png because - // systemAppFrame is unavailable during xpcshell tests. - let hasAboutMemory = false; - - logResults.logFilenames.forEach(filename => { - // Because the about:memory log's filename has the PID in it we can not - // use simple equality but instead search for the "about_memory" part of - // the filename which will look like logshake-about_memory-{PID}.json.gz - if (filename.indexOf("about_memory") < 0) { - return; - } - hasAboutMemory = true; - }); - - ok(hasAboutMemory, - "LogShake's asynchronous read of about:memory should have succeeded."); - - run_next_test(); - }, - error => { - LogShake.uninit(); - - ok(false, "Should not have received error: " + error); - - run_next_test(); - }); -}); diff --git a/b2g/components/test/unit/test_signintowebsite.js b/b2g/components/test/unit/test_signintowebsite.js deleted file mode 100644 index 38d4fa79e..000000000 --- a/b2g/components/test/unit/test_signintowebsite.js +++ /dev/null @@ -1,322 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Tests for b2g/components/SignInToWebsite.jsm - -"use strict"; - -XPCOMUtils.defineLazyModuleGetter(this, "MinimalIDService", - "resource://gre/modules/identity/MinimalIdentity.jsm", - "IdentityService"); - -XPCOMUtils.defineLazyModuleGetter(this, "SignInToWebsiteController", - "resource://gre/modules/SignInToWebsite.jsm", - "SignInToWebsiteController"); - -Cu.import("resource://gre/modules/identity/LogUtils.jsm"); - -function log(...aMessageArgs) { - Logger.log.apply(Logger, ["test_signintowebsite"].concat(aMessageArgs)); -} - -function test_overall() { - do_check_neq(MinimalIDService, null); - run_next_test(); -} - -function objectContains(object, subset) { - let objectKeys = Object.keys(object); - let subsetKeys = Object.keys(subset); - - // can't have fewer keys than the subset - if (objectKeys.length < subsetKeys.length) { - return false; - } - - let key; - let success = true; - if (subsetKeys.length > 0) { - for (let i=0; i<subsetKeys.length; i++) { - key = subsetKeys[i]; - - // key exists in the source object - if (typeof object[key] === 'undefined') { - success = false; - break; - } - - // recursively check object values - else if (typeof subset[key] === 'object') { - if (typeof object[key] !== 'object') { - success = false; - break; - } - if (! objectContains(object[key], subset[key])) { - success = false; - break; - } - } - - else if (object[key] !== subset[key]) { - success = false; - break; - } - } - } - - return success; -} - -function test_object_contains() { - do_test_pending(); - - let someObj = { - pies: 42, - green: "spam", - flan: {yes: "please"} - }; - let otherObj = { - pies: 42, - flan: {yes: "please"} - }; - do_check_true(objectContains(someObj, otherObj)); - do_test_finished(); - run_next_test(); -} - -function test_mock_doc() { - do_test_pending(); - let mockedDoc = mockDoc({loggedInUser: null}, function(action, params) { - do_check_eq(action, 'coffee'); - do_test_finished(); - run_next_test(); - }); - - // A smoke test to ensure that mockedDoc is functioning correctly. - // There is presently no doCoffee method in Persona. - mockedDoc.doCoffee(); -} - -function test_watch() { - do_test_pending(); - - setup_test_identity("pie@food.gov", TEST_CERT, function() { - let controller = SignInToWebsiteController; - - let mockedDoc = mockDoc({loggedInUser: null}, function(action, params) { - do_check_eq(action, 'ready'); - controller.uninit(); - MinimalIDService.RP.unwatch(mockedDoc.id); - do_test_finished(); - run_next_test(); - }); - - controller.init({pipe: mockReceivingPipe()}); - MinimalIDService.RP.watch(mockedDoc, {}); - }); -} - -function test_request_login() { - do_test_pending(); - - setup_test_identity("flan@food.gov", TEST_CERT, function() { - let controller = SignInToWebsiteController; - - let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially( - function(action, params) { - do_check_eq(action, 'ready'); - do_check_eq(params, undefined); - }, - function(action, params) { - do_check_eq(action, 'login'); - do_check_eq(params, TEST_CERT); - controller.uninit(); - MinimalIDService.RP.unwatch(mockedDoc.id); - do_test_finished(); - run_next_test(); - } - )); - - controller.init({pipe: mockReceivingPipe()}); - MinimalIDService.RP.watch(mockedDoc, {}); - MinimalIDService.RP.request(mockedDoc.id, {}); - }); -} - -function test_request_logout() { - do_test_pending(); - - setup_test_identity("flan@food.gov", TEST_CERT, function() { - let controller = SignInToWebsiteController; - - let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially( - function(action, params) { - do_check_eq(action, 'ready'); - do_check_eq(params, undefined); - }, - function(action, params) { - do_check_eq(action, 'logout'); - do_check_eq(params, undefined); - controller.uninit(); - MinimalIDService.RP.unwatch(mockedDoc.id); - do_test_finished(); - run_next_test(); - } - )); - - controller.init({pipe: mockReceivingPipe()}); - MinimalIDService.RP.watch(mockedDoc, {}); - MinimalIDService.RP.logout(mockedDoc.id, {}); - }); -} - -function test_request_login_logout() { - do_test_pending(); - - setup_test_identity("unagi@food.gov", TEST_CERT, function() { - let controller = SignInToWebsiteController; - - let mockedDoc = mockDoc({loggedInUser: null}, call_sequentially( - function(action, params) { - do_check_eq(action, 'ready'); - do_check_eq(params, undefined); - }, - function(action, params) { - do_check_eq(action, 'login'); - do_check_eq(params, TEST_CERT); - }, - function(action, params) { - do_check_eq(action, 'logout'); - do_check_eq(params, undefined); - controller.uninit(); - MinimalIDService.RP.unwatch(mockedDoc.id); - do_test_finished(); - run_next_test(); - } - )); - - controller.init({pipe: mockReceivingPipe()}); - MinimalIDService.RP.watch(mockedDoc, {}); - MinimalIDService.RP.request(mockedDoc.id, {}); - MinimalIDService.RP.logout(mockedDoc.id, {}); - }); -} - -function test_logout_everywhere() { - do_test_pending(); - let logouts = 0; - - setup_test_identity("fugu@food.gov", TEST_CERT, function() { - let controller = SignInToWebsiteController; - - let mockedDoc1 = mockDoc({loggedInUser: null}, call_sequentially( - function(action, params) { - do_check_eq(action, 'ready'); - }, - function(action, params) { - do_check_eq(action, 'login'); - }, - function(action, params) { - // Result of logout from doc2. - // We don't know what order the logouts will occur in. - do_check_eq(action, 'logout'); - if (++logouts === 2) { - do_test_finished(); - run_next_test(); - } - } - )); - - let mockedDoc2 = mockDoc({loggedInUser: null}, call_sequentially( - function(action, params) { - do_check_eq(action, 'ready'); - }, - function(action, params) { - do_check_eq(action, 'login'); - }, - function(action, params) { - do_check_eq(action, 'logout'); - if (++logouts === 2) { - do_test_finished(); - run_next_test(); - } - } - )); - - controller.init({pipe: mockReceivingPipe()}); - MinimalIDService.RP.watch(mockedDoc1, {}); - MinimalIDService.RP.request(mockedDoc1.id, {}); - - MinimalIDService.RP.watch(mockedDoc2, {}); - MinimalIDService.RP.request(mockedDoc2.id, {}); - - // Logs out of both docs because they share the - // same origin. - MinimalIDService.RP.logout(mockedDoc2.id, {}); - }); -} - -function test_options_pass_through() { - do_test_pending(); - - // An meaningless structure for testing that RP messages preserve - // objects and their parameters as they are passed back and forth. - let randomMixedParams = { - loggedInUser: "juanita@mozilla.com", - forceAuthentication: true, - forceIssuer: "foo.com", - someThing: { - name: "Pertelote", - legs: 4, - nested: {bee: "Eric", remaining: "1/2"} - } - }; - - let mockedDoc = mockDoc(randomMixedParams, function(action, params) {}); - - function pipeOtherEnd(rpOptions, gaiaOptions) { - // Ensure that every time we receive a message, our mixed - // random params are contained in that message - do_check_true(objectContains(rpOptions, randomMixedParams)); - - switch (gaiaOptions.message) { - case "identity-delegate-watch": - MinimalIDService.RP.request(mockedDoc.id, {}); - break; - case "identity-delegate-request": - MinimalIDService.RP.logout(mockedDoc.id, {}); - break; - case "identity-delegate-logout": - do_test_finished(); - controller.uninit(); - MinimalIDService.RP.unwatch(mockedDoc.id); - run_next_test(); - break; - } - } - - let controller = SignInToWebsiteController; - controller.init({pipe: mockSendingPipe(pipeOtherEnd)}); - - MinimalIDService.RP.watch(mockedDoc, {}); -} - -var TESTS = [ - test_overall, - test_mock_doc, - test_object_contains, - - test_watch, - test_request_login, - test_request_logout, - test_request_login_logout, - test_logout_everywhere, - - test_options_pass_through -]; - -TESTS.forEach(add_test); - -function run_test() { - run_next_test(); -} diff --git a/b2g/components/test/unit/xpcshell.ini b/b2g/components/test/unit/xpcshell.ini deleted file mode 100644 index ca3df5bf6..000000000 --- a/b2g/components/test/unit/xpcshell.ini +++ /dev/null @@ -1,49 +0,0 @@ -[DEFAULT] -head = -tail = - -support-files = - data/test_logger_file - -[test_bug793310.js] - -[test_bug832946.js] - -[test_fxaccounts.js] -[test_signintowebsite.js] -head = head_identity.js -tail = - -# testing non gonk-specific stuff -[test_logcapture.js] - -[test_logcapture_gonk.js] -# can be slow because of what the test does, so let's give it some more time -# to avoid intermittents: bug 1212395 -requesttimeoutfactor = 2 -# only run on b2g builds due to requiring b2g-specific log files to exist -skip-if = toolkit != "gonk" - -[test_logparser.js] - -[test_logshake.js] - -[test_logshake_gonk.js] -# can be slow because of what the test does, so let's give it some more time -# to avoid intermittents: bug 1144499 -requesttimeoutfactor = 2 -head = head_logshake_gonk.js -# only run on b2g builds due to requiring b2g-specific log files to exist -skip-if = (toolkit != "gonk") - -[test_logshake_gonk_compression.js] -head = head_logshake_gonk.js -# only run on b2g builds due to requiring b2g-specific log files to exist -skip-if = (toolkit != "gonk") - -[test_logshake_readLog_gonk.js] -head = head_logshake_gonk.js -# only run on b2g builds due to requiring b2g-specific log files to exist -skip-if = (toolkit != "gonk") - -[test_aboutserviceworkers.js] |