1// Copyright (C) 2021 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 {Time} from '../base/time'; 16import {createEmptyRecordConfig} from '../controller/record_config_types'; 17import {featureFlags} from '../core/feature_flags'; 18import {Aggregation} from '../frontend/pivot_table_types'; 19import { 20 autosaveConfigStore, 21 recordTargetStore, 22} from '../frontend/record_config'; 23import {SqlTables} from '../frontend/sql_table/well_known_tables'; 24 25import {NonSerializableState, State, STATE_VERSION} from './state'; 26 27const AUTOLOAD_STARTED_CONFIG_FLAG = featureFlags.register({ 28 id: 'autoloadStartedConfig', 29 name: 'Auto-load last used recording config', 30 description: 31 'Starting a recording automatically saves its configuration. ' + 32 'This flag controls whether this config is automatically loaded.', 33 defaultValue: true, 34}); 35 36export function keyedMap<T>( 37 keyFn: (key: T) => string, 38 ...values: T[] 39): Map<string, T> { 40 const result = new Map<string, T>(); 41 42 for (const value of values) { 43 result.set(keyFn(value), value); 44 } 45 46 return result; 47} 48 49export const COUNT_AGGREGATION: Aggregation = { 50 aggregationFunction: 'COUNT', 51 // Exact column is ignored for count aggregation because it does not matter 52 // what to count, use empty strings. 53 column: {kind: 'regular', table: '', column: ''}, 54}; 55 56export function createEmptyNonSerializableState(): NonSerializableState { 57 return { 58 pivotTable: { 59 queryResult: null, 60 selectedPivots: [ 61 {kind: 'regular', table: SqlTables.slice.name, column: 'name'}, 62 ], 63 selectedAggregations: [ 64 { 65 aggregationFunction: 'SUM', 66 column: {kind: 'regular', table: SqlTables.slice.name, column: 'dur'}, 67 sortDirection: 'DESC', 68 }, 69 { 70 aggregationFunction: 'SUM', 71 column: { 72 kind: 'regular', 73 table: SqlTables.slice.name, 74 column: 'thread_dur', 75 }, 76 }, 77 COUNT_AGGREGATION, 78 ], 79 constrainToArea: true, 80 queryRequested: false, 81 }, 82 }; 83} 84 85export function createEmptyState(): State { 86 return { 87 version: STATE_VERSION, 88 nextId: '-1', 89 newEngineMode: 'USE_HTTP_RPC_IF_AVAILABLE', 90 tracks: {}, 91 utidToThreadSortKey: {}, 92 aggregatePreferences: {}, 93 trackGroups: {}, 94 pinnedTracks: [], 95 scrollingTracks: [], 96 queries: {}, 97 notes: {}, 98 99 recordConfig: AUTOLOAD_STARTED_CONFIG_FLAG.get() 100 ? autosaveConfigStore.get() 101 : createEmptyRecordConfig(), 102 displayConfigAsPbtxt: false, 103 lastLoadedConfig: {type: 'NONE'}, 104 105 frontendLocalState: { 106 visibleState: { 107 start: Time.ZERO, 108 end: Time.fromSeconds(10), 109 lastUpdate: 0, 110 resolution: 0n, 111 }, 112 }, 113 114 omniboxState: { 115 omnibox: '', 116 mode: 'SEARCH', 117 }, 118 119 status: {msg: '', timestamp: 0}, 120 selection: { 121 kind: 'empty', 122 }, 123 traceConversionInProgress: false, 124 125 perfDebug: false, 126 sidebarVisible: true, 127 hoveredUtid: -1, 128 hoveredPid: -1, 129 hoverCursorTimestamp: Time.INVALID, 130 hoveredNoteTimestamp: Time.INVALID, 131 highlightedSliceId: -1, 132 focusedFlowIdLeft: -1, 133 focusedFlowIdRight: -1, 134 searchIndex: -1, 135 136 tabs: { 137 currentTab: 'current_selection', 138 openTabs: [], 139 }, 140 141 recordingInProgress: false, 142 recordingCancelled: false, 143 extensionInstalled: false, 144 flamegraphModalDismissed: false, 145 recordingTarget: recordTargetStore.getValidTarget(), 146 availableAdbDevices: [], 147 148 fetchChromeCategories: false, 149 chromeCategories: undefined, 150 nonSerializableState: createEmptyNonSerializableState(), 151 152 // Somewhere to store plugins' persistent state. 153 plugins: {}, 154 }; 155} 156