@@ -10,17 +10,15 @@ import {DEFAULT_ADB_EXEC_TIMEOUT, cloneDeep, getSdkRootFromEnv, memoize, zip} fr
1010import type {
1111 ConnectedDevicesOptions ,
1212 Device ,
13- VerboseDevice ,
1413 AvdLaunchOptions ,
1514 Version ,
1615 RootResult ,
1716 ShellExecOptions ,
1817 SpecialAdbExecOptions ,
18+ TFullOutputOption ,
1919 ExecResult ,
2020} from './types' ;
2121
22- type AdbExecOptions = ShellExecOptions & SpecialAdbExecOptions ;
23-
2422const DEFAULT_ADB_REBOOT_RETRIES = 90 ;
2523const LINKER_WARNING_REGEXP = / ^ W A R N I N G : l i n k e r .+ $ / m;
2624const ADB_RETRY_ERROR_PATTERNS = [
@@ -211,32 +209,17 @@ export async function getBinaryFromPath(this: ADB, binaryName: string): Promise<
211209 }
212210}
213211
214- /**
215- * Retrieve the list of devices visible to adb.
216- *
217- * @param opts - Options with `verbose: true` for long `adb devices -l` output
218- * @returns Array of connected devices with product/model metadata
219- * @throws {Error } If adb devices command fails or returns unexpected output
220- */
221- export async function getConnectedDevices (
222- this : ADB ,
223- opts : ConnectedDevicesOptions & { verbose : true } ,
224- ) : Promise < VerboseDevice [ ] > ;
225212/**
226213 * Retrieve the list of devices visible to adb.
227214 *
228215 * @param opts - Options for device retrieval
229216 * @returns Array of connected devices
230217 * @throws {Error } If adb devices command fails or returns unexpected output
231218 */
232- export async function getConnectedDevices (
233- this : ADB ,
234- opts ?: ConnectedDevicesOptions ,
235- ) : Promise < Device [ ] > ;
236219export async function getConnectedDevices (
237220 this : ADB ,
238221 opts : ConnectedDevicesOptions = { } ,
239- ) : Promise < Device [ ] | VerboseDevice [ ] > {
222+ ) : Promise < Device [ ] > {
240223 log . debug ( 'Getting connected devices' ) ;
241224 const args = [ ...this . executable . defaultArgs , 'devices' ] ;
242225 if ( opts . verbose ) {
@@ -273,32 +256,15 @@ export async function getConnectedDevices(
273256 . map ( ( line ) => {
274257 // state is "device", afaic
275258 const [ udid , state , ...description ] = line . split ( / \s + / ) ;
276- if ( ! opts . verbose ) {
277- return { udid, state} ;
278- }
279- const device : VerboseDevice = {
280- udid,
281- state,
282- product : '' ,
283- model : '' ,
284- device : '' ,
285- } ;
286- for ( const entry of description ) {
287- if ( ! entry . includes ( ':' ) ) {
288- continue ;
289- }
290- // each entry looks like key:value
291- const [ key , value ] = entry . split ( ':' ) ;
292- if ( key === 'product' ) {
293- device . product = value ;
294- } else if ( key === 'model' ) {
295- device . model = value ;
296- } else if ( key === 'device' ) {
297- device . device = value ;
298- } else if ( key === 'usb' ) {
299- device . usb = value ;
300- } else if ( key === 'transport_id' ) {
301- device . transport_id = value ;
259+ const device : Device & Record < string , string > = { udid, state} as Device &
260+ Record < string , string > ;
261+ if ( opts . verbose ) {
262+ for ( const entry of description ) {
263+ if ( entry . includes ( ':' ) ) {
264+ // each entry looks like key:value
265+ const [ key , value ] = entry . split ( ':' ) ;
266+ device [ key ] = value ;
267+ }
302268 }
303269 }
304270 return device ;
@@ -467,42 +433,27 @@ export const EXEC_OUTPUT_FORMAT = {
467433 FULL : 'full' ,
468434} as const ;
469435
470- /**
471- * Execute the given adb command.
472- *
473- * @param cmd - Command string or array of command arguments
474- * @param opts - Execution options with `outputFormat: 'full'`
475- * @returns Command stdout and stderr
476- * @throws {Error } If command execution fails or timeout is exceeded
477- */
478- export async function adbExec (
479- this : ADB ,
480- cmd : string | string [ ] ,
481- opts : AdbExecOptions & { outputFormat : 'full' } ,
482- ) : Promise < ExecResult > ;
483436/**
484437 * Execute the given adb command.
485438 *
486439 * @param cmd - Command string or array of command arguments
487440 * @param opts - Execution options
488- * @returns Command stdout
441+ * @returns Command output (string or ExecResult depending on outputFormat)
489442 * @throws {Error } If command execution fails or timeout is exceeded
490443 */
491- export async function adbExec (
444+ export async function adbExec <
445+ TExecOpts extends ShellExecOptions & SpecialAdbExecOptions = ShellExecOptions &
446+ SpecialAdbExecOptions ,
447+ > (
492448 this : ADB ,
493449 cmd : string | string [ ] ,
494- opts ?: AdbExecOptions ,
495- ) : Promise < string > ;
496- export async function adbExec (
497- this : ADB ,
498- cmd : string | string [ ] ,
499- opts ?: AdbExecOptions ,
500- ) : Promise < string | ExecResult > {
450+ opts ?: TExecOpts ,
451+ ) : Promise < TExecOpts extends TFullOutputOption ? ExecResult : string > {
501452 if ( ! cmd ) {
502453 throw new Error ( 'You need to pass in a command to adbExec()' ) ;
503454 }
504455
505- const optsCopy = cloneDeep ( opts ?? { } ) as AdbExecOptions ;
456+ const optsCopy = cloneDeep ( opts ?? { } ) as TExecOpts ;
506457 // setting default timeout for each command to prevent infinite wait.
507458 optsCopy . timeout = optsCopy . timeout || this . adbExecTimeout || DEFAULT_ADB_EXEC_TIMEOUT ;
508459 optsCopy . timeoutCapName = optsCopy . timeoutCapName || 'adbExecTimeout' ; // For error message
@@ -572,46 +523,28 @@ export async function adbExec(
572523 isExecLocked = true ;
573524 }
574525 try {
575- return await execFunc ( ) ;
526+ return ( await execFunc ( ) ) as TExecOpts extends TFullOutputOption ? ExecResult : string ;
576527 } finally {
577528 if ( optsCopy . exclusive ) {
578529 isExecLocked = false ;
579530 }
580531 }
581532}
582533
583- /**
584- * Execute the given command using _adb shell_ prefix.
585- *
586- * @param cmd - Command string or array of command arguments
587- * @param opts - Execution options with `outputFormat: 'full'`
588- * @returns Command stdout and stderr
589- * @throws {Error } If command execution fails
590- */
591- export async function shell (
592- this : ADB ,
593- cmd : string | string [ ] ,
594- opts : ShellExecOptions & { outputFormat : 'full' } ,
595- ) : Promise < ExecResult > ;
596534/**
597535 * Execute the given command using _adb shell_ prefix.
598536 *
599537 * @param cmd - Command string or array of command arguments
600538 * @param opts - Execution options
601- * @returns Command stdout
539+ * @returns Command output (string or ExecResult depending on outputFormat)
602540 * @throws {Error } If command execution fails
603541 */
604- export async function shell (
605- this : ADB ,
606- cmd : string | string [ ] ,
607- opts ?: ShellExecOptions ,
608- ) : Promise < string > ;
609- export async function shell (
542+ export async function shell < TShellExecOpts extends ShellExecOptions = ShellExecOptions > (
610543 this : ADB ,
611544 cmd : string | string [ ] ,
612- opts ?: ShellExecOptions ,
613- ) : Promise < string | ExecResult > {
614- const { privileged} = opts ?? { } ;
545+ opts ?: TShellExecOpts ,
546+ ) : Promise < TShellExecOpts extends TFullOutputOption ? ExecResult : string > {
547+ const { privileged} = opts ?? ( { } as TShellExecOpts ) ;
615548
616549 const cmdArr = Array . isArray ( cmd ) ? cmd : [ cmd ] ;
617550 const fullCmd : string [ ] = [ 'shell' ] ;
@@ -642,6 +575,17 @@ export function createSubProcess(this: ADB, args: string[] = []): SubProcess {
642575 return new SubProcess ( this . getAdbPath ( ) , finalArgs ) ;
643576}
644577
578+ /**
579+ * Retrieve the current adb port.
580+ * @todo can probably deprecate this now that the logic is just to read this.adbPort
581+ * @deprecated Use this.adbPort instead
582+ *
583+ * @returns The ADB server port number
584+ */
585+ export function getAdbServerPort ( this : ADB ) : number {
586+ return this . adbPort as number ;
587+ }
588+
645589/**
646590 * Retrieve the current emulator port from _adb devices_ output.
647591 *
@@ -679,38 +623,21 @@ export function getPortFromEmulatorString(this: ADB, emStr: string): number | fa
679623 return match ? parseInt ( match [ 1 ] , 10 ) : false ;
680624}
681625
682- /**
683- * Retrieve the list of currently connected emulators.
684- *
685- * @param opts - Options with `verbose: true` for long `adb devices -l` output
686- * @returns Array of connected emulator devices with product/model metadata
687- * @throws {Error } If error occurs while getting emulators
688- */
689- export async function getConnectedEmulators (
690- this : ADB ,
691- opts : ConnectedDevicesOptions & { verbose : true } ,
692- ) : Promise < VerboseDevice [ ] > ;
693626/**
694627 * Retrieve the list of currently connected emulators.
695628 *
696629 * @param opts - Options for device retrieval
697630 * @returns Array of connected emulator devices
698631 * @throws {Error } If error occurs while getting emulators
699632 */
700- export async function getConnectedEmulators (
701- this : ADB ,
702- opts ?: ConnectedDevicesOptions ,
703- ) : Promise < Device [ ] > ;
704633export async function getConnectedEmulators (
705634 this : ADB ,
706635 opts : ConnectedDevicesOptions = { } ,
707- ) : Promise < Device [ ] | VerboseDevice [ ] > {
636+ ) : Promise < Device [ ] > {
708637 log . debug ( 'Getting connected emulators' ) ;
709638 try {
710- const devices = opts . verbose
711- ? await this . getConnectedDevices ( { verbose : true } )
712- : await this . getConnectedDevices ( opts ) ;
713- const emulators : Array < Device | VerboseDevice > = [ ] ;
639+ const devices = await this . getConnectedDevices ( opts ) ;
640+ const emulators : Device [ ] = [ ] ;
714641 for ( const device of devices ) {
715642 const port = this . getPortFromEmulatorString ( device . udid ) ;
716643 if ( port ) {
0 commit comments