diff options
Diffstat (limited to 'ui/src/controller/record_controller.ts')
-rw-r--r-- | ui/src/controller/record_controller.ts | 108 |
1 files changed, 76 insertions, 32 deletions
diff --git a/ui/src/controller/record_controller.ts b/ui/src/controller/record_controller.ts index a124ecfdf..f1631a86b 100644 --- a/ui/src/controller/record_controller.ts +++ b/ui/src/controller/record_controller.ts @@ -43,9 +43,11 @@ import { isAndroidP, isChromeTarget, isCrOSTarget, - RecordConfig, + isLinuxTarget, + isTargetOsAtLeast, RecordingTarget } from '../common/state'; +import {publishBufferUsage, publishTrackData} from '../frontend/publish'; import {AdbOverWebUsb} from './adb'; import {AdbConsumerPort} from './adb_shell_controller'; @@ -62,6 +64,7 @@ import { } from './consumer_port_types'; import {Controller} from './controller'; import {App, globals} from './globals'; +import {RecordConfig} from './record_config_types'; import {Consumer, RpcConsumerPort} from './record_controller_interfaces'; type RPCImplMethod = (Method|rpc.ServiceMethod<Message<{}>, Message<{}>>); @@ -114,6 +117,8 @@ export function genConfig( const atraceApps = new Set<string>(); const chromeCategories = new Set<string>(); uiCfg.chromeCategoriesSelected.forEach(it => chromeCategories.add(it)); + uiCfg.chromeHighOverheadCategoriesSelected.forEach( + it => chromeCategories.add(it)); let procThreadAssociationPolling = false; let procThreadAssociationFtrace = false; @@ -122,6 +127,10 @@ export function genConfig( if (uiCfg.cpuSched) { procThreadAssociationPolling = true; procThreadAssociationFtrace = true; + uiCfg.ftrace = true; + if (isTargetOsAtLeast(target, 'S')) { + uiCfg.symbolizeKsyms = true; + } ftraceEvents.add('sched/sched_switch'); ftraceEvents.add('power/suspend_resume'); ftraceEvents.add('sched/sched_wakeup'); @@ -156,25 +165,22 @@ export function genConfig( ftraceEvents.add('raw_syscalls/sys_exit'); } - if (procThreadAssociationFtrace) { - ftraceEvents.add('sched/sched_process_exit'); - ftraceEvents.add('sched/sched_process_free'); - ftraceEvents.add('task/task_newtask'); - ftraceEvents.add('task/task_rename'); - } - if (uiCfg.batteryDrain) { const ds = new TraceConfig.DataSource(); ds.config = new DataSourceConfig(); - ds.config.name = 'android.power'; - ds.config.androidPowerConfig = new AndroidPowerConfig(); - ds.config.androidPowerConfig.batteryPollMs = uiCfg.batteryDrainPollMs; - ds.config.androidPowerConfig.batteryCounters = [ - AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CAPACITY_PERCENT, - AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CHARGE, - AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CURRENT, - ]; - ds.config.androidPowerConfig.collectPowerRails = true; + if (isCrOSTarget(target) || isLinuxTarget(target)) { + ds.config.name = 'linux.sysfs_power'; + } else { + ds.config.name = 'android.power'; + ds.config.androidPowerConfig = new AndroidPowerConfig(); + ds.config.androidPowerConfig.batteryPollMs = uiCfg.batteryDrainPollMs; + ds.config.androidPowerConfig.batteryCounters = [ + AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CAPACITY_PERCENT, + AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CHARGE, + AndroidPowerConfig.BatteryCounters.BATTERY_COUNTER_CURRENT, + ]; + ds.config.androidPowerConfig.collectPowerRails = true; + } if (!isChromeTarget(target) || isCrOSTarget(target)) { protoCfg.dataSources.push(ds); } @@ -192,7 +198,7 @@ export function genConfig( let sysStatsCfg: SysStatsConfig|undefined = undefined; if (uiCfg.cpuCoarse) { - if (sysStatsCfg === undefined) sysStatsCfg = new SysStatsConfig(); + sysStatsCfg = new SysStatsConfig(); sysStatsCfg.statPeriodMs = uiCfg.cpuCoarsePollMs; sysStatsCfg.statCounters = [ SysStatsConfig.StatCounters.STAT_CPU_TIMES, @@ -211,6 +217,13 @@ export function genConfig( ftraceEvents.add('kmem/ion_heap_shrink'); } + if (procThreadAssociationFtrace) { + ftraceEvents.add('sched/sched_process_exit'); + ftraceEvents.add('sched/sched_process_free'); + ftraceEvents.add('task/task_newtask'); + ftraceEvents.add('task/task_rename'); + } + if (uiCfg.meminfo) { if (sysStatsCfg === undefined) sysStatsCfg = new SysStatsConfig(); sysStatsCfg.meminfoPeriodMs = uiCfg.meminfoPeriodMs; @@ -393,7 +406,7 @@ export function genConfig( } if (chromeCategories.size !== 0) { - let chromeRecordMode = ''; + let chromeRecordMode; if (uiCfg.mode === 'STOP_WHEN_FULL') { chromeRecordMode = 'record-until-full'; } else { @@ -430,10 +443,22 @@ export function genConfig( metadataDs.config.chromeConfig = new ChromeConfig(); metadataDs.config.chromeConfig.traceConfig = traceConfigJson; protoCfg.dataSources.push(metadataDs); - } - if (uiCfg.screenRecord) { - atraceCats.add('gfx'); + if (chromeCategories.has('disabled-by-default-memory-infra')) { + const memoryDs = new TraceConfig.DataSource(); + memoryDs.config = new DataSourceConfig(); + memoryDs.config.name = 'org.chromium.memory_instrumentation'; + memoryDs.config.chromeConfig = new ChromeConfig(); + memoryDs.config.chromeConfig.traceConfig = traceConfigJson; + protoCfg.dataSources.push(memoryDs); + + const HeapProfDs = new TraceConfig.DataSource(); + HeapProfDs.config = new DataSourceConfig(); + HeapProfDs.config.name = 'org.chromium.native_heap_profiler'; + HeapProfDs.config.chromeConfig = new ChromeConfig(); + HeapProfDs.config.chromeConfig.traceConfig = traceConfigJson; + protoCfg.dataSources.push(HeapProfDs); + } } // Keep these last. The stages above can enrich them. @@ -467,7 +492,8 @@ export function genConfig( protoCfg.dataSources.push(ds); } - if (uiCfg.ftrace || uiCfg.atraceApps.length > 0 || ftraceEvents.size > 0 || + // TODO(octaviant): move all this logic in a follow up CL. + if (uiCfg.ftrace || uiCfg.atrace || ftraceEvents.size > 0 || atraceCats.size > 0 || atraceApps.size > 0) { const ds = new TraceConfig.DataSource(); ds.config = new DataSourceConfig(); @@ -478,12 +504,24 @@ export function genConfig( if (uiCfg.ftrace) { ds.config.ftraceConfig.bufferSizeKb = uiCfg.ftraceBufferSizeKb; ds.config.ftraceConfig.drainPeriodMs = uiCfg.ftraceDrainPeriodMs; + if (uiCfg.symbolizeKsyms) { + ds.config.ftraceConfig.symbolizeKsyms = true; + ftraceEvents.add('sched/sched_blocked_reason'); + } for (const line of uiCfg.ftraceExtraEvents.split('\n')) { if (line.trim().length > 0) ftraceEvents.add(line.trim()); } } - for (const line of uiCfg.atraceApps.split('\n')) { - if (line.trim().length > 0) atraceApps.add(line.trim()); + + if (uiCfg.atrace) { + if (uiCfg.allAtraceApps) { + atraceApps.clear(); + atraceApps.add('*'); + } else { + for (const line of uiCfg.atraceApps.split('\n')) { + if (line.trim().length > 0) atraceApps.add(line.trim()); + } + } } if (atraceCats.size > 0 || atraceApps.size > 0) { @@ -584,13 +622,14 @@ export function toPbtxt(configBuffer: Uint8Array): string { export class RecordController extends Controller<'main'> implements Consumer { private app: App; private config: RecordConfig|null = null; - private extensionPort: MessagePort; + private readonly extensionPort: MessagePort; private recordingInProgress = false; private consumerPort: ConsumerPort; private traceBuffer: Uint8Array[] = []; private bufferUpdateInterval: ReturnType<typeof setTimeout>|undefined; private adb = new AdbOverWebUsb(); private recordedTraceSuffix = TRACE_SUFFIX; + private fetchedCategories = false; // We have a different controller for each targetOS. The correct one will be // created when needed, and stored here. When the key is a string, it is the @@ -608,11 +647,12 @@ export class RecordController extends Controller<'main'> implements Consumer { run() { // TODO(eseckler): Use ConsumerPort's QueryServiceState instead // of posting a custom extension message to retrieve the category list. - if (this.app.state.updateChromeCategories === true) { + if (this.app.state.fetchChromeCategories && !this.fetchedCategories) { + this.fetchedCategories = true; if (this.app.state.extensionInstalled) { this.extensionPort.postMessage({method: 'GetCategories'}); } - globals.dispatch(Actions.setUpdateChromeCategories({update: false})); + globals.dispatch(Actions.setFetchChromeCategories({fetch: false})); } if (this.app.state.recordConfig === this.config && this.app.state.recordingInProgress === this.recordingInProgress) { @@ -632,7 +672,7 @@ export class RecordController extends Controller<'main'> implements Consumer { `; const traceConfig = genConfig(this.config, this.app.state.recordingTarget); // TODO(hjd): This should not be TrackData after we unify the stores. - this.app.publish('TrackData', { + publishTrackData({ id: 'config', data: { commandline, @@ -683,13 +723,16 @@ export class RecordController extends Controller<'main'> implements Consumer { // TODO(nicomazz): handle this as intended by consumer_port.proto. console.assert(data.slices.length === 1); if (data.slices[0].data) this.traceBuffer.push(data.slices[0].data); + // The line underneath is 'misusing' the format ReadBuffersResponse. + // The boolean field 'lastSliceForPacket' is used as 'lastPacketInTrace'. + // See http://shortn/_53WB8A1aIr. if (data.slices[0].lastSliceForPacket) this.onTraceComplete(); } else if (isEnableTracingResponse(data)) { this.readBuffers(); } else if (isGetTraceStatsResponse(data)) { const percentage = this.getBufferUsagePercentage(data); if (percentage) { - globals.publish('BufferUsage', {percentage}); + publishBufferUsage({percentage}); } } else if (isFreeBuffersResponse(data)) { // No action required. @@ -744,6 +787,7 @@ export class RecordController extends Controller<'main'> implements Consumer { } onError(message: string) { + // TODO(octaviant): b/204998302 console.error('Error in record controller: ', message); globals.dispatch( Actions.setLastRecordingError({error: message.substr(0, 150)})); @@ -764,7 +808,7 @@ export class RecordController extends Controller<'main'> implements Consumer { // protocol. Actually, there is no full consumer_port implementation, but // only the support to start tracing and fetch the file. async getTargetController(target: RecordingTarget): Promise<RpcConsumerPort> { - const identifier = this.getTargetIdentifier(target); + const identifier = RecordController.getTargetIdentifier(target); // The reason why caching the target 'record controller' Promise is that // multiple rcp calls can happen while we are trying to understand if an @@ -798,7 +842,7 @@ export class RecordController extends Controller<'main'> implements Consumer { return controllerPromise; } - private getTargetIdentifier(target: RecordingTarget): string { + private static getTargetIdentifier(target: RecordingTarget): string { return isAdbTarget(target) ? target.serial : target.os; } |