blob: 821408e87d3037c0c56d62deaea2f64e3876943c [file] [log] [blame]
// 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 m from 'mithril';
import {DataSourceDescriptor} from '../../common/protos';
import {globals} from '../globals';
import {
Dropdown,
DropdownAttrs,
Probe,
ProbeAttrs,
Slider,
SliderAttrs,
Textarea,
TextareaAttrs,
Toggle,
ToggleAttrs,
} from '../record_widgets';
import {RecordingSectionAttrs} from './recording_sections';
const LOG_BUFFERS = new Map<string, string>();
LOG_BUFFERS.set('LID_CRASH', 'Crash');
LOG_BUFFERS.set('LID_DEFAULT', 'Main');
LOG_BUFFERS.set('LID_EVENTS', 'Binary events');
LOG_BUFFERS.set('LID_KERNEL', 'Kernel');
LOG_BUFFERS.set('LID_RADIO', 'Radio');
LOG_BUFFERS.set('LID_SECURITY', 'Security');
LOG_BUFFERS.set('LID_STATS', 'Stats');
LOG_BUFFERS.set('LID_SYSTEM', 'System');
const DEFAULT_ATRACE_CATEGORIES = new Map<string, string>();
DEFAULT_ATRACE_CATEGORIES.set('adb', 'ADB');
DEFAULT_ATRACE_CATEGORIES.set('aidl', 'AIDL calls');
DEFAULT_ATRACE_CATEGORIES.set('am', 'Activity Manager');
DEFAULT_ATRACE_CATEGORIES.set('audio', 'Audio');
DEFAULT_ATRACE_CATEGORIES.set('binder_driver', 'Binder Kernel driver');
DEFAULT_ATRACE_CATEGORIES.set('binder_lock', 'Binder global lock trace');
DEFAULT_ATRACE_CATEGORIES.set('bionic', 'Bionic C library');
DEFAULT_ATRACE_CATEGORIES.set('camera', 'Camera');
DEFAULT_ATRACE_CATEGORIES.set('dalvik', 'ART & Dalvik');
DEFAULT_ATRACE_CATEGORIES.set('database', 'Database');
DEFAULT_ATRACE_CATEGORIES.set('gfx', 'Graphics');
DEFAULT_ATRACE_CATEGORIES.set('hal', 'Hardware Modules');
DEFAULT_ATRACE_CATEGORIES.set('input', 'Input');
DEFAULT_ATRACE_CATEGORIES.set('network', 'Network');
DEFAULT_ATRACE_CATEGORIES.set('nnapi', 'Neural Network API');
DEFAULT_ATRACE_CATEGORIES.set('pm', 'Package Manager');
DEFAULT_ATRACE_CATEGORIES.set('power', 'Power Management');
DEFAULT_ATRACE_CATEGORIES.set('res', 'Resource Loading');
DEFAULT_ATRACE_CATEGORIES.set('rro', 'Resource Overlay');
DEFAULT_ATRACE_CATEGORIES.set('rs', 'RenderScript');
DEFAULT_ATRACE_CATEGORIES.set('sm', 'Sync Manager');
DEFAULT_ATRACE_CATEGORIES.set('ss', 'System Server');
DEFAULT_ATRACE_CATEGORIES.set('vibrator', 'Vibrator');
DEFAULT_ATRACE_CATEGORIES.set('video', 'Video');
DEFAULT_ATRACE_CATEGORIES.set('view', 'View System');
DEFAULT_ATRACE_CATEGORIES.set('webview', 'WebView');
DEFAULT_ATRACE_CATEGORIES.set('wm', 'Window Manager');
function isDataSourceDescriptor(descriptor: unknown):
descriptor is DataSourceDescriptor {
if (descriptor instanceof Object) {
return (descriptor as DataSourceDescriptor).name !== undefined;
}
return false;
}
class AtraceAppsList implements m.ClassComponent {
view() {
if (globals.state.recordConfig.allAtraceApps) {
return m('div');
}
return m(Textarea, {
placeholder: 'Apps to profile, one per line, e.g.:\n' +
'com.android.phone\n' +
'lmkd\n' +
'com.android.nfc',
cssClass: '.atrace-apps-list',
set: (cfg, val) => cfg.atraceApps = val,
get: (cfg) => cfg.atraceApps,
} as TextareaAttrs);
}
}
export class AndroidSettings implements
m.ClassComponent<RecordingSectionAttrs> {
view({attrs}: m.CVnode<RecordingSectionAttrs>) {
let atraceCategories = DEFAULT_ATRACE_CATEGORIES;
for (const dataSource of attrs.dataSources) {
if (dataSource.name !== 'linux.ftrace' ||
!isDataSourceDescriptor(dataSource.descriptor)) {
continue;
}
const atraces = dataSource.descriptor.ftraceDescriptor?.atraceCategories;
if (!atraces || atraces.length === 0) {
break;
}
atraceCategories = new Map<string, string>();
for (const atrace of atraces) {
if (atrace.name) {
atraceCategories.set(atrace.name, atrace.description || '');
}
}
}
return m(
`.record-section${attrs.cssClass}`,
m(Probe,
{
title: 'Atrace userspace annotations',
img: 'rec_atrace.png',
descr: `Enables C++ / Java codebase annotations (ATRACE_BEGIN() /
os.Trace())`,
setEnabled: (cfg, val) => cfg.atrace = val,
isEnabled: (cfg) => cfg.atrace,
} as ProbeAttrs,
m(Dropdown, {
title: 'Categories',
cssClass: '.multicolumn.atrace-categories',
options: atraceCategories,
set: (cfg, val) => cfg.atraceCats = val,
get: (cfg) => cfg.atraceCats,
} as DropdownAttrs),
m(Toggle, {
title: 'Record events from all Android apps and services',
descr: '',
setEnabled: (cfg, val) => cfg.allAtraceApps = val,
isEnabled: (cfg) => cfg.allAtraceApps,
} as ToggleAttrs),
m(AtraceAppsList)),
m(Probe,
{
title: 'Event log (logcat)',
img: 'rec_logcat.png',
descr: `Streams the event log into the trace. If no buffer filter is
specified, all buffers are selected.`,
setEnabled: (cfg, val) => cfg.androidLogs = val,
isEnabled: (cfg) => cfg.androidLogs,
} as ProbeAttrs,
m(Dropdown, {
title: 'Buffers',
cssClass: '.multicolumn',
options: LOG_BUFFERS,
set: (cfg, val) => cfg.androidLogBuffers = val,
get: (cfg) => cfg.androidLogBuffers,
} as DropdownAttrs)),
m(Probe, {
title: 'Frame timeline',
img: 'rec_frame_timeline.png',
descr: `Records expected/actual frame timings from surface_flinger.
Requires Android 12 (S) or above.`,
setEnabled: (cfg, val) => cfg.androidFrameTimeline = val,
isEnabled: (cfg) => cfg.androidFrameTimeline,
} as ProbeAttrs),
m(Probe, {
title: 'Game intervention list',
img: '',
descr: `List game modes and interventions.
Requires Android 13 (T) or above.`,
setEnabled: (cfg, val) => cfg.androidGameInterventionList = val,
isEnabled: (cfg) => cfg.androidGameInterventionList,
} as ProbeAttrs),
m(Probe,
{
title: 'Network Tracing',
img: '',
descr: `Records detailed information on network packets.
Requires Android 14 (U) or above.`,
setEnabled: (cfg, val) => cfg.androidNetworkTracing = val,
isEnabled: (cfg) => cfg.androidNetworkTracing,
} as ProbeAttrs,
m(Slider, {
title: 'Poll interval',
cssClass: '.thin',
values: [100, 250, 500, 1000, 2500],
unit: 'ms',
set: (cfg, val) => cfg.androidNetworkTracingPollMs = val,
get: (cfg) => cfg.androidNetworkTracingPollMs,
} as SliderAttrs)));
}
}