• 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 m from 'mithril';
16
17import {DataSourceDescriptor} from '../../common/protos';
18import {globals} from '../globals';
19import {
20  Dropdown,
21  DropdownAttrs,
22  Probe,
23  ProbeAttrs,
24  Slider,
25  SliderAttrs,
26  Textarea,
27  TextareaAttrs,
28  Toggle,
29  ToggleAttrs,
30} from '../record_widgets';
31
32import {RecordingSectionAttrs} from './recording_sections';
33
34const LOG_BUFFERS = new Map<string, string>();
35LOG_BUFFERS.set('LID_CRASH', 'Crash');
36LOG_BUFFERS.set('LID_DEFAULT', 'Main');
37LOG_BUFFERS.set('LID_EVENTS', 'Binary events');
38LOG_BUFFERS.set('LID_KERNEL', 'Kernel');
39LOG_BUFFERS.set('LID_RADIO', 'Radio');
40LOG_BUFFERS.set('LID_SECURITY', 'Security');
41LOG_BUFFERS.set('LID_STATS', 'Stats');
42LOG_BUFFERS.set('LID_SYSTEM', 'System');
43
44const DEFAULT_ATRACE_CATEGORIES = new Map<string, string>();
45DEFAULT_ATRACE_CATEGORIES.set('adb', 'ADB');
46DEFAULT_ATRACE_CATEGORIES.set('aidl', 'AIDL calls');
47DEFAULT_ATRACE_CATEGORIES.set('am', 'Activity Manager');
48DEFAULT_ATRACE_CATEGORIES.set('audio', 'Audio');
49DEFAULT_ATRACE_CATEGORIES.set('binder_driver', 'Binder Kernel driver');
50DEFAULT_ATRACE_CATEGORIES.set('binder_lock', 'Binder global lock trace');
51DEFAULT_ATRACE_CATEGORIES.set('bionic', 'Bionic C library');
52DEFAULT_ATRACE_CATEGORIES.set('camera', 'Camera');
53DEFAULT_ATRACE_CATEGORIES.set('dalvik', 'ART & Dalvik');
54DEFAULT_ATRACE_CATEGORIES.set('database', 'Database');
55DEFAULT_ATRACE_CATEGORIES.set('gfx', 'Graphics');
56DEFAULT_ATRACE_CATEGORIES.set('hal', 'Hardware Modules');
57DEFAULT_ATRACE_CATEGORIES.set('input', 'Input');
58DEFAULT_ATRACE_CATEGORIES.set('network', 'Network');
59DEFAULT_ATRACE_CATEGORIES.set('nnapi', 'Neural Network API');
60DEFAULT_ATRACE_CATEGORIES.set('pm', 'Package Manager');
61DEFAULT_ATRACE_CATEGORIES.set('power', 'Power Management');
62DEFAULT_ATRACE_CATEGORIES.set('res', 'Resource Loading');
63DEFAULT_ATRACE_CATEGORIES.set('rro', 'Resource Overlay');
64DEFAULT_ATRACE_CATEGORIES.set('rs', 'RenderScript');
65DEFAULT_ATRACE_CATEGORIES.set('sm', 'Sync Manager');
66DEFAULT_ATRACE_CATEGORIES.set('ss', 'System Server');
67DEFAULT_ATRACE_CATEGORIES.set('vibrator', 'Vibrator');
68DEFAULT_ATRACE_CATEGORIES.set('video', 'Video');
69DEFAULT_ATRACE_CATEGORIES.set('view', 'View System');
70DEFAULT_ATRACE_CATEGORIES.set('webview', 'WebView');
71DEFAULT_ATRACE_CATEGORIES.set('wm', 'Window Manager');
72
73function isDataSourceDescriptor(descriptor: unknown):
74    descriptor is DataSourceDescriptor {
75  if (descriptor instanceof Object) {
76    return (descriptor as DataSourceDescriptor).name !== undefined;
77  }
78  return false;
79}
80
81class AtraceAppsList implements m.ClassComponent {
82  view() {
83    if (globals.state.recordConfig.allAtraceApps) {
84      return m('div');
85    }
86
87    return m(Textarea, {
88      placeholder: 'Apps to profile, one per line, e.g.:\n' +
89          'com.android.phone\n' +
90          'lmkd\n' +
91          'com.android.nfc',
92      cssClass: '.atrace-apps-list',
93      set: (cfg, val) => cfg.atraceApps = val,
94      get: (cfg) => cfg.atraceApps,
95    } as TextareaAttrs);
96  }
97}
98
99export class AndroidSettings implements
100    m.ClassComponent<RecordingSectionAttrs> {
101  view({attrs}: m.CVnode<RecordingSectionAttrs>) {
102    let atraceCategories = DEFAULT_ATRACE_CATEGORIES;
103    for (const dataSource of attrs.dataSources) {
104      if (dataSource.name !== 'linux.ftrace' ||
105          !isDataSourceDescriptor(dataSource.descriptor)) {
106        continue;
107      }
108      const atraces = dataSource.descriptor.ftraceDescriptor?.atraceCategories;
109      if (!atraces || atraces.length === 0) {
110        break;
111      }
112
113      atraceCategories = new Map<string, string>();
114      for (const atrace of atraces) {
115        if (atrace.name) {
116          atraceCategories.set(atrace.name, atrace.description || '');
117        }
118      }
119    }
120
121    return m(
122        `.record-section${attrs.cssClass}`,
123        m(Probe,
124          {
125            title: 'Atrace userspace annotations',
126            img: 'rec_atrace.png',
127            descr: `Enables C++ / Java codebase annotations (ATRACE_BEGIN() /
128                      os.Trace())`,
129            setEnabled: (cfg, val) => cfg.atrace = val,
130            isEnabled: (cfg) => cfg.atrace,
131          } as ProbeAttrs,
132          m(Dropdown, {
133            title: 'Categories',
134            cssClass: '.multicolumn.atrace-categories',
135            options: atraceCategories,
136            set: (cfg, val) => cfg.atraceCats = val,
137            get: (cfg) => cfg.atraceCats,
138          } as DropdownAttrs),
139          m(Toggle, {
140            title: 'Record events from all Android apps and services',
141            descr: '',
142            setEnabled: (cfg, val) => cfg.allAtraceApps = val,
143            isEnabled: (cfg) => cfg.allAtraceApps,
144          } as ToggleAttrs),
145          m(AtraceAppsList)),
146        m(Probe,
147          {
148            title: 'Event log (logcat)',
149            img: 'rec_logcat.png',
150            descr: `Streams the event log into the trace. If no buffer filter is
151                      specified, all buffers are selected.`,
152            setEnabled: (cfg, val) => cfg.androidLogs = val,
153            isEnabled: (cfg) => cfg.androidLogs,
154          } as ProbeAttrs,
155          m(Dropdown, {
156            title: 'Buffers',
157            cssClass: '.multicolumn',
158            options: LOG_BUFFERS,
159            set: (cfg, val) => cfg.androidLogBuffers = val,
160            get: (cfg) => cfg.androidLogBuffers,
161          } as DropdownAttrs)),
162        m(Probe, {
163          title: 'Frame timeline',
164          img: 'rec_frame_timeline.png',
165          descr: `Records expected/actual frame timings from surface_flinger.
166                      Requires Android 12 (S) or above.`,
167          setEnabled: (cfg, val) => cfg.androidFrameTimeline = val,
168          isEnabled: (cfg) => cfg.androidFrameTimeline,
169        } as ProbeAttrs),
170        m(Probe, {
171          title: 'Game intervention list',
172          img: '',
173          descr: `List game modes and interventions.
174                    Requires Android 13 (T) or above.`,
175          setEnabled: (cfg, val) => cfg.androidGameInterventionList = val,
176          isEnabled: (cfg) => cfg.androidGameInterventionList,
177        } as ProbeAttrs),
178        m(Probe,
179          {
180            title: 'Network Tracing',
181            img: '',
182            descr: `Records detailed information on network packets.
183                      Requires Android 14 (U) or above.`,
184            setEnabled: (cfg, val) => cfg.androidNetworkTracing = val,
185            isEnabled: (cfg) => cfg.androidNetworkTracing,
186          } as ProbeAttrs,
187          m(Slider, {
188            title: 'Poll interval',
189            cssClass: '.thin',
190            values: [100, 250, 500, 1000, 2500],
191            unit: 'ms',
192            set: (cfg, val) => cfg.androidNetworkTracingPollMs = val,
193            get: (cfg) => cfg.androidNetworkTracingPollMs,
194          } as SliderAttrs)));
195  }
196}
197