usb-runtimes.js (3655B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 loader.lazyRequireGetter( 8 this, 9 "adb", 10 "resource://devtools/client/shared/remote-debugging/adb/adb.js", 11 true 12 ); 13 14 /** 15 * Used to represent a regular runtime returned by ADB. 16 */ 17 class UsbRuntime { 18 constructor(adbRuntime) { 19 this.id = adbRuntime.id; 20 this.deviceId = adbRuntime.deviceId; 21 this.deviceName = adbRuntime.deviceName; 22 this.shortName = adbRuntime.shortName; 23 this.socketPath = adbRuntime.socketPath; 24 this.isFenix = adbRuntime.isFenix; 25 this.isUnavailable = false; 26 this.isUnplugged = false; 27 this.versionName = adbRuntime.versionName; 28 } 29 } 30 31 /** 32 * Used when a device was detected, meaning USB debugging is enabled on the device, but no 33 * runtime/browser is available for connection. 34 */ 35 class UnavailableUsbRuntime { 36 constructor(adbDevice) { 37 this.id = adbDevice.id + "|unavailable"; 38 this.deviceId = adbDevice.id; 39 this.deviceName = adbDevice.name; 40 this.shortName = "Unavailable runtime"; 41 this.socketPath = null; 42 this.isFenix = false; 43 this.isUnavailable = true; 44 this.isUnplugged = false; 45 this.versionName = null; 46 } 47 } 48 49 /** 50 * Used to represent USB devices that were previously connected but are now missing 51 * (presumably after being unplugged/disconnected from the computer). 52 */ 53 class UnpluggedUsbRuntime { 54 constructor(deviceId, deviceName) { 55 this.id = deviceId + "|unplugged"; 56 this.deviceId = deviceId; 57 this.deviceName = deviceName; 58 this.shortName = "Unplugged runtime"; 59 this.socketPath = null; 60 this.isFenix = false; 61 this.isUnavailable = true; 62 this.isUnplugged = true; 63 this.versionName = null; 64 } 65 } 66 67 /** 68 * Map used to keep track of discovered usb devices. Will be used to create the unplugged 69 * usb runtimes. 70 */ 71 const devices = new Map(); 72 73 /** 74 * This module provides a collection of helper methods to detect USB runtimes whom Firefox 75 * is running on. 76 */ 77 function addUSBRuntimesObserver(listener) { 78 adb.registerListener(listener); 79 } 80 exports.addUSBRuntimesObserver = addUSBRuntimesObserver; 81 82 async function getUSBRuntimes() { 83 // Get the available runtimes 84 const runtimes = adb.getRuntimes().map(r => new UsbRuntime(r)); 85 86 // Get devices found by ADB, but without any available runtime. 87 const runtimeDevices = runtimes.map(r => r.deviceId); 88 const unavailableRuntimes = adb 89 .getDevices() 90 .filter(d => !runtimeDevices.includes(d.id)) 91 .map(d => new UnavailableUsbRuntime(d)); 92 93 // Add all devices to the map detected devices. 94 const allRuntimes = runtimes.concat(unavailableRuntimes); 95 for (const runtime of allRuntimes) { 96 devices.set(runtime.deviceId, runtime.deviceName); 97 } 98 99 // Get devices previously found by ADB but no longer available. 100 const currentDevices = allRuntimes.map(r => r.deviceId); 101 const detectedDevices = [...devices.keys()]; 102 const unpluggedDevices = detectedDevices.filter( 103 id => !currentDevices.includes(id) 104 ); 105 const unpluggedRuntimes = unpluggedDevices.map(deviceId => { 106 const deviceName = devices.get(deviceId); 107 return new UnpluggedUsbRuntime(deviceId, deviceName); 108 }); 109 110 return allRuntimes.concat(unpluggedRuntimes); 111 } 112 exports.getUSBRuntimes = getUSBRuntimes; 113 114 function removeUSBRuntimesObserver(listener) { 115 adb.unregisterListener(listener); 116 } 117 exports.removeUSBRuntimesObserver = removeUSBRuntimesObserver; 118 119 function refreshUSBRuntimes() { 120 return adb.updateRuntimes(); 121 } 122 exports.refreshUSBRuntimes = refreshUSBRuntimes;