• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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