Bug 915974 - Make adb stay on if USB functions are being used. r=fabrice, a=lsblakk
authorDave Hylands <dhylands@mozilla.com>
Sat, 14 Dec 2013 11:44:57 -0800
changeset 169268 284895507d2d118473a93d472b51a98f94898ac4
parent 169267 3d50d3496a640d281fe06db8c78601e23848b105
child 169269 24e822034332748994fb9673012dd4d2f95519e0
push id4961
push userryanvm@gmail.com
push dateThu, 16 Jan 2014 14:21:24 +0000
treeherdermozilla-aurora@51dd19c057f7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfabrice, lsblakk
bugs915974
milestone28.0a2
Bug 915974 - Make adb stay on if USB functions are being used. r=fabrice, a=lsblakk
b2g/chrome/content/settings.js
--- 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();
       }
     }
   }
 };