• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2024 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 m from 'mithril';
16import {TargetPlatformId} from '../interfaces/target_platform';
17import {TraceConfigBuilder} from './trace_config_builder';
18import {RecordPluginSchema, RecordSessionSchema} from '../serialization_schema';
19
20/**
21 * A sub-page of the Record page.
22 * Each section maps to an entry in the left sidebar of the recording page.
23 * There are three types of subpages. The last two are identical with exception
24 * of the serialization scope.
25 * 1. Probes pages: the ones that are a structured collection of probes that
26 *    can be toggled.
27 * 2,3. Session and global pages: they care of their own rendering and
28 *    de/serialization.
29 * 2. Session pages serialize their state in the per-session object (e.g. buffer
30 *    sizes). This object can be shared with other people when using the share
31 *    config feature.
32 * 3. Global pages instead hold onto the "global" state of the plugin, which is
33 *    not tied to the specific config of the recording session (e.g. the target
34 *    being recorded, the list of saved configs). This state is retained in
35 *    localstorage but is NOT shared with others.
36 */
37export type RecordSubpage = {
38  /** A unique string. This becomes the subpage in the fragment #!/record/xxx */
39  readonly id: string;
40
41  /** The name of the material-design icon that is displayed on the sidebar. */
42  readonly icon: string;
43
44  /** The main text displayed in the left sidebar. */
45  readonly title: string;
46
47  /** The subtitle displayed when hovering over the entry of the sidebar. */
48  readonly subtitle: string;
49} & (
50  | {
51      kind: 'PROBES_PAGE';
52
53      /** The list of probes (togglable entries) for this section. */
54      readonly probes: ReadonlyArray<RecordProbe>;
55    }
56  | {
57      kind: 'SESSION_PAGE';
58      render(): m.Children;
59
60      // Save-restore the page state into the JSON object that is saved in
61      // localstorage and shared when sharing a config.
62      serialize(state: RecordSessionSchema): void;
63      deserialize(state: RecordSessionSchema): void;
64    }
65  | {
66      kind: 'GLOBAL_PAGE';
67      render(): m.Children;
68
69      // Save-restore the page state into the JSON object that is saved in
70      // localstorage.
71      serialize(state: RecordPluginSchema): void;
72      deserialize(state: RecordPluginSchema): void;
73    }
74);
75
76export interface RecordProbe {
77  /**
78   * lower_with_under id. Keep stable, is used for serialization.
79   * This id must be globally unique (not just per-section).
80   */
81  readonly id: string;
82
83  /** Human readable name. */
84  readonly title: string;
85
86  /** (optional) decription. */
87  readonly description?: string;
88
89  /** (optional) file name of a .png file under assets/. */
90  readonly image?: string;
91
92  /** (optional) Link to documentation (e.g. 'https://docs.perfetto.dev/...') */
93  readonly docsLink?: string;
94
95  /** (optional). If specified restricts the probe to the given platorms. */
96  readonly supportedPlatforms?: TargetPlatformId[];
97
98  /** (optional): a list of settings for the probe (e.g. polling interval). */
99  readonly settings?: Record<string, ProbeSetting>;
100
101  /**
102   * (optional): a list of probe IDs that will be force-enabled if this probe is
103   * also enabled.
104   */
105  readonly dependencies?: string[];
106
107  /**
108   * Generate the TraceConfig for the probe. This happens in vdom-style: every
109   * time we make a change to the probes the RecordingManager starts a blank
110   * TraceConfigBuilder and asks all probes to update its config invoking this
111   * method.
112   */
113  genConfig(tc: TraceConfigBuilder): void;
114}
115
116/**
117 * The interface to create widgets that change the state of a probe.
118 * The widget is maintains its own state and must be able to de/serialize it.
119 * Realistically you don't want to implment this interface yourself but use one
120 * of the pre-made widgets under ../pages/widgets/, e.g., Slider().
121 */
122export interface ProbeSetting {
123  readonly render: () => m.Children;
124
125  // The two methods below are supposed to save/restore the state of the setting
126  // in a JSON-serializable entity (object | number | string | boolean). This is
127  // to support saving configs into localstorage and sharing them.
128  serialize(): unknown;
129  deserialize(state: unknown): void;
130}
131
132export function supportsPlatform(
133  probe: RecordProbe,
134  platform: TargetPlatformId,
135): boolean {
136  return (
137    probe.supportedPlatforms === undefined ||
138    probe.supportedPlatforms.includes(platform)
139  );
140}
141