merge b2g-inbound to mozilla-central
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 16 Dec 2013 10:17:43 +0100
changeset 160620 0d11fce4f8454d6544022ef70a5d577d69d661b9
parent 160598 4f38b8a96681ad077c9c2c74727c3abfb1cc13c2 (current diff)
parent 160619 68df51ee946bf71eb7e92541d41735ed78b153e3 (diff)
child 160621 69a5abf01ed1443b8fe1051c78e713e9988b8969
child 160624 832ef0e8771edb2e631072d71f7376dd398996c6
child 160682 63f5446f942e35abfcca9dd00b225441e2ee9b20
child 160697 05574fb19ebf9c1351b9752384ce099be885cc01
push id37652
push userryanvm@gmail.com
push dateMon, 16 Dec 2013 14:05:12 +0000
treeherdermozilla-inbound@69a5abf01ed1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone29.0a1
first release with
nightly linux32
0d11fce4f845 / 29.0a1 / 20131216030202 / files
nightly linux64
0d11fce4f845 / 29.0a1 / 20131216030202 / files
nightly mac
0d11fce4f845 / 29.0a1 / 20131216030202 / files
nightly win32
0d11fce4f845 / 29.0a1 / 20131216030202 / files
nightly win64
0d11fce4f845 / 29.0a1 / 20131216030202 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge b2g-inbound to mozilla-central
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -218,16 +218,17 @@ Components.utils.import('resource://gre/
 #ifdef MOZ_WIDGET_GONK
 let AdbController = {
   DEBUG: false,
   locked: undefined,
   remoteDebuggerEnabled: undefined,
   lockEnabled: undefined,
   disableAdbTimer: null,
   disableAdbTimeoutHours: 12,
+  umsActive: false,
 
   debug: function(str) {
     dump("AdbController: " + str + "\n");
   },
 
   setLockscreenEnabled: function(value) {
     this.lockEnabled = value;
     if (this.DEBUG) {
@@ -299,16 +300,61 @@ let AdbController = {
       // disconnected, if the user happens to be using logcat.
       dump("AdbController: ADB timer expired - disabling ADB\n");
       navigator.mozSettings.createLock().set(
         {'devtools.debugger.remote-enabled': false});
     }
   },
 
   updateState: function() {
+    this.umsActive = false;
+    this.storages = navigator.getDeviceStorages('sdcard');
+    this.updateStorageState(0);
+  },
+
+  updateStorageState: function(storageIndex) {
+    if (storageIndex >= this.storages.length) {
+      // We've iterated through all of the storage objects, now we can
+      // really do updateStateInternal.
+      this.updateStateInternal();
+      return;
+    }
+    let storage = this.storages[storageIndex];
+    if (this.DEBUG) {
+      this.debug("Checking availability of storage: '" +
+                 storage.storageName);
+    }
+
+    let req = storage.available();
+    req.onsuccess = function(e) {
+      if (this.DEBUG) {
+        this.debug("Storage: '" + storage.storageName + "' is '" +
+                   e.target.result);
+      }
+      if (e.target.result == 'shared') {
+        // We've found a storage area that's being shared with the PC.
+        // We can stop looking now.
+        this.umsActive = true;
+        this.updateStateInternal();
+        return;
+      }
+      this.updateStorageState(storageIndex + 1);
+    }.bind(this);
+    req.onerror = function(e) {
+      dump("AdbController: error querying storage availability for '" +
+           this.storages[storageIndex].storageName + "' (ignoring)\n");
+      this.updateStorageState(storageIndex + 1);
+    }.bind(this);
+  },
+
+  updateStateInternal: function() {
+    if (this.DEBUG) {
+      this.debug("updateStateInternal: called");
+    }
+
     if (this.remoteDebuggerEnabled === undefined ||
         this.lockEnabled === undefined ||
         this.locked === undefined) {
       // Part of initializing the settings database will cause the observers
       // to trigger. We want to wait until both have been initialized before
       // we start changing ther adb state. Without this then we can wind up
       // toggling adb off and back on again (or on and back off again).
       //
@@ -333,18 +379,25 @@ let AdbController = {
     // Check if we have a remote debugging session going on. If so, we won't
     // disable adb even if the screen is locked.
     let isDebugging = DebuggerServer._connections &&
                       Object.keys(DebuggerServer._connections).length > 0;
     if (this.DEBUG) {
       this.debug("isDebugging=" + isDebugging);
     }
 
+    // If USB Mass Storage, USB tethering, or a debug session is active,
+    // then we don't want to disable adb in an automatic fashion (i.e.
+    // when the screen locks or due to timeout).
+    let sysUsbConfig = libcutils.property_get("sys.usb.config");
+    let rndisActive = (sysUsbConfig.split(",").indexOf("rndis") >= 0);
+    let usbFuncActive = rndisActive || this.umsActive || isDebugging;
+
     let enableAdb = this.remoteDebuggerEnabled &&
-      (!(this.lockEnabled && this.locked) || isDebugging);
+      (!(this.lockEnabled && this.locked) || usbFuncActive);
 
     let useDisableAdbTimer = true;
     try {
       if (Services.prefs.getBoolPref("marionette.defaultPrefs.enabled")) {
         // Marionette is enabled. Marionette requires that adb be on (and also
         // requires that remote debugging be off). The fact that marionette
         // is enabled also implies that we're doing a non-production build, so
         // we want adb enabled all of the time.
@@ -354,17 +407,18 @@ let AdbController = {
     } catch (e) {
       // This means that the pref doesn't exist. Which is fine. We just leave
       // enableAdb alone.
     }
     if (this.DEBUG) {
       this.debug("updateState: enableAdb = " + enableAdb +
                  " remoteDebuggerEnabled = " + this.remoteDebuggerEnabled +
                  " lockEnabled = " + this.lockEnabled +
-                 " locked = " + this.locked);
+                 " locked = " + this.locked +
+                 " usbFuncActive = " + usbFuncActive);
     }
 
     // Configure adb.
     let currentConfig = libcutils.property_get("persist.sys.usb.config");
     let configFuncs = currentConfig.split(",");
     let adbIndex = configFuncs.indexOf("adb");
 
     if (enableAdb) {
@@ -386,17 +440,17 @@ let AdbController = {
       }
       try {
         libcutils.property_set("persist.sys.usb.config", newConfig);
       } catch(e) {
         dump("Error configuring adb: " + e);
       }
     }
     if (useDisableAdbTimer) {
-      if (enableAdb && !isDebugging) {
+      if (enableAdb && !usbFuncActive) {
         this.startDisableAdbTimer();
       } else {
         this.stopDisableAdbTimer();
       }
     }
   }
 };
 
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "62c0ad5b88f15d5da1cc2496b9534087dbc5d015", 
+    "revision": "f63fa4e31cea664886f43504529d96bc046506fc", 
     "repo_path": "/integration/gaia-central"
 }
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -2953,18 +2953,25 @@ onInstallSuccessAck: function onInstallS
       // and assume the build date is correct (which we cannot
       // really know either).
       let isLaterThanBuildTime = Date.now() > PLATFORM_BUILD_ID_TIME;
 
       let isSigned;
 
       if (Components.isSuccessCode(result)) {
         isSigned = true;
-      } else if (result == Cr.NS_ERROR_FILE_CORRUPTED) {
+      } else if (result == Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY ||
+                 result == Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY ||
+                 result == Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) {
         throw "APP_PACKAGE_CORRUPTED";
+      } else if (result == Cr.NS_ERROR_FILE_CORRUPTED ||
+                 result == Cr.NS_ERROR_SIGNED_JAR_ENTRY_TOO_LARGE ||
+                 result == Cr.NS_ERROR_SIGNED_JAR_ENTRY_INVALID ||
+                 result == Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID) {
+        throw "APP_PACKAGE_INVALID";
       } else if ((!aIsLocalFileInstall || isLaterThanBuildTime) &&
                  (result != Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED)) {
         throw "INVALID_SIGNATURE";
       } else {
         // If it's a localFileInstall and the validation failed
         // because of a expired certificate, just assume it was valid
         // and that the error occurred because the system time has not
         // been set yet.
--- a/dom/downloads/src/DownloadsAPI.js
+++ b/dom/downloads/src/DownloadsAPI.js
@@ -201,19 +201,19 @@ function DOMDownloadImpl() {
 
   this.wrappedJSObject = this;
   this.totalBytes = 0;
   this.currentBytes = 0;
   this.url = null;
   this.path = null;
   this.state = "stopped";
   this.contentType = null;
-  this.error = null;
 
   /* fields that require getters/setters */
+  this._error = null;
   this._startTime = new Date();
 
   /* private fields */
   this.id = null;
 }
 
 DOMDownloadImpl.prototype = {
 
@@ -242,16 +242,24 @@ DOMDownloadImpl.prototype = {
   set onstatechange(aHandler) {
     this.__DOM_IMPL__.setEventHandler("onstatechange", aHandler);
   },
 
   get onstatechange() {
     return this.__DOM_IMPL__.getEventHandler("onstatechange");
   },
 
+  get error() {
+    return this._error;
+  },
+
+  set error(aError) {
+    this._error = aError;
+  },
+
   get startTime() {
     return this._startTime;
   },
 
   set startTime(aStartTime) {
     if (aStartTime instanceof Date) {
       this._startTime = aStartTime;
     }
--- a/dom/downloads/tests/test_downloads_basic.html
+++ b/dom/downloads/tests/test_downloads_basic.html
@@ -46,24 +46,20 @@ function checkConsistentDownloadAttribut
   var href = document.getElementById("download1").getAttribute("href");
   var expectedServeURL = baseServeURL + href;
   var expectedDownloadPath = baseDownloadPath + "test.bin";
 
   // bug 945323: Download path isn't honoring download attribute
   todo(download.path === expectedDownloadPath,
        "Download path = " + expectedDownloadPath);
 
-  // bug 948287: Accessing startTime attribute at download start fires
-  //             NS_ERROR_UNEXPECTED in emulator
-  //ok(download.startTime >= todayDate,
-  //   "Download start time should be greater than or equal to today");
+  ok(download.startTime >= todayDate,
+     "Download start time should be greater than or equal to today");
 
-  // bug 945366: Accessing error attribute at download start fires
-  //             NS_ERROR_UNEXPECTED in emulator
-  //is(download.error, null, "Download does not have an error");
+  is(download.error, null, "Download does not have an error");
 
   is(download.url, expectedServeURL,
      "Download URL = " + expectedServeURL);
   ok(download.id !== null, "Download id is defined");
   is(download.contentType, "application/octet-stream",
      "Download content type is application/octet-stream");
 }
 
--- a/dom/inputmethod/forms.js
+++ b/dom/inputmethod/forms.js
@@ -410,17 +410,17 @@ let FormAssistant = {
         }
 
         // We may receive multiple resize events in quick succession, so wait
         // a bit before scrolling the input element into view.
         if (this.focusedElement) {
           this.scrollIntoViewTimeout = content.setTimeout(function () {
             this.scrollIntoViewTimeout = null;
             if (this.focusedElement && !FormVisibility.isVisible(this.focusedElement)) {
-              this.focusedElement.scrollIntoView(false);
+              scrollSelectionOrElementIntoView(this.focusedElement);
             }
           }.bind(this), RESIZE_SCROLL_DELAY);
         }
         break;
 
       case "input":
         if (this.focusedElement) {
           // When the text content changes, notify the keyboard
@@ -1012,16 +1012,33 @@ function setSelectionRange(element, star
 
     let selectionLength = end - start;
     while (getContentEditableSelectionLength(element, sel) < selectionLength) {
       sel.modify("extend", "forward", "character");
     }
   }
 }
 
+/**
+ * Scroll the given element into view.
+ *
+ * Calls scrollSelectionIntoView for contentEditable elements.
+ */
+function scrollSelectionOrElementIntoView(element) {
+  let editor = getPlaintextEditor(element);
+  if (editor) {
+    editor.selectionController.scrollSelectionIntoView(
+      Ci.nsISelectionController.SELECTION_NORMAL,
+      Ci.nsISelectionController.SELECTION_FOCUS_REGION,
+      Ci.nsISelectionController.SCROLL_SYNCHRONOUS);
+  } else {
+      element.scrollIntoView(false);
+  }
+}
+
 // Get nsIPlaintextEditor object from an input field
 function getPlaintextEditor(element) {
   let editor = null;
   // Get nsIEditor
   if (isPlainTextField(element)) {
     // Get from the <input> and <textarea> elements
     editor = element.QueryInterface(Ci.nsIDOMNSEditableElement).editor;
   } else if (isContentEditable(element)) {
--- a/dom/nfc/nsNfc.js
+++ b/dom/nfc/nsNfc.js
@@ -133,18 +133,22 @@ MozNFCPeer.prototype = {
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 };
 
 /**
  * Navigator NFC object
  */
 function mozNfc() {
   debug("In mozNfc Constructor");
-  this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
-                             .getService(Ci.nsINfcContentHelper);
+  try {
+    this._nfcContentHelper = Cc["@mozilla.org/nfc/content-helper;1"]
+                               .getService(Ci.nsINfcContentHelper);
+  } catch(e) {
+    debug("No NFC support.")
+  }
 }
 mozNfc.prototype = {
   _nfcContentHelper: null,
   _window: null,
   _wrap: function _wrap(obj) {
     return ObjectWrapper.wrap(obj, this._window);
   },
 
--- a/dom/system/gonk/Nfc.js
+++ b/dom/system/gonk/Nfc.js
@@ -20,16 +20,19 @@
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
 let NFC = {};
 Cu.import("resource://gre/modules/nfc_consts.js", NFC);
 
+Cu.import("resource://gre/modules/systemlibs.js");
+const NFC_ENABLED = libcutils.property_get("ro.moz.nfc.enabled", "false") === "true";
+
 // set to true in nfc_consts.js to see debug messages
 let DEBUG = NFC.DEBUG_NFC;
 
 let debug;
 if (DEBUG) {
   debug = function (s) {
     dump("-*- Nfc: " + s + "\n");
   };
@@ -622,9 +625,11 @@ Nfc.prototype = {
     }
   },
 
   setConfig: function setConfig(prop) {
     this.sendToWorker("config", prop);
   }
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Nfc]);
+if (NFC_ENABLED) {
+  this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Nfc]);
+}
--- a/dom/system/gonk/NfcContentHelper.js
+++ b/dom/system/gonk/NfcContentHelper.js
@@ -21,16 +21,19 @@ const {classes: Cc, interfaces: Ci, util
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 
 let NFC = {};
 Cu.import("resource://gre/modules/nfc_consts.js", NFC);
 
+Cu.import("resource://gre/modules/systemlibs.js");
+const NFC_ENABLED = libcutils.property_get("ro.moz.nfc.enabled", "false") === "true";
+
 // set to true to in nfc_consts.js to see debug messages
 let DEBUG = NFC.DEBUG_CONTENT_HELPER;
 
 let debug;
 if (DEBUG) {
   debug = function (s) {
     dump("-*- NfcContentHelper: " + s + "\n");
   };
@@ -379,9 +382,11 @@ NfcContentHelper.prototype = {
     if (message.status !== NFC.GECKO_NFC_ERROR_SUCCESS) {
       this.fireRequestError(requestId, result.status);
     } else {
       this.fireRequestSuccess(requestId, result);
     }
   },
 };
 
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NfcContentHelper]);
+if (NFC_ENABLED) {
+  this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NfcContentHelper]);
+}
--- a/dom/webidl/Downloads.webidl
+++ b/dom/webidl/Downloads.webidl
@@ -54,17 +54,17 @@ interface DOMDownload : EventTarget {
   readonly attribute Date startTime;
 
   // An opaque identifier for this download. All instances of the same
   // download (eg. in different windows) will have the same id.
   readonly attribute DOMString id;
 
   // A DOM error object, that will be not null when a download is stopped
   // because something failed.
-  readonly attribute DOMError error;
+  readonly attribute DOMError? error;
 
   // Pauses the download.
   Promise pause();
 
   // Resumes the download. This resolves only once the download has
   // succeeded.
   Promise resume();
 
--- a/testing/mochitest/b2g-desktop.json
+++ b/testing/mochitest/b2g-desktop.json
@@ -289,43 +289,16 @@
     "dom/file/test/test_readonly_lockedfiles.html":"",
     "dom/file/test/test_success_events_after_abort.html":"",
     "dom/file/test/test_truncate.html":"",
     "dom/file/test/test_workers.html":"",
     "dom/file/test/test_write_read_data.html":"",
 
     "dom/imptests/editing/conformancetest/test_runtest.html":"takes too long",
 
-    "dom/media/tests/mochitest/test_dataChannel_basicAudio.html":"bug 908473",
-    "dom/media/tests/mochitest/test_dataChannel_basicAudioVideo.html":"",
-    "dom/media/tests/mochitest/test_dataChannel_basicAudioVideoCombined.html":"",
-    "dom/media/tests/mochitest/test_dataChannel_basicDataOnly.html":"",
-    "dom/media/tests/mochitest/test_dataChannel_basicVideo.html":"",
-    "dom/media/tests/mochitest/test_dataChannel_noOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_addCandidateInHaveLocalOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_basicAudio.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_basicAudioVideo.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_basicVideo.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_bug822674.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_bug825703.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_bug827843.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_bug834153.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_bug835370.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_errorCallbacks.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInHaveLocalOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setLocalAnswerInStable.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setLocalOfferInHaveRemoteOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInHaveRemoteOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setRemoteAnswerInStable.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_setRemoteOfferInHaveLocalOffer.html":"",
-    "dom/media/tests/mochitest/test_peerConnection_throwInCallbacks.html":"",
     "dom/media/tests/ipc/test_ipc.html":"nested ipc not working",
 
     "dom/network/tests/test_networkstats_basics.html":"Will be fixed in bug 858005",
     "dom/permission/tests/test_permission_basics.html":"Bug 907770",
 
     "dom/tests/mochitest/bugs/test_bug335976.xhtml":"",
     "dom/tests/mochitest/bugs/test_bug369306.html":"test timed out, can't focus back from popup window to opener?",
     "dom/tests/mochitest/bugs/test_bug396843.html":"",