| // Copyright (C) 2022 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import {TraceConfig} from '../protos'; |
| |
| // TargetFactory connects, disconnects and keeps track of targets. |
| // There is one factory for AndroidWebusb, AndroidWebsocket, Chrome etc. |
| // For instance, the AndroidWebusb factory returns a RecordingTargetV2 for each |
| // device. |
| export interface TargetFactory { |
| // Store the kind explicitly as a string as opposed to using class.kind in |
| // case we ever minify our code. |
| readonly kind: string; |
| |
| // Setter for OnTargetChange, which is executed when a target is |
| // added/removed or when its information is updated. |
| setOnTargetChange(onTargetChange: OnTargetChangeCallback): void; |
| |
| getName(): string; |
| |
| listTargets(): RecordingTargetV2[]; |
| // Returns recording problems that we encounter when not directly using the |
| // target. For instance we connect webusb devices when Perfetto is loaded. If |
| // there is an issue with connecting a webusb device, we do not want to crash |
| // all of Perfetto, as the user may not want to use the recording |
| // functionality at all. |
| listRecordingProblems(): string[]; |
| |
| connectNewTarget(): Promise<RecordingTargetV2>; |
| } |
| |
| export interface DataSource { |
| name: string; |
| |
| // Contains information that is opaque to the recording code. The caller can |
| // use the DataSource name to type cast the DataSource descriptor. |
| // For targets calling QueryServiceState, 'descriptor' will hold the |
| // datasource descriptor: |
| // https://source.corp.google.com/android/external/perfetto/protos/perfetto/ |
| // common/data_source_descriptor.proto;l=28-60 |
| // For Chrome, 'descriptor' will contain the answer received from |
| // 'GetCategories': |
| // https://source.corp.google.com/android/external/perfetto/ui/src/ |
| // chrome_extension/chrome_tracing_controller.ts;l=220 |
| descriptor: unknown; |
| } |
| |
| // Common fields for all types of targetInfo: Chrome, Android, Linux etc. |
| interface TargetInfoBase { |
| name: string; |
| |
| // The dataSources exposed by a target. They are fetched from the target |
| // (ex: using QSS for Android or GetCategories for Chrome). |
| dataSources: DataSource[]; |
| } |
| |
| export interface AndroidTargetInfo extends TargetInfoBase { |
| targetType: 'ANDROID'; |
| |
| // This is the Android API level. For instance, it can be 32, 31, 30 etc. |
| // It is the "API level" column here: |
| // https://source.android.com/setup/start/build-numbers |
| androidApiLevel?: number; |
| } |
| |
| export interface ChromeTargetInfo extends TargetInfoBase { |
| targetType: 'CHROME'|'CHROME_OS'; |
| } |
| |
| export interface HostOsTargetInfo extends TargetInfoBase { |
| targetType: 'LINUX'|'MACOS'; |
| } |
| |
| // Holds information about a target. It's used by the UI and the logic which |
| // generates a config. |
| export type TargetInfo = AndroidTargetInfo|ChromeTargetInfo|HostOsTargetInfo; |
| |
| // RecordingTargetV2 is subclassed by Android devices and the Chrome browser/OS. |
| // It creates tracing sessions which are used by the UI. For Android, it manages |
| // the connection with the device. |
| export interface RecordingTargetV2 { |
| // Allows targets to surface target specific information such as |
| // well known key/value pairs: OS, targetType('ANDROID', 'CHROME', etc.) |
| getInfo(): TargetInfo; |
| |
| // Disconnects the target. |
| disconnect(disconnectMessage?: string): Promise<void>; |
| |
| // Returns true if we are able to connect to the target without interfering |
| // with other processes. For example, for adb devices connected over WebUSB, |
| // this will be false when we can not claim the interface (Which most likely |
| // means that 'adb server' is running locally.). After querrying this method, |
| // the caller can decide if they want to connect to the target and as a side |
| // effect take the connection away from other processes. |
| canConnectWithoutContention(): Promise<boolean>; |
| |
| // Whether the recording target can be used in a tracing session. For example, |
| // virtual targets do not support a tracing session. |
| canCreateTracingSession(recordingMode?: string): boolean; |
| |
| // Some target information can only be obtained after connecting to the |
| // target. This will establish a connection and retrieve data such as |
| // dataSources and apiLevel for Android. |
| fetchTargetInfo(tracingSessionListener: TracingSessionListener): |
| Promise<void>; |
| |
| createTracingSession(tracingSessionListener: TracingSessionListener): |
| Promise<TracingSession>; |
| } |
| |
| // TracingSession is used by the UI to record a trace. Depending on user |
| // actions, the UI can start/stop/cancel a session. During the recording, it |
| // provides updates about buffer usage. It is subclassed by |
| // TracedTracingSession, which manages the communication with traced and has |
| // logic for encoding/decoding Perfetto client requests/replies. |
| export interface TracingSession { |
| // Starts the tracing session. |
| start(config: TraceConfig): void; |
| |
| // Will stop the tracing session and NOT return any trace. |
| cancel(): void; |
| |
| // Will stop the tracing session. The implementing class may also return |
| // the trace using a callback. |
| stop(): void; |
| |
| // Returns the percentage of the trace buffer that is currently being |
| // occupied. |
| getTraceBufferUsage(): Promise<number>; |
| } |
| |
| // Connection with an Adb device. Implementations will have logic specific to |
| // the connection protocol used(Ex: WebSocket, WebUsb). |
| export interface AdbConnection { |
| // Will push a binary to a given path. |
| push(binary: ArrayBuffer, path: string): Promise<void>; |
| |
| // Will issue a shell command to the device. |
| shell(cmd: string): Promise<ByteStream>; |
| |
| // Will establish a connection(a ByteStream) with the device. |
| connectSocket(path: string): Promise<ByteStream>; |
| |
| // Returns true if we are able to connect without interfering |
| // with other processes. For example, for adb devices connected over WebUSB, |
| // this will be false when we can not claim the interface (Which most likely |
| // means that 'adb server' is running locally.). |
| canConnectWithoutContention(): Promise<boolean>; |
| |
| // Ends the connection. |
| disconnect(disconnectMessage?: string): Promise<void>; |
| } |
| |
| // A stream for a connection between a target and a tracing session. |
| export interface ByteStream { |
| // The caller can add callbacks, to be executed when the stream receives new |
| // data or when it finished closing itself. |
| addOnStreamDataCallback(onStreamData: OnStreamDataCallback): void; |
| addOnStreamCloseCallback(onStreamClose: OnStreamCloseCallback): void; |
| |
| isConnected(): boolean; |
| write(data: string|Uint8Array): void; |
| |
| close(): void; |
| closeAndWaitForTeardown(): Promise<void>; |
| } |
| |
| // Handles binary messages received over the ByteStream. |
| export interface OnStreamDataCallback { |
| (data: Uint8Array): void; |
| } |
| |
| // Called when the ByteStream is closed. |
| export interface OnStreamCloseCallback { |
| (): void; |
| } |
| |
| // OnTraceDataCallback will return the entire trace when it has been fully |
| // assembled. This will be changed in the following CL aosp/2057640. |
| export interface OnTraceDataCallback { |
| (trace: Uint8Array): void; |
| } |
| |
| // Handles messages that are useful in the UI and that occur at any layer of the |
| // recording (trace, connection). The messages includes both status messages and |
| // error messages. |
| export interface OnMessageCallback { |
| (message: string): void; |
| } |
| |
| // Handles the loss of the connection at the connection layer (used by the |
| // AdbConnection). |
| export interface OnDisconnectCallback { |
| (errorMessage?: string): void; |
| } |
| |
| // Called when there is a change of targets or within a target. |
| // For instance, it's used when an Adb device becomes connected/disconnected. |
| // It's also executed by a target when the information it stores gets updated. |
| export interface OnTargetChangeCallback { |
| (): void; |
| } |
| |
| // A collection of callbacks that is passed to RecordingTargetV2 and |
| // subsequently to TracingSession. The callbacks are decided by the UI, so the |
| // recording code is not coupled with the rendering logic. |
| export interface TracingSessionListener { |
| onTraceData: OnTraceDataCallback; |
| onStatus: OnMessageCallback; |
| onDisconnect: OnDisconnectCallback; |
| onError: OnMessageCallback; |
| } |