1/* 2 * Copyright 2022, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17import {assertUnreachable} from 'common/assert_utils'; 18import {HttpRequestStatus, HttpResponse} from 'common/http_request'; 19import {AdbDevice} from './adb_device'; 20import {ConnectionState} from './connection_state'; 21import {TraceRequest} from './trace_request'; 22 23export abstract class AdbConnection { 24 abstract initialize( 25 detectStateChangeInUi: () => Promise<void>, 26 availableTracesChangeCallback: (traces: string[]) => void, 27 devicesChangeCallback: (devices: AdbDevice[]) => void, 28 ): Promise<void>; 29 abstract restartConnection(): Promise<void>; 30 abstract setSecurityToken(token: string): void; 31 abstract getDevices(): AdbDevice[]; 32 abstract getState(): ConnectionState; 33 abstract getErrorText(): string; 34 abstract startTrace( 35 device: AdbDevice, 36 requestedTraces: TraceRequest[], 37 ): Promise<void>; 38 abstract endTrace(device: AdbDevice): Promise<void>; 39 abstract dumpState( 40 device: AdbDevice, 41 requestedDumps: TraceRequest[], 42 ): Promise<void>; 43 abstract fetchLastTracingSessionData(device: AdbDevice): Promise<File[]>; 44 abstract onDestroy(): void; 45 46 protected async processHttpResponse( 47 resp: HttpResponse, 48 onSuccess: OnRequestSuccessCallback, 49 ): Promise<AdbResponse | undefined> { 50 let newState: ConnectionState | undefined; 51 let errorMsg: string | undefined; 52 53 switch (resp.status) { 54 case HttpRequestStatus.UNSENT: 55 newState = ConnectionState.NOT_FOUND; 56 break; 57 58 case HttpRequestStatus.UNAUTH: 59 newState = ConnectionState.UNAUTH; 60 break; 61 62 case HttpRequestStatus.SUCCESS: 63 try { 64 await onSuccess(resp); 65 } catch (err) { 66 newState = ConnectionState.ERROR; 67 errorMsg = 68 `Error handling request response:\n${err}\n\n` + 69 `Request:\n ${resp.text}`; 70 } 71 break; 72 73 case HttpRequestStatus.ERROR: 74 if (resp.type === 'text' || !resp.type) { 75 errorMsg = resp.text; 76 } else if (resp.type === 'arraybuffer') { 77 errorMsg = String.fromCharCode.apply(null, new Array(resp.body)); 78 if (errorMsg === '\x00') { 79 errorMsg = 'No data received.'; 80 } 81 } 82 newState = ConnectionState.ERROR; 83 break; 84 85 default: 86 assertUnreachable(resp.status); 87 } 88 89 return newState !== undefined ? {newState, errorMsg} : undefined; 90 } 91} 92 93interface AdbResponse { 94 newState: ConnectionState; 95 errorMsg: string | undefined; 96} 97 98export type OnRequestSuccessCallback = ( 99 resp: HttpResponse, 100) => void | Promise<void>; 101