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 {DataSource} from '../../common/recordingV2/recording_interfaces_v2'; 18import {getBuiltinChromeCategoryList, isChromeTarget} from '../../common/state'; 19import {globals} from '../globals'; 20import { 21 CategoriesCheckboxList, 22 CompactProbe, 23 Toggle, 24 ToggleAttrs, 25} from '../record_widgets'; 26 27import {RecordingSectionAttrs} from './recording_sections'; 28 29function extractChromeCategories(dataSources: DataSource[]): string[]| 30 undefined { 31 for (const dataSource of dataSources) { 32 if (dataSource.name === 'chromeCategories') { 33 return dataSource.descriptor as string[]; 34 } 35 } 36 return undefined; 37} 38 39class ChromeCategoriesSelection implements 40 m.ClassComponent<RecordingSectionAttrs> { 41 view({attrs}: m.CVnode<RecordingSectionAttrs>) { 42 // If we are attempting to record via the Chrome extension, we receive the 43 // list of actually supported categories via DevTools. Otherwise, we fall 44 // back to an integrated list of categories from a recent version of Chrome. 45 let categories = globals.state.chromeCategories || 46 extractChromeCategories(attrs.dataSources); 47 if (!categories || !isChromeTarget(globals.state.recordingTarget)) { 48 categories = getBuiltinChromeCategoryList(); 49 } 50 51 const defaultCategories = new Map<string, string>(); 52 const disabledByDefaultCategories = new Map<string, string>(); 53 const disabledPrefix = 'disabled-by-default-'; 54 categories.forEach((cat) => { 55 if (cat.startsWith(disabledPrefix)) { 56 disabledByDefaultCategories.set(cat, cat.replace(disabledPrefix, '')); 57 } else { 58 defaultCategories.set(cat, cat); 59 } 60 }); 61 62 return m( 63 '.chrome-categories', 64 m(CategoriesCheckboxList, { 65 categories: defaultCategories, 66 title: 'Additional categories', 67 get: (cfg) => cfg.chromeCategoriesSelected, 68 set: (cfg, val) => cfg.chromeCategoriesSelected = val, 69 }), 70 m(CategoriesCheckboxList, { 71 categories: disabledByDefaultCategories, 72 title: 'High overhead categories', 73 get: (cfg) => cfg.chromeHighOverheadCategoriesSelected, 74 set: (cfg, val) => cfg.chromeHighOverheadCategoriesSelected = val, 75 })); 76 } 77} 78 79export class ChromeSettings implements m.ClassComponent<RecordingSectionAttrs> { 80 view({attrs}: m.CVnode<RecordingSectionAttrs>) { 81 return m( 82 `.record-section${attrs.cssClass}`, 83 CompactProbe({ 84 title: 'Task scheduling', 85 setEnabled: (cfg, val) => cfg.taskScheduling = val, 86 isEnabled: (cfg) => cfg.taskScheduling, 87 }), 88 CompactProbe({ 89 title: 'IPC flows', 90 setEnabled: (cfg, val) => cfg.ipcFlows = val, 91 isEnabled: (cfg) => cfg.ipcFlows, 92 }), 93 CompactProbe({ 94 title: 'Javascript execution', 95 setEnabled: (cfg, val) => cfg.jsExecution = val, 96 isEnabled: (cfg) => cfg.jsExecution, 97 }), 98 CompactProbe({ 99 title: 'Web content rendering, layout and compositing', 100 setEnabled: (cfg, val) => cfg.webContentRendering = val, 101 isEnabled: (cfg) => cfg.webContentRendering, 102 }), 103 CompactProbe({ 104 title: 'UI rendering & surface compositing', 105 setEnabled: (cfg, val) => cfg.uiRendering = val, 106 isEnabled: (cfg) => cfg.uiRendering, 107 }), 108 CompactProbe({ 109 title: 'Input events', 110 setEnabled: (cfg, val) => cfg.inputEvents = val, 111 isEnabled: (cfg) => cfg.inputEvents, 112 }), 113 CompactProbe({ 114 title: 'Navigation & Loading', 115 setEnabled: (cfg, val) => cfg.navigationAndLoading = val, 116 isEnabled: (cfg) => cfg.navigationAndLoading, 117 }), 118 CompactProbe({ 119 title: 'Chrome Logs', 120 setEnabled: (cfg, val) => cfg.chromeLogs = val, 121 isEnabled: (cfg) => cfg.chromeLogs, 122 }), 123 m(Toggle, { 124 title: 'Remove untyped and sensitive data like URLs from the trace', 125 descr: 'Not recommended unless you intend to share the trace' + 126 ' with third-parties.', 127 setEnabled: (cfg, val) => cfg.chromePrivacyFiltering = val, 128 isEnabled: (cfg) => cfg.chromePrivacyFiltering, 129 } as ToggleAttrs), 130 m(ChromeCategoriesSelection, attrs)); 131 } 132} 133