@@ -34,7 +34,7 @@ import { removeFolders } from '../utils/fileUtils';
34
34
import { helper } from '../helper' ;
35
35
import { SdkObject , serverSideCallMetadata } from '../instrumentation' ;
36
36
import { gracefullyCloseSet } from '../utils/processLauncher' ;
37
- import { isAbortError , Progress , ProgressController } from '../progress' ;
37
+ import { isAbortError , Progress , ProgressController , raceUncancellableOperationWithCleanup } from '../progress' ;
38
38
import { registry } from '../registry' ;
39
39
40
40
import type { BrowserOptions , BrowserProcess } from '../browser' ;
@@ -79,8 +79,7 @@ export class Android extends SdkObject {
79
79
newSerials . add ( d . serial ) ;
80
80
if ( this . _devices . has ( d . serial ) )
81
81
continue ;
82
- const device = await progress . raceWithCleanup ( AndroidDevice . create ( this , d , options ) , device => device . close ( ) ) ;
83
- this . _devices . set ( d . serial , device ) ;
82
+ await progress . race ( AndroidDevice . create ( this , d , options ) . then ( device => this . _devices . set ( d . serial , device ) ) ) ;
84
83
}
85
84
for ( const d of this . _devices . keys ( ) ) {
86
85
if ( ! newSerials . has ( d ) )
@@ -152,7 +151,7 @@ export class AndroidDevice extends SdkObject {
152
151
}
153
152
154
153
async open ( progress : Progress , command : string ) : Promise < SocketBackend > {
155
- return await progress . raceWithCleanup ( this . _backend . open ( ` ${ command } ` ) , socket => socket . close ( ) ) ;
154
+ return await this . _open ( progress , command ) ;
156
155
}
157
156
158
157
async screenshot ( ) : Promise < Buffer > {
@@ -216,7 +215,7 @@ export class AndroidDevice extends SdkObject {
216
215
debug ( 'pw:android' ) ( `Polling the socket localabstract:${ socketName } ` ) ;
217
216
while ( ! socket ) {
218
217
try {
219
- socket = await progress . raceWithCleanup ( this . _backend . open ( `localabstract:${ socketName } ` ) , socket => socket . close ( ) ) ;
218
+ socket = await this . _open ( progress , `localabstract:${ socketName } ` ) ;
220
219
} catch ( e ) {
221
220
if ( isAbortError ( e ) )
222
221
throw e ;
@@ -273,8 +272,13 @@ export class AndroidDevice extends SdkObject {
273
272
await progress . race ( this . _backend . runCommand ( `shell:echo "${ Buffer . from ( commandLine ) . toString ( 'base64' ) } " | base64 -d > /data/local/tmp/chrome-command-line` ) ) ;
274
273
await progress . race ( this . _backend . runCommand ( `shell:am start -a android.intent.action.VIEW -d about:blank ${ pkg } ` ) ) ;
275
274
const browserContext = await this . _connectToBrowser ( progress , socketName , options ) ;
276
- await progress . race ( this . _backend . runCommand ( `shell:rm /data/local/tmp/chrome-command-line` ) ) ;
277
- return browserContext ;
275
+ try {
276
+ await progress . race ( this . _backend . runCommand ( `shell:rm /data/local/tmp/chrome-command-line` ) ) ;
277
+ return browserContext ;
278
+ } catch ( error ) {
279
+ await browserContext . close ( { reason : 'Failed to launch' } ) . catch ( ( ) => { } ) ;
280
+ throw error ;
281
+ }
278
282
}
279
283
280
284
private _defaultArgs ( options : channels . AndroidDeviceLaunchBrowserParams , socketName : string ) : string [ ] {
@@ -315,43 +319,50 @@ export class AndroidDevice extends SdkObject {
315
319
316
320
private async _connectToBrowser ( progress : Progress , socketName : string , options : types . BrowserContextOptions = { } ) : Promise < BrowserContext > {
317
321
const socket = await this . _waitForLocalAbstract ( progress , socketName ) ;
318
- const androidBrowser = new AndroidBrowser ( this , socket ) ;
319
- progress . cleanupWhenAborted ( ( ) => androidBrowser . close ( ) ) ;
320
- await progress . race ( androidBrowser . _init ( ) ) ;
321
- this . _browserConnections . add ( androidBrowser ) ;
322
-
323
- const artifactsDir = await progress . race ( fs . promises . mkdtemp ( ARTIFACTS_FOLDER ) ) ;
324
- const cleanupArtifactsDir = async ( ) => {
325
- const errors = ( await removeFolders ( [ artifactsDir ] ) ) . filter ( Boolean ) ;
326
- for ( let i = 0 ; i < ( errors || [ ] ) . length ; ++ i )
327
- debug ( 'pw:android' ) ( `exception while removing ${ artifactsDir } : ${ errors [ i ] } ` ) ;
328
- } ;
329
- progress . cleanupWhenAborted ( cleanupArtifactsDir ) ;
330
- gracefullyCloseSet . add ( cleanupArtifactsDir ) ;
331
- socket . on ( 'close' , async ( ) => {
332
- gracefullyCloseSet . delete ( cleanupArtifactsDir ) ;
333
- cleanupArtifactsDir ( ) . catch ( e => debug ( 'pw:android' ) ( `could not cleanup artifacts dir: ${ e } ` ) ) ;
334
- } ) ;
335
- const browserOptions : BrowserOptions = {
336
- name : 'clank' ,
337
- isChromium : true ,
338
- slowMo : 0 ,
339
- persistent : { ...options , noDefaultViewport : true } ,
340
- artifactsDir,
341
- downloadsPath : artifactsDir ,
342
- tracesDir : artifactsDir ,
343
- browserProcess : new ClankBrowserProcess ( androidBrowser ) ,
344
- proxy : options . proxy ,
345
- protocolLogger : helper . debugProtocolLogger ( ) ,
346
- browserLogsCollector : new RecentLogsCollector ( ) ,
347
- originalLaunchOptions : { } ,
348
- } ;
349
- validateBrowserContextOptions ( options , browserOptions ) ;
322
+ try {
323
+ const androidBrowser = new AndroidBrowser ( this , socket ) ;
324
+ await progress . race ( androidBrowser . _init ( ) ) ;
325
+ this . _browserConnections . add ( androidBrowser ) ;
326
+
327
+ const artifactsDir = await progress . race ( fs . promises . mkdtemp ( ARTIFACTS_FOLDER ) ) ;
328
+ const cleanupArtifactsDir = async ( ) => {
329
+ const errors = ( await removeFolders ( [ artifactsDir ] ) ) . filter ( Boolean ) ;
330
+ for ( let i = 0 ; i < ( errors || [ ] ) . length ; ++ i )
331
+ debug ( 'pw:android' ) ( `exception while removing ${ artifactsDir } : ${ errors [ i ] } ` ) ;
332
+ } ;
333
+ gracefullyCloseSet . add ( cleanupArtifactsDir ) ;
334
+ socket . on ( 'close' , async ( ) => {
335
+ gracefullyCloseSet . delete ( cleanupArtifactsDir ) ;
336
+ cleanupArtifactsDir ( ) . catch ( e => debug ( 'pw:android' ) ( `could not cleanup artifacts dir: ${ e } ` ) ) ;
337
+ } ) ;
338
+ const browserOptions : BrowserOptions = {
339
+ name : 'clank' ,
340
+ isChromium : true ,
341
+ slowMo : 0 ,
342
+ persistent : { ...options , noDefaultViewport : true } ,
343
+ artifactsDir,
344
+ downloadsPath : artifactsDir ,
345
+ tracesDir : artifactsDir ,
346
+ browserProcess : new ClankBrowserProcess ( androidBrowser ) ,
347
+ proxy : options . proxy ,
348
+ protocolLogger : helper . debugProtocolLogger ( ) ,
349
+ browserLogsCollector : new RecentLogsCollector ( ) ,
350
+ originalLaunchOptions : { } ,
351
+ } ;
352
+ validateBrowserContextOptions ( options , browserOptions ) ;
353
+
354
+ const browser = await progress . race ( CRBrowser . connect ( this . attribution . playwright , androidBrowser , browserOptions ) ) ;
355
+ const defaultContext = browser . _defaultContext ! ;
356
+ await defaultContext . _loadDefaultContextAsIs ( progress ) ;
357
+ return defaultContext ;
358
+ } catch ( error ) {
359
+ socket . close ( ) ;
360
+ throw error ;
361
+ }
362
+ }
350
363
351
- const browser = await progress . race ( CRBrowser . connect ( this . attribution . playwright , androidBrowser , browserOptions ) ) ;
352
- const defaultContext = browser . _defaultContext ! ;
353
- await defaultContext . _loadDefaultContextAsIs ( progress ) ;
354
- return defaultContext ;
364
+ private _open ( progress : Progress , command : string ) : Promise < SocketBackend > {
365
+ return raceUncancellableOperationWithCleanup ( progress , ( ) => this . _backend . open ( command ) , socket => socket . close ( ) ) ;
355
366
}
356
367
357
368
webViews ( ) : channels . AndroidWebView [ ] {
@@ -361,7 +372,7 @@ export class AndroidDevice extends SdkObject {
361
372
async installApk ( progress : Progress , content : Buffer , options ?: { args ?: string [ ] } ) : Promise < void > {
362
373
const args = options && options . args ? options . args : [ '-r' , '-t' , '-S' ] ;
363
374
debug ( 'pw:android' ) ( 'Opening install socket' ) ;
364
- const installSocket = await progress . raceWithCleanup ( this . _backend . open ( `shell:cmd package install ${ args . join ( ' ' ) } ${ content . length } ` ) , socket => socket . close ( ) ) ;
375
+ const installSocket = await this . _open ( progress , `shell:cmd package install ${ args . join ( ' ' ) } ${ content . length } ` ) ;
365
376
debug ( 'pw:android' ) ( 'Writing driver bytes: ' + content . length ) ;
366
377
await progress . race ( installSocket . write ( content ) ) ;
367
378
const success = await progress . race ( new Promise ( f => installSocket . on ( 'data' , f ) ) ) ;
@@ -370,7 +381,7 @@ export class AndroidDevice extends SdkObject {
370
381
}
371
382
372
383
async push ( progress : Progress , content : Buffer , path : string , mode = 0o644 ) : Promise < void > {
373
- const socket = await progress . raceWithCleanup ( this . _backend . open ( `sync:` ) , socket => socket . close ( ) ) ;
384
+ const socket = await this . _open ( progress , `sync:` ) ;
374
385
const sendHeader = async ( command : string , length : number ) => {
375
386
const buffer = Buffer . alloc ( command . length + 4 ) ;
376
387
buffer . write ( command , 0 ) ;
0 commit comments