0
# Android Development
1
2
ADB integration for developing and testing extensions on Firefox for Android devices. Provides device management, file transfer, APK handling, and remote debugging capabilities.
3
4
## Capabilities
5
6
### ADB Utilities Class
7
8
Comprehensive Android Debug Bridge integration for Firefox extension development on mobile devices.
9
10
```javascript { .api }
11
class ADBUtils {
12
constructor(params: ADBParams);
13
/** Discover connected Android devices */
14
discoverDevices(): Promise<string[]>;
15
/** Get current user ID on device */
16
getCurrentUser(deviceId: string): Promise<string>;
17
/** Execute shell command on device */
18
runShellCommand(deviceId: string, cmd: string): Promise<string>;
19
/** Find installed Firefox APKs on device */
20
discoverInstalledFirefoxAPKs(deviceId: string, firefoxApk?: string): Promise<string[]>;
21
/** Force stop an APK on device */
22
amForceStopAPK(deviceId: string, apk: string): Promise<void>;
23
/** Create or get artifacts directory on device */
24
getOrCreateArtifactsDir(deviceId: string): Promise<string>;
25
/** Detect or remove old artifacts from device */
26
detectOrRemoveOldArtifacts(deviceId: string, removeArtifactDirs?: boolean): Promise<string[]>;
27
/** Clear artifacts directory on device */
28
clearArtifactsDir(deviceId: string): Promise<void>;
29
/** Upload file from computer to device */
30
pushFile(deviceId: string, localPath: string, devicePath: string): Promise<void>;
31
/** Launch Firefox APK with extension */
32
startFirefoxAPK(deviceId: string, apk: string, apkComponent?: string, deviceProfileDir?: string): Promise<void>;
33
/** Control discovery abort mechanism */
34
setUserAbortDiscovery(value: boolean): void;
35
/** Discover remote debugging Unix socket */
36
discoverRDPUnixSocket(deviceId: string, apk: string, options?: DiscoveryOptions): Promise<string>;
37
/** Set up ADB port forwarding */
38
setupForward(deviceId: string, remote: string, local: string): Promise<void>;
39
}
40
41
interface ADBParams {
42
/** Path to adb binary */
43
adbBin?: string;
44
/** ADB host to connect to */
45
adbHost?: string;
46
/** ADB port number */
47
adbPort?: string;
48
/** Target device ID */
49
adbDevice?: string;
50
/** Discovery timeout in milliseconds */
51
adbDiscoveryTimeout?: number;
52
/** Enable verbose logging */
53
verbose?: boolean;
54
}
55
56
interface DiscoveryOptions {
57
/** Maximum retry attempts */
58
maxTries?: number;
59
/** Retry delay in milliseconds */
60
retryInterval?: number;
61
}
62
```
63
64
**Usage Examples:**
65
66
```javascript
67
import { ADBUtils } from "web-ext/util/adb";
68
69
// Initialize ADB utilities
70
const adb = new ADBUtils({
71
adbBin: '/usr/local/bin/adb',
72
adbDevice: 'emulator-5554',
73
adbDiscoveryTimeout: 30000
74
});
75
76
// Discover and connect to devices
77
const devices = await adb.discoverDevices();
78
console.log('Found devices:', devices);
79
80
// Upload extension to device
81
await adb.pushFile('emulator-5554', './extension.xpi', '/data/local/tmp/extension.xpi');
82
83
// Start Firefox with extension
84
await adb.startFirefoxAPK('emulator-5554', 'org.mozilla.fenix');
85
```
86
87
### Device Discovery Functions
88
89
Standalone functions for device and APK discovery without class instantiation.
90
91
```javascript { .api }
92
/**
93
* List all connected ADB devices
94
* @param adbBin - Path to adb binary
95
* @returns Promise resolving to array of device IDs
96
*/
97
function listADBDevices(adbBin?: string): Promise<string[]>;
98
99
/**
100
* List Firefox APKs installed on a device
101
* @param deviceId - Target device identifier
102
* @param adbBin - Path to adb binary
103
* @returns Promise resolving to array of APK package names
104
*/
105
function listADBFirefoxAPKs(deviceId: string, adbBin?: string): Promise<string[]>;
106
```
107
108
**Usage Examples:**
109
110
```javascript
111
import { listADBDevices, listADBFirefoxAPKs } from "web-ext/util/adb";
112
113
// Quick device discovery
114
const devices = await listADBDevices();
115
if (devices.length === 0) {
116
console.log('No Android devices found');
117
return;
118
}
119
120
// Find Firefox installations
121
const firefoxApks = await listADBFirefoxAPKs(devices[0]);
122
console.log('Firefox APKs:', firefoxApks);
123
// Output: ['org.mozilla.firefox', 'org.mozilla.fenix', 'org.mozilla.firefox_beta']
124
```
125
126
### Device Path Management
127
128
Constants and utilities for managing file paths on Android devices.
129
130
```javascript { .api }
131
/** Base directory for temporary files on Android device */
132
const DEVICE_DIR_BASE: string = "/data/local/tmp/";
133
134
/** Prefix for web-ext artifact directories */
135
const ARTIFACTS_DIR_PREFIX: string = "web-ext-artifacts-";
136
```
137
138
### Remote Debugging Integration
139
140
Set up remote debugging connections for Firefox Android extensions.
141
142
```javascript { .api }
143
/**
144
* Discover and connect to Firefox remote debugging socket
145
* @param deviceId - Target Android device
146
* @param apk - Firefox APK package name
147
* @param options - Discovery configuration
148
* @returns Promise resolving to Unix socket path
149
*/
150
async function discoverRDPUnixSocket(
151
deviceId: string,
152
apk: string,
153
options?: DiscoveryOptions
154
): Promise<string>;
155
156
/**
157
* Set up port forwarding for remote debugging
158
* @param deviceId - Target device
159
* @param remote - Remote socket/port on device
160
* @param local - Local port on development machine
161
* @returns Promise that resolves when forwarding is established
162
*/
163
async function setupForward(
164
deviceId: string,
165
remote: string,
166
local: string
167
): Promise<void>;
168
```
169
170
**Usage Example:**
171
172
```javascript
173
// Set up remote debugging
174
const socket = await adb.discoverRDPUnixSocket('emulator-5554', 'org.mozilla.fenix', {
175
maxTries: 10,
176
retryInterval: 1000
177
});
178
179
// Forward remote debugging port
180
await adb.setupForward('emulator-5554', socket, '6000');
181
console.log('Remote debugging available at localhost:6000');
182
```
183
184
### File Transfer Operations
185
186
Manage files and directories on Android devices.
187
188
```javascript { .api }
189
/**
190
* Upload file from local system to Android device
191
* @param deviceId - Target device
192
* @param localPath - Source file path on computer
193
* @param devicePath - Destination path on device
194
* @returns Promise that resolves when transfer completes
195
*/
196
async function pushFile(
197
deviceId: string,
198
localPath: string,
199
devicePath: string
200
): Promise<void>;
201
202
/**
203
* Create artifacts directory on device
204
* @param deviceId - Target device
205
* @returns Promise resolving to created directory path
206
*/
207
async function getOrCreateArtifactsDir(deviceId: string): Promise<string>;
208
209
/**
210
* Clean up old artifact directories
211
* @param deviceId - Target device
212
* @param removeArtifactDirs - Whether to remove old directories
213
* @returns Promise resolving to list of old directories
214
*/
215
async function detectOrRemoveOldArtifacts(
216
deviceId: string,
217
removeArtifactDirs?: boolean
218
): Promise<string[]>;
219
```
220
221
### APK Management
222
223
Handle Firefox APK operations on Android devices.
224
225
```javascript { .api }
226
/**
227
* Force stop a running APK
228
* @param deviceId - Target device
229
* @param apk - APK package name to stop
230
* @returns Promise that resolves when APK is stopped
231
*/
232
async function amForceStopAPK(deviceId: string, apk: string): Promise<void>;
233
234
/**
235
* Launch Firefox APK with optional extension
236
* @param deviceId - Target device
237
* @param apk - Firefox APK package name
238
* @param apkComponent - Specific APK component (optional)
239
* @param deviceProfileDir - Profile directory on device (optional)
240
* @returns Promise that resolves when APK is started
241
*/
242
async function startFirefoxAPK(
243
deviceId: string,
244
apk: string,
245
apkComponent?: string,
246
deviceProfileDir?: string
247
): Promise<void>;
248
```
249
250
**Firefox APK Examples:**
251
- `org.mozilla.firefox` - Firefox Release
252
- `org.mozilla.firefox_beta` - Firefox Beta
253
- `org.mozilla.fenix` - Firefox Nightly
254
- `org.mozilla.fenix.nightly` - Firefox Nightly (alternative)
255
- `org.mozilla.fennec_aurora` - Firefox Developer Edition (legacy)
256
257
### Shell Command Execution
258
259
Execute arbitrary shell commands on Android devices.
260
261
```javascript { .api }
262
/**
263
* Execute shell command on Android device
264
* @param deviceId - Target device identifier
265
* @param cmd - Shell command to execute
266
* @returns Promise resolving to command output
267
*/
268
async function runShellCommand(deviceId: string, cmd: string): Promise<string>;
269
270
/**
271
* Get current user ID on Android device
272
* @param deviceId - Target device
273
* @returns Promise resolving to user ID string
274
*/
275
async function getCurrentUser(deviceId: string): Promise<string>;
276
```
277
278
**Usage Examples:**
279
280
```javascript
281
// Check device storage
282
const storage = await adb.runShellCommand('emulator-5554', 'df -h');
283
console.log('Device storage:', storage);
284
285
// Get device info
286
const userInfo = await adb.getCurrentUser('emulator-5554');
287
console.log('Current user:', userInfo);
288
289
// Check running processes
290
const processes = await adb.runShellCommand('emulator-5554', 'ps | grep firefox');
291
console.log('Firefox processes:', processes);
292
```
293
294
### Error Handling and Troubleshooting
295
296
Common error scenarios and solutions:
297
298
```javascript { .api }
299
interface ADBError extends Error {
300
/** ADB-specific error code */
301
code: string;
302
/** Device ID where error occurred */
303
deviceId?: string;
304
/** ADB command that failed */
305
command?: string;
306
}
307
```
308
309
**Common Error Codes:**
310
- `DEVICE_NOT_FOUND` - Device not connected or not recognized
311
- `ADB_NOT_FOUND` - ADB binary not found in PATH
312
- `PERMISSION_DENIED` - Insufficient permissions for device access
313
- `TIMEOUT` - Operation timed out
314
- `APK_NOT_FOUND` - Firefox APK not installed on device
315
- `CONNECTION_FAILED` - Cannot establish ADB connection
316
317
**Usage Example with Error Handling:**
318
319
```javascript
320
try {
321
const adb = new ADBUtils({
322
adbDevice: 'emulator-5554',
323
adbDiscoveryTimeout: 30000
324
});
325
326
const devices = await adb.discoverDevices();
327
if (devices.length === 0) {
328
throw new Error('No Android devices found. Please connect a device or start an emulator.');
329
}
330
331
await adb.startFirefoxAPK(devices[0], 'org.mozilla.fenix');
332
console.log('Firefox started successfully on device');
333
334
} catch (error) {
335
if (error.code === 'DEVICE_NOT_FOUND') {
336
console.error('Device not found. Check USB debugging is enabled.');
337
} else if (error.code === 'APK_NOT_FOUND') {
338
console.error('Firefox not installed. Install Firefox from Play Store or APK.');
339
} else {
340
console.error('ADB operation failed:', error.message);
341
}
342
}
343
```
344
345
### Integration with Extension Runners
346
347
ADB utilities integrate seamlessly with web-ext's extension runner system:
348
349
```javascript
350
// Android-specific run parameters
351
await cmd.run({
352
sourceDir: './extension',
353
target: ['firefox-android'],
354
adbDevice: 'emulator-5554',
355
firefoxApk: 'org.mozilla.fenix',
356
adbRemoveOldArtifacts: true
357
});
358
```
359
360
This automatically uses ADBUtils internally to:
361
1. Discover the specified device
362
2. Install the extension
363
3. Start Firefox with the extension loaded
364
4. Set up remote debugging connection
365
5. Enable hot reloading for development