• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2022 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {TraceConfig} from '../protos';
16
17// TargetFactory connects, disconnects and keeps track of targets.
18// There is one factory for AndroidWebusb, AndroidWebsocket, Chrome etc.
19// For instance, the AndroidWebusb factory returns a RecordingTargetV2 for each
20// device.
21export interface TargetFactory {
22  // Store the kind explicitly as a string as opposed to using class.kind in
23  // case we ever minify our code.
24  readonly kind: string;
25
26  // Setter for OnTargetChange, which is executed when a target is
27  // added/removed or when its information is updated.
28  setOnTargetChange(onTargetChange: OnTargetChangeCallback): void;
29
30  getName(): string;
31
32  listTargets(): RecordingTargetV2[];
33  // Returns recording problems that we encounter when not directly using the
34  // target. For instance we connect webusb devices when Perfetto is loaded. If
35  // there is an issue with connecting a webusb device, we do not want to crash
36  // all of Perfetto, as the user may not want to use the recording
37  // functionality at all.
38  listRecordingProblems(): string[];
39
40  connectNewTarget(): Promise<RecordingTargetV2>;
41}
42
43export interface DataSource {
44  name: string;
45
46  // Contains information that is opaque to the recording code. The caller can
47  // use the DataSource name to type cast the DataSource descriptor.
48  // For targets calling QueryServiceState, 'descriptor' will hold the
49  // datasource descriptor:
50  // https://source.corp.google.com/android/external/perfetto/protos/perfetto/
51  // common/data_source_descriptor.proto;l=28-60
52  // For Chrome, 'descriptor' will contain the answer received from
53  // 'GetCategories':
54  // https://source.corp.google.com/android/external/perfetto/ui/src/
55  // chrome_extension/chrome_tracing_controller.ts;l=220
56  descriptor: unknown;
57}
58
59// Common fields for all types of targetInfo: Chrome, Android, Linux etc.
60interface TargetInfoBase {
61  name: string;
62
63  // The dataSources exposed by a target. They are fetched from the target
64  // (ex: using QSS for Android or GetCategories for Chrome).
65  dataSources: DataSource[];
66}
67
68export interface AndroidTargetInfo extends TargetInfoBase {
69  targetType: 'ANDROID';
70
71  // This is the Android API level. For instance, it can be 32, 31, 30 etc.
72  // It is the "API level" column here:
73  // https://source.android.com/setup/start/build-numbers
74  androidApiLevel?: number;
75}
76
77export interface ChromeTargetInfo extends TargetInfoBase {
78  targetType: 'CHROME'|'CHROME_OS';
79}
80
81export interface HostOsTargetInfo extends TargetInfoBase {
82  targetType: 'LINUX'|'MACOS';
83}
84
85// Holds information about a target. It's used by the UI and the logic which
86// generates a config.
87export type TargetInfo = AndroidTargetInfo|ChromeTargetInfo|HostOsTargetInfo;
88
89// RecordingTargetV2 is subclassed by Android devices and the Chrome browser/OS.
90// It creates tracing sessions which are used by the UI. For Android, it manages
91// the connection with the device.
92export interface RecordingTargetV2 {
93  // Allows targets to surface target specific information such as
94  // well known key/value pairs: OS, targetType('ANDROID', 'CHROME', etc.)
95  getInfo(): TargetInfo;
96
97  // Disconnects the target.
98  disconnect(disconnectMessage?: string): Promise<void>;
99
100  // Returns true if we are able to connect to the target without interfering
101  // with other processes. For example, for adb devices connected over WebUSB,
102  // this will be false when we can not claim the interface (Which most likely
103  // means that 'adb server' is running locally.). After querrying this method,
104  // the caller can decide if they want to connect to the target and as a side
105  // effect take the connection away from other processes.
106  canConnectWithoutContention(): Promise<boolean>;
107
108  // Whether the recording target can be used in a tracing session. For example,
109  // virtual targets do not support a tracing session.
110  canCreateTracingSession(recordingMode?: string): boolean;
111
112  // Some target information can only be obtained after connecting to the
113  // target. This will establish a connection and retrieve data such as
114  // dataSources and apiLevel for Android.
115  fetchTargetInfo(tracingSessionListener: TracingSessionListener):
116      Promise<void>;
117
118  createTracingSession(tracingSessionListener: TracingSessionListener):
119      Promise<TracingSession>;
120}
121
122// TracingSession is used by the UI to record a trace. Depending on user
123// actions, the UI can start/stop/cancel a session. During the recording, it
124// provides updates about buffer usage. It is subclassed by
125// TracedTracingSession, which manages the communication with traced and has
126// logic for encoding/decoding Perfetto client requests/replies.
127export interface TracingSession {
128  // Starts the tracing session.
129  start(config: TraceConfig): void;
130
131  // Will stop the tracing session and NOT return any trace.
132  cancel(): void;
133
134  // Will stop the tracing session. The implementing class may also return
135  // the trace using a callback.
136  stop(): void;
137
138  // Returns the percentage of the trace buffer that is currently being
139  // occupied.
140  getTraceBufferUsage(): Promise<number>;
141}
142
143// Connection with an Adb device. Implementations will have logic specific to
144// the connection protocol used(Ex: WebSocket, WebUsb).
145export interface AdbConnection {
146  // Will push a binary to a given path.
147  push(binary: ArrayBuffer, path: string): Promise<void>;
148
149  // Will issue a shell command to the device.
150  shell(cmd: string): Promise<ByteStream>;
151
152  // Will establish a connection(a ByteStream) with the device.
153  connectSocket(path: string): Promise<ByteStream>;
154
155  // Returns true if we are able to connect without interfering
156  // with other processes. For example, for adb devices connected over WebUSB,
157  // this will be false when we can not claim the interface (Which most likely
158  // means that 'adb server' is running locally.).
159  canConnectWithoutContention(): Promise<boolean>;
160
161  // Ends the connection.
162  disconnect(disconnectMessage?: string): Promise<void>;
163}
164
165// A stream for a connection between a target and a tracing session.
166export interface ByteStream {
167  // The caller can add callbacks, to be executed when the stream receives new
168  // data or when it finished closing itself.
169  addOnStreamDataCallback(onStreamData: OnStreamDataCallback): void;
170  addOnStreamCloseCallback(onStreamClose: OnStreamCloseCallback): void;
171
172  isConnected(): boolean;
173  write(data: string|Uint8Array): void;
174
175  close(): void;
176  closeAndWaitForTeardown(): Promise<void>;
177}
178
179// Handles binary messages received over the ByteStream.
180export interface OnStreamDataCallback {
181  (data: Uint8Array): void;
182}
183
184// Called when the ByteStream is closed.
185export interface OnStreamCloseCallback {
186  (): void;
187}
188
189// OnTraceDataCallback will return the entire trace when it has been fully
190// assembled. This will be changed in the following CL aosp/2057640.
191export interface OnTraceDataCallback {
192  (trace: Uint8Array): void;
193}
194
195// Handles messages that are useful in the UI and that occur at any layer of the
196// recording (trace, connection). The messages includes both status messages and
197// error messages.
198export interface OnMessageCallback {
199  (message: string): void;
200}
201
202// Handles the loss of the connection at the connection layer (used by the
203// AdbConnection).
204export interface OnDisconnectCallback {
205  (errorMessage?: string): void;
206}
207
208// Called when there is a change of targets or within a target.
209// For instance, it's used when an Adb device becomes connected/disconnected.
210// It's also executed by a target when the information it stores gets updated.
211export interface OnTargetChangeCallback {
212  (): void;
213}
214
215// A collection of callbacks that is passed to RecordingTargetV2 and
216// subsequently to TracingSession. The callbacks are decided by the UI, so the
217// recording code is not coupled with the rendering logic.
218export interface TracingSessionListener {
219  onTraceData: OnTraceDataCallback;
220  onStatus: OnMessageCallback;
221  onDisconnect: OnDisconnectCallback;
222  onError: OnMessageCallback;
223}
224