1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace'; 17fb726d48Sopenharmony_ciimport { info } from '../../../log/Log'; 18fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow'; 19fb726d48Sopenharmony_ciimport { ColorUtils } from '../trace/base/ColorUtils'; 20fb726d48Sopenharmony_ciimport { CpuFreqLimitRender, CpuFreqLimitsStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 21fb726d48Sopenharmony_ciimport { CpuFreqStruct, FreqRender } from '../../database/ui-worker/ProcedureWorkerFreq'; 22fb726d48Sopenharmony_ciimport { CpuStateRender, CpuStateStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCpuState'; 23fb726d48Sopenharmony_ciimport { folderSupplier, folderThreadHandler, rowThreadHandler } from './SpChartManager'; 24fb726d48Sopenharmony_ciimport { Utils } from '../trace/base/Utils'; 25fb726d48Sopenharmony_ciimport { cpuFreqDataSender } from '../../database/data-trafic/cpu/CpuFreqDataSender'; 26fb726d48Sopenharmony_ciimport { cpuStateSender } from '../../database/data-trafic/cpu/CpuStateSender'; 27fb726d48Sopenharmony_ciimport { cpuFreqLimitSender } from '../../database/data-trafic/cpu/CpuFreqLimitDataSender'; 28fb726d48Sopenharmony_ciimport { 29fb726d48Sopenharmony_ci getCpuLimitFreqId, 30fb726d48Sopenharmony_ci getCpuLimitFreqMax, 31fb726d48Sopenharmony_ci queryCpuFreq, 32fb726d48Sopenharmony_ci queryCpuMaxFreq, 33fb726d48Sopenharmony_ci queryCpuStateFilter, 34fb726d48Sopenharmony_ci} from '../../database/sql/Cpu.sql'; 35fb726d48Sopenharmony_ciimport { BaseStruct } from '../../bean/BaseStruct'; 36fb726d48Sopenharmony_ci 37fb726d48Sopenharmony_ciexport class SpFreqChart { 38fb726d48Sopenharmony_ci private readonly trace: SpSystemTrace; 39fb726d48Sopenharmony_ci 40fb726d48Sopenharmony_ci constructor(trace: SpSystemTrace) { 41fb726d48Sopenharmony_ci this.trace = trace; 42fb726d48Sopenharmony_ci } 43fb726d48Sopenharmony_ci 44fb726d48Sopenharmony_ci async init(parentRow?: TraceRow<BaseStruct>, traceId?: string): Promise<void> { 45fb726d48Sopenharmony_ci let freqList = await queryCpuFreq(traceId); 46fb726d48Sopenharmony_ci let cpuStateFilterIds = await queryCpuStateFilter(traceId); 47fb726d48Sopenharmony_ci //@ts-ignore 48fb726d48Sopenharmony_ci this.trace.stateRowsId = cpuStateFilterIds; 49fb726d48Sopenharmony_ci let cpuFreqLimits = await getCpuLimitFreqId(traceId); 50fb726d48Sopenharmony_ci let cpuFreqLimitsMax = await getCpuLimitFreqMax(cpuFreqLimits.map((limit) => limit.maxFilterId).join(','), traceId); 51fb726d48Sopenharmony_ci if (freqList.length > 0) { 52fb726d48Sopenharmony_ci let folderRow = this.createFolderRow(traceId); 53fb726d48Sopenharmony_ci folderRow.rowId = 'Cpu Frequency'; 54fb726d48Sopenharmony_ci folderRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_ALL; 55fb726d48Sopenharmony_ci folderRow.name = 'Cpu Frequency'; 56fb726d48Sopenharmony_ci folderRow.selectChangeHandler = this.trace.selectChangeHandler; 57fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRow); 58fb726d48Sopenharmony_ci info('Cpu Freq data size is: ', freqList!.length); 59fb726d48Sopenharmony_ci await this.addFreqRows(freqList, folderRow, traceId); 60fb726d48Sopenharmony_ci if (parentRow) { 61fb726d48Sopenharmony_ci parentRow.addChildTraceRow(folderRow); 62fb726d48Sopenharmony_ci } else { 63fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRow); 64fb726d48Sopenharmony_ci } 65fb726d48Sopenharmony_ci } 66fb726d48Sopenharmony_ci if (cpuStateFilterIds.length > 0) { 67fb726d48Sopenharmony_ci let folderRowState = this.createFolderRow(); 68fb726d48Sopenharmony_ci folderRowState.rowId = 'Cpu State'; 69fb726d48Sopenharmony_ci folderRowState.rowType = TraceRow.ROW_TYPE_CPU_STATE_ALL; 70fb726d48Sopenharmony_ci folderRowState.name = 'Cpu State'; 71fb726d48Sopenharmony_ci folderRowState.selectChangeHandler = this.trace.selectChangeHandler; 72fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRowState); 73fb726d48Sopenharmony_ci this.addStateRows(cpuStateFilterIds, folderRowState, traceId); 74fb726d48Sopenharmony_ci if (parentRow) { 75fb726d48Sopenharmony_ci parentRow.addChildTraceRow(folderRowState); 76fb726d48Sopenharmony_ci } else { 77fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRowState); 78fb726d48Sopenharmony_ci } 79fb726d48Sopenharmony_ci } 80fb726d48Sopenharmony_ci if (cpuFreqLimits.length > 0) { 81fb726d48Sopenharmony_ci let folderRowLimit = this.createFolderRow(); 82fb726d48Sopenharmony_ci folderRowLimit.rowId = 'Cpu Freq Limit'; 83fb726d48Sopenharmony_ci folderRowLimit.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMITALL; 84fb726d48Sopenharmony_ci folderRowLimit.name = 'Cpu Freq Limit'; 85fb726d48Sopenharmony_ci folderRowLimit.selectChangeHandler = this.trace.selectChangeHandler; 86fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRowLimit); 87fb726d48Sopenharmony_ci this.addFreqLimitRows(cpuFreqLimits, cpuFreqLimitsMax, folderRowLimit, traceId); 88fb726d48Sopenharmony_ci if (parentRow) { 89fb726d48Sopenharmony_ci parentRow.addChildTraceRow(folderRowLimit); 90fb726d48Sopenharmony_ci } else { 91fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folderRowLimit); 92fb726d48Sopenharmony_ci } 93fb726d48Sopenharmony_ci } 94fb726d48Sopenharmony_ci } 95fb726d48Sopenharmony_ci 96fb726d48Sopenharmony_ci createFolderRow(traceId?: string): TraceRow<BaseStruct> { 97fb726d48Sopenharmony_ci let folder = TraceRow.skeleton<BaseStruct>(traceId); 98fb726d48Sopenharmony_ci folder.rowParentId = ''; 99fb726d48Sopenharmony_ci folder.folder = true; 100fb726d48Sopenharmony_ci folder.style.height = '40px'; 101fb726d48Sopenharmony_ci folder.rowHidden = folder.expansion; 102fb726d48Sopenharmony_ci folder.setAttribute('children', ''); 103fb726d48Sopenharmony_ci folder.supplier = folderSupplier(); 104fb726d48Sopenharmony_ci folder.onThreadHandler = folderThreadHandler(folder, this.trace); 105fb726d48Sopenharmony_ci return folder; 106fb726d48Sopenharmony_ci } 107fb726d48Sopenharmony_ci 108fb726d48Sopenharmony_ci async addFreqRows( 109fb726d48Sopenharmony_ci freqList: Array<{ cpu: number; filterId: number }>, 110fb726d48Sopenharmony_ci folderRow: TraceRow<BaseStruct>, 111fb726d48Sopenharmony_ci traceId?: string 112fb726d48Sopenharmony_ci ): Promise<void> { 113fb726d48Sopenharmony_ci let freqMaxList = await queryCpuMaxFreq(traceId); 114fb726d48Sopenharmony_ci CpuFreqStruct.maxFreq = freqMaxList[0].maxFreq; 115fb726d48Sopenharmony_ci let maxFreqObj = Utils.getFrequencyWithUnit(freqMaxList[0].maxFreq); 116fb726d48Sopenharmony_ci CpuFreqStruct.maxFreq = maxFreqObj.maxFreq; 117fb726d48Sopenharmony_ci CpuFreqStruct.maxFreqName = maxFreqObj.maxFreqName; 118fb726d48Sopenharmony_ci for (let i = 0; i < freqList.length; i++) { 119fb726d48Sopenharmony_ci const it = freqList[i]; 120fb726d48Sopenharmony_ci let traceRow = TraceRow.skeleton<CpuFreqStruct>(traceId); 121fb726d48Sopenharmony_ci traceRow.rowId = `${it.filterId}`; 122fb726d48Sopenharmony_ci traceRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ; 123fb726d48Sopenharmony_ci traceRow.rowParentId = ''; 124fb726d48Sopenharmony_ci traceRow.style.height = '40px'; 125fb726d48Sopenharmony_ci traceRow.name = `Cpu ${it.cpu} Frequency`; 126fb726d48Sopenharmony_ci traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 127fb726d48Sopenharmony_ci traceRow.selectChangeHandler = this.trace.selectChangeHandler; 128fb726d48Sopenharmony_ci traceRow.supplierFrame = (): Promise<CpuFreqStruct[]> => cpuFreqDataSender(it.cpu, traceRow); 129fb726d48Sopenharmony_ci traceRow.focusHandler = (): void => { 130fb726d48Sopenharmony_ci this.trace?.displayTip( 131fb726d48Sopenharmony_ci traceRow, 132fb726d48Sopenharmony_ci CpuFreqStruct.hoverCpuFreqStruct, 133fb726d48Sopenharmony_ci `<span>${ColorUtils.formatNumberComma(CpuFreqStruct.hoverCpuFreqStruct?.value!)} kHz</span>` 134fb726d48Sopenharmony_ci ); 135fb726d48Sopenharmony_ci }; 136fb726d48Sopenharmony_ci traceRow.findHoverStruct = (): void => { 137fb726d48Sopenharmony_ci CpuFreqStruct.hoverCpuFreqStruct = traceRow.getHoverStruct(true, false, 'value'); 138fb726d48Sopenharmony_ci }; 139fb726d48Sopenharmony_ci traceRow.onThreadHandler = rowThreadHandler<FreqRender>( 140fb726d48Sopenharmony_ci 'freq', 141fb726d48Sopenharmony_ci 'context', 142fb726d48Sopenharmony_ci { 143fb726d48Sopenharmony_ci type: `freq${it.cpu}`, 144fb726d48Sopenharmony_ci }, 145fb726d48Sopenharmony_ci traceRow, 146fb726d48Sopenharmony_ci this.trace 147fb726d48Sopenharmony_ci ); 148fb726d48Sopenharmony_ci folderRow!.addChildTraceRow(traceRow); 149fb726d48Sopenharmony_ci } 150fb726d48Sopenharmony_ci } 151fb726d48Sopenharmony_ci 152fb726d48Sopenharmony_ci addStateRows( 153fb726d48Sopenharmony_ci cpuStateFilterIds: Array<{ cpu: number; filterId: number }>, 154fb726d48Sopenharmony_ci folderRowState: TraceRow<BaseStruct>, 155fb726d48Sopenharmony_ci traceId?: string 156fb726d48Sopenharmony_ci ): void { 157fb726d48Sopenharmony_ci for (let it of cpuStateFilterIds) { 158fb726d48Sopenharmony_ci let cpuStateRow = TraceRow.skeleton<CpuStateStruct>(traceId); 159fb726d48Sopenharmony_ci cpuStateRow.rowId = `${it.filterId}`; 160fb726d48Sopenharmony_ci cpuStateRow.rowType = TraceRow.ROW_TYPE_CPU_STATE; 161fb726d48Sopenharmony_ci cpuStateRow.rowParentId = ''; 162fb726d48Sopenharmony_ci cpuStateRow.style.height = '40px'; 163fb726d48Sopenharmony_ci cpuStateRow.name = `Cpu ${it.cpu} State`; 164fb726d48Sopenharmony_ci cpuStateRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 165fb726d48Sopenharmony_ci cpuStateRow.selectChangeHandler = this.trace.selectChangeHandler; 166fb726d48Sopenharmony_ci cpuStateRow.supplierFrame = async (): Promise<CpuStateStruct[]> => { 167fb726d48Sopenharmony_ci let rs = await cpuStateSender(it.filterId, cpuStateRow); 168fb726d48Sopenharmony_ci rs.forEach((t) => (t.cpu = it.cpu)); 169fb726d48Sopenharmony_ci return rs; 170fb726d48Sopenharmony_ci }; 171fb726d48Sopenharmony_ci cpuStateRow.focusHandler = (): void => { 172fb726d48Sopenharmony_ci this.trace.displayTip( 173fb726d48Sopenharmony_ci cpuStateRow, 174fb726d48Sopenharmony_ci CpuStateStruct.hoverStateStruct, 175fb726d48Sopenharmony_ci `<span>State: ${CpuStateStruct.hoverStateStruct?.value}</span>` 176fb726d48Sopenharmony_ci ); 177fb726d48Sopenharmony_ci }; 178fb726d48Sopenharmony_ci cpuStateRow.findHoverStruct = (): void => { 179fb726d48Sopenharmony_ci CpuStateStruct.hoverStateStruct = cpuStateRow.getHoverStruct(); 180fb726d48Sopenharmony_ci }; 181fb726d48Sopenharmony_ci cpuStateRow.onThreadHandler = rowThreadHandler<CpuStateRender>( 182fb726d48Sopenharmony_ci 'cpu-state', 183fb726d48Sopenharmony_ci 'cpuStateContext', 184fb726d48Sopenharmony_ci { 185fb726d48Sopenharmony_ci type: `cpu-state-${it.cpu}`, 186fb726d48Sopenharmony_ci cpu: it.cpu, 187fb726d48Sopenharmony_ci }, 188fb726d48Sopenharmony_ci cpuStateRow, 189fb726d48Sopenharmony_ci this.trace 190fb726d48Sopenharmony_ci ); 191fb726d48Sopenharmony_ci folderRowState!.addChildTraceRow(cpuStateRow); 192fb726d48Sopenharmony_ci } 193fb726d48Sopenharmony_ci } 194fb726d48Sopenharmony_ci 195fb726d48Sopenharmony_ci addFreqLimitRows( 196fb726d48Sopenharmony_ci cpuFreqLimits: Array<CpuFreqRowLimit>, 197fb726d48Sopenharmony_ci cpuFreqLimitsMax: Array<{ maxValue: number; filterId: number }>, 198fb726d48Sopenharmony_ci folderRowLimit: TraceRow<BaseStruct>, 199fb726d48Sopenharmony_ci traceId?: string 200fb726d48Sopenharmony_ci ): void { 201fb726d48Sopenharmony_ci for (let limit of cpuFreqLimits) { 202fb726d48Sopenharmony_ci let findMax = Utils.getFrequencyWithUnit( 203fb726d48Sopenharmony_ci cpuFreqLimitsMax.find((maxLimit) => maxLimit.filterId === limit.maxFilterId)?.maxValue || 0 204fb726d48Sopenharmony_ci ); 205fb726d48Sopenharmony_ci let cpuFreqLimitRow = TraceRow.skeleton<CpuFreqLimitsStruct>(traceId); 206fb726d48Sopenharmony_ci cpuFreqLimitRow.rowId = `${limit.cpu}`; 207fb726d48Sopenharmony_ci cpuFreqLimitRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMIT; 208fb726d48Sopenharmony_ci cpuFreqLimitRow.rowParentId = ''; 209fb726d48Sopenharmony_ci cpuFreqLimitRow.style.height = '40px'; 210fb726d48Sopenharmony_ci cpuFreqLimitRow.name = `Cpu ${limit.cpu} Freq Limit`; 211fb726d48Sopenharmony_ci cpuFreqLimitRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 212fb726d48Sopenharmony_ci cpuFreqLimitRow.selectChangeHandler = this.trace.selectChangeHandler; 213fb726d48Sopenharmony_ci cpuFreqLimitRow.setAttribute('maxFilterId', `${limit.maxFilterId}`); 214fb726d48Sopenharmony_ci cpuFreqLimitRow.setAttribute('minFilterId', `${limit.minFilterId}`); 215fb726d48Sopenharmony_ci cpuFreqLimitRow.setAttribute('cpu', `${limit.cpu}`); 216fb726d48Sopenharmony_ci cpuFreqLimitRow.supplierFrame = async (): Promise<CpuFreqLimitsStruct[]> => { 217fb726d48Sopenharmony_ci const res = 218fb726d48Sopenharmony_ci await cpuFreqLimitSender(limit.maxFilterId, limit.minFilterId, limit.cpu, cpuFreqLimitRow); 219fb726d48Sopenharmony_ci res.forEach((item) => (item.cpu = limit.cpu)); 220fb726d48Sopenharmony_ci return res; 221fb726d48Sopenharmony_ci }; 222fb726d48Sopenharmony_ci cpuFreqLimitRow.focusHandler = (ev): void => { 223fb726d48Sopenharmony_ci this.trace.displayTip( 224fb726d48Sopenharmony_ci cpuFreqLimitRow, 225fb726d48Sopenharmony_ci CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct, 226fb726d48Sopenharmony_ci `<span>Max Freq: ${ColorUtils.formatNumberComma( 227fb726d48Sopenharmony_ci CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.max || 0 228fb726d48Sopenharmony_ci )} kHz</span><span>Min Freq: ${ColorUtils.formatNumberComma( 229fb726d48Sopenharmony_ci CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.min || 0 230fb726d48Sopenharmony_ci )} kHz</span>` 231fb726d48Sopenharmony_ci ); 232fb726d48Sopenharmony_ci }; 233fb726d48Sopenharmony_ci cpuFreqLimitRow.findHoverStruct = (): void => { 234fb726d48Sopenharmony_ci CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = cpuFreqLimitRow.getHoverStruct(); 235fb726d48Sopenharmony_ci }; 236fb726d48Sopenharmony_ci cpuFreqLimitRow.onThreadHandler = rowThreadHandler<CpuFreqLimitRender>( 237fb726d48Sopenharmony_ci 'cpu-limit-freq', 238fb726d48Sopenharmony_ci 'context', 239fb726d48Sopenharmony_ci { 240fb726d48Sopenharmony_ci type: `cpu-limit-freq-${limit.cpu}`, 241fb726d48Sopenharmony_ci cpu: limit.cpu, 242fb726d48Sopenharmony_ci maxFreq: findMax?.maxFreq || 0, 243fb726d48Sopenharmony_ci maxFreqName: findMax?.maxFreqName || '', 244fb726d48Sopenharmony_ci }, 245fb726d48Sopenharmony_ci cpuFreqLimitRow, 246fb726d48Sopenharmony_ci this.trace 247fb726d48Sopenharmony_ci ); 248fb726d48Sopenharmony_ci folderRowLimit!.addChildTraceRow(cpuFreqLimitRow); 249fb726d48Sopenharmony_ci } 250fb726d48Sopenharmony_ci } 251fb726d48Sopenharmony_ci} 252fb726d48Sopenharmony_ci 253fb726d48Sopenharmony_ciexport class CpuFreqRowLimit { 254fb726d48Sopenharmony_ci cpu: number = 0; 255fb726d48Sopenharmony_ci maxFilterId: number = 0; 256fb726d48Sopenharmony_ci minFilterId: number = 0; 257fb726d48Sopenharmony_ci} 258