xref: /aosp_15_r20/development/tools/winscope/src/trace_collection/adb_connection.ts (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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