• 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 '../../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(
74  descriptor: unknown,
75): descriptor is DataSourceDescriptor {
76  if (descriptor instanceof Object) {
77    return (descriptor as DataSourceDescriptor).name !== undefined;
78  }
79  return false;
80}
81
82class AtraceAppsList implements m.ClassComponent {
83  view() {
84    if (globals.state.recordConfig.allAtraceApps) {
85      return m('div');
86    }
87
88    return m(Textarea, {
89      placeholder:
90        'Apps to profile, one per line, e.g.:\n' +
91        'com.android.phone\n' +
92        'lmkd\n' +
93        'com.android.nfc',
94      cssClass: '.record-apps-list',
95      set: (cfg, val) => (cfg.atraceApps = val),
96      get: (cfg) => cfg.atraceApps,
97    } as TextareaAttrs);
98  }
99}
100
101export class AndroidSettings
102  implements m.ClassComponent<RecordingSectionAttrs>
103{
104  view({attrs}: m.CVnode<RecordingSectionAttrs>) {
105    let atraceCategories = DEFAULT_ATRACE_CATEGORIES;
106    for (const dataSource of attrs.dataSources) {
107      if (
108        dataSource.name !== 'linux.ftrace' ||
109        !isDataSourceDescriptor(dataSource.descriptor)
110      ) {
111        continue;
112      }
113      const atraces = dataSource.descriptor.ftraceDescriptor?.atraceCategories;
114      if (!atraces || atraces.length === 0) {
115        break;
116      }
117
118      atraceCategories = new Map<string, string>();
119      for (const atrace of atraces) {
120        if (atrace.name) {
121          atraceCategories.set(atrace.name, atrace.description || '');
122        }
123      }
124    }
125
126    return m(
127      `.record-section${attrs.cssClass}`,
128      m(
129        Probe,
130        {
131          title: 'Atrace userspace annotations',
132          img: 'rec_atrace.png',
133          descr: `Enables C++ / Java codebase annotations (ATRACE_BEGIN() /
134                      os.Trace())`,
135          setEnabled: (cfg, val) => (cfg.atrace = val),
136          isEnabled: (cfg) => cfg.atrace,
137        } as ProbeAttrs,
138        m(Dropdown, {
139          title: 'Categories',
140          cssClass: '.multicolumn.atrace-categories',
141          options: atraceCategories,
142          set: (cfg, val) => (cfg.atraceCats = val),
143          get: (cfg) => cfg.atraceCats,
144        } as DropdownAttrs),
145        m(Toggle, {
146          title: 'Record events from all Android apps and services',
147          descr: '',
148          setEnabled: (cfg, val) => (cfg.allAtraceApps = val),
149          isEnabled: (cfg) => cfg.allAtraceApps,
150        } as ToggleAttrs),
151        m(AtraceAppsList),
152      ),
153      m(
154        Probe,
155        {
156          title: 'Event log (logcat)',
157          img: 'rec_logcat.png',
158          descr: `Streams the event log into the trace. If no buffer filter is
159                      specified, all buffers are selected.`,
160          setEnabled: (cfg, val) => (cfg.androidLogs = val),
161          isEnabled: (cfg) => cfg.androidLogs,
162        } as ProbeAttrs,
163        m(Dropdown, {
164          title: 'Buffers',
165          cssClass: '.multicolumn',
166          options: LOG_BUFFERS,
167          set: (cfg, val) => (cfg.androidLogBuffers = val),
168          get: (cfg) => cfg.androidLogBuffers,
169        } as DropdownAttrs),
170      ),
171      m(Probe, {
172        title: 'Frame timeline',
173        img: 'rec_frame_timeline.png',
174        descr: `Records expected/actual frame timings from surface_flinger.
175                      Requires Android 12 (S) or above.`,
176        setEnabled: (cfg, val) => (cfg.androidFrameTimeline = val),
177        isEnabled: (cfg) => cfg.androidFrameTimeline,
178      } as ProbeAttrs),
179      m(Probe, {
180        title: 'Game intervention list',
181        img: '',
182        descr: `List game modes and interventions.
183                    Requires Android 13 (T) or above.`,
184        setEnabled: (cfg, val) => (cfg.androidGameInterventionList = val),
185        isEnabled: (cfg) => cfg.androidGameInterventionList,
186      } as ProbeAttrs),
187      m(
188        Probe,
189        {
190          title: 'Network Tracing',
191          img: '',
192          descr: `Records detailed information on network packets.
193                      Requires Android 14 (U) or above.`,
194          setEnabled: (cfg, val) => (cfg.androidNetworkTracing = val),
195          isEnabled: (cfg) => cfg.androidNetworkTracing,
196        } as ProbeAttrs,
197        m(Slider, {
198          title: 'Poll interval',
199          cssClass: '.thin',
200          values: [100, 250, 500, 1000, 2500],
201          unit: 'ms',
202          set: (cfg, val) => (cfg.androidNetworkTracingPollMs = val),
203          get: (cfg) => cfg.androidNetworkTracingPollMs,
204        } as SliderAttrs),
205      ),
206    );
207  }
208}
209