1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 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 */ 15 16import { BaseElement, element } from '../../../../../base-ui/BaseElement'; 17import { LitTable } from '../../../../../base-ui/table/lit-table'; 18import { SelectionParam } from '../../../../bean/BoxSelection'; 19import { log } from '../../../../../log/Log'; 20import { PowerDetailsEnergy } from '../../../../bean/EnergyStruct'; 21import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; 22import { resizeObserver } from '../SheetUtils'; 23import { getTabPowerDetailsData } from '../../../../database/sql/ProcessThread.sql'; 24import { TabPanePowerDetailsHTML } from './TabPanePowerDetails.html'; 25import { NUM_100, NUM_3 } from '../../../../bean/NumBean'; 26 27@element('tabpane-power-details') 28export class TabPanePowerDetails extends BaseElement { 29 private tblPowerDetails: LitTable | null | undefined; 30 private sourcePowerDetails: Array<unknown> = []; 31 private itemType: unknown; 32 33 set data(valPowerDetails: SelectionParam) { 34 this.queryDataByDB(valPowerDetails); 35 } 36 37 connectedCallback(): void { 38 super.connectedCallback(); 39 resizeObserver(this.parentElement!, this.tblPowerDetails!); 40 } 41 42 getTimeTypeValue(): string[] { 43 return [ 44 'foreground_duration', 45 'background_duration', 46 'screen_on_duration', 47 'screen_off_duration', 48 'foreground_count', 49 'background_count', 50 'screen_on_count', 51 'screen_off_count', 52 'duration', 53 'energy', 54 'usage', 55 'camera_id', 56 ]; 57 } 58 59 getDurationTypeValue(): string[] { 60 return [ 61 'background_time', 62 'screen_on_time', 63 'screen_off_time', 64 'load', 65 'uid', 66 'usage', 67 'charge', 68 'foreground_count', 69 'background_count', 70 'screen_on_count', 71 'screen_off_count', 72 'energy', 73 'duration', 74 ]; 75 } 76 77 getEnergyTypeValue(): string[] { 78 return [ 79 'background_time', 80 'screen_on_time', 81 'screen_off_time', 82 'load', 83 'charge', 84 'foreground_count', 85 'background_count', 86 'screen_on_count', 87 'screen_off_count', 88 'camera_id', 89 'uid', 90 'foreground_duration', 91 'foreground_energy', 92 'background_duration', 93 'background_energy', 94 'screen_on_duration', 95 'screen_on_energy', 96 'screen_off_duration', 97 'screen_off_energy', 98 ]; 99 } 100 101 getCountTypeValue(): string[] { 102 return [ 103 'background_time', 104 'screen_on_time', 105 'screen_off_time', 106 'load', 107 'energy', 108 'usage', 109 'foreground_duration', 110 'background_duration', 111 'screen_on_duration', 112 'screen_off_duration', 113 'camera_id', 114 'uid', 115 'duration', 116 'charge', 117 ]; 118 } 119 120 initElements(): void { 121 this.tblPowerDetails = this.shadowRoot?.querySelector<LitTable>('#tb-power-details-energy'); 122 this.tblPowerDetails!.addEventListener('column-click', (evt): void => { 123 // @ts-ignore 124 this.sortByColumn(evt.detail); 125 }); 126 this.sourcePowerDetails = []; 127 this.itemType = { 128 time_type: [], 129 duration_type: [], 130 energy_type: [], 131 count_type: [], 132 }; 133 // @ts-ignore 134 this.itemType.time_type = this.getTimeTypeValue(); 135 // @ts-ignore 136 this.itemType.duration_type = this.getDurationTypeValue(); 137 // @ts-ignore 138 this.itemType.energy_type = this.getEnergyTypeValue(); 139 // @ts-ignore 140 this.itemType.count_type = this.getCountTypeValue(); 141 } 142 143 getPowerData(): unknown { 144 return { 145 POWER_IDE_CPU: new PowerDetailsEnergy('CPU'), 146 POWER_IDE_LOCATION: new PowerDetailsEnergy('LOCATION'), 147 POWER_IDE_GPU: new PowerDetailsEnergy('GPU'), 148 POWER_IDE_DISPLAY: new PowerDetailsEnergy('DISPLAY'), 149 POWER_IDE_CAMERA: new PowerDetailsEnergy('CAMERA'), 150 POWER_IDE_BLUETOOTH: new PowerDetailsEnergy('BLUETOOTH'), 151 POWER_IDE_FLASHLIGHT: new PowerDetailsEnergy('FLASHLIGHT'), 152 POWER_IDE_AUDIO: new PowerDetailsEnergy('AUDIO'), 153 POWER_IDE_WIFISCAN: new PowerDetailsEnergy('WIFISCAN'), 154 }; 155 } 156 157 getTotalEnergy(powerData: unknown): number { 158 return ( 159 // @ts-ignore 160 powerData.POWER_IDE_CPU.getTotalEnergy(false) + 161 // @ts-ignore 162 powerData.POWER_IDE_LOCATION.getTotalEnergy(false) + 163 // @ts-ignore 164 powerData.POWER_IDE_GPU.getTotalEnergy(true) + 165 // @ts-ignore 166 powerData.POWER_IDE_DISPLAY.getTotalEnergy(true) + 167 // @ts-ignore 168 powerData.POWER_IDE_CAMERA.getTotalEnergy(false) + 169 // @ts-ignore 170 powerData.POWER_IDE_BLUETOOTH.getTotalEnergy(false) + 171 // @ts-ignore 172 powerData.POWER_IDE_FLASHLIGHT.getTotalEnergy(false) + 173 // @ts-ignore 174 powerData.POWER_IDE_AUDIO.getTotalEnergy(false) + 175 // @ts-ignore 176 powerData.POWER_IDE_WIFISCAN.getTotalEnergy(false) 177 ); 178 } 179 180 queryDataByDB(val: SelectionParam | unknown): void { 181 // @ts-ignore 182 getTabPowerDetailsData(val.leftNs - val.leftNs, val.rightNs).then((items): void => { 183 log(`getTabPowerDetailsData size :${items.length}`); 184 let detailsData: Array<unknown> = []; 185 let set = new Set(); 186 set.add('COUNT'); 187 set.add('LOAD'); 188 set.add('CHARGE'); 189 set.add('CAMERA_ID'); 190 let powerData: unknown = this.getPowerData(); 191 let tsMax = 0; 192 let currentAppIndex = -1; 193 items.forEach((item): void => { 194 // @ts-ignore 195 let powerDatum: unknown = powerData[item.eventName]; 196 if (item.appKey.toLocaleLowerCase() === 'appname') { 197 // @ts-ignore 198 powerDatum.appName = SpHiSysEnergyChart.app_name; 199 currentAppIndex = item.eventValue.split(',').indexOf(SpHiSysEnergyChart.app_name!); 200 tsMax = 0; 201 } else if (currentAppIndex > -1 && (set.has(item.appKey) ? item.startNS >= tsMax : true)) { 202 if (set.has(item.appKey)) { 203 // @ts-ignore 204 powerDatum[item.appKey.toLocaleLowerCase()] = 205 item.startNS >= tsMax 206 ? ((tsMax = item.startNS), item.eventValue) 207 : // @ts-ignore 208 powerDatum[item.appKey.toLocaleLowerCase()]; 209 } else { 210 // @ts-ignore 211 powerDatum[item.appKey.toLocaleLowerCase()] = 212 // @ts-ignore 213 (powerDatum[item.appKey.toLocaleLowerCase()] || 0) + 214 parseInt(item.eventValue.split(',')[currentAppIndex]); 215 } 216 } 217 }); 218 let totalEnergy = this.getTotalEnergy(powerData); 219 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_CPU', false, 'time_type')); 220 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_LOCATION', false, 'duration_type')); 221 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_GPU', true, 'energy_type')); 222 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_DISPLAY', true, 'energy_type')); 223 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_CAMERA', false, 'duration_type')); 224 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_BLUETOOTH', false, 'duration_type')); 225 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_FLASHLIGHT', false, 'duration_type')); 226 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_AUDIO', false, 'duration_type')); 227 detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_WIFISCAN', false, 'count_type')); 228 if (detailsData.length > 0) { 229 this.sourcePowerDetails = detailsData; 230 this.tblPowerDetails!.recycleDataSource = detailsData; 231 } else { 232 this.sourcePowerDetails = []; 233 this.tblPowerDetails!.recycleDataSource = []; 234 } 235 this.updateTableStyles(); 236 }); 237 let th = this.tblPowerDetails?.shadowRoot?.querySelector<HTMLDivElement>('.th'); 238 if (th) { 239 th!.style.gridColumnGap = '5px'; 240 } 241 } 242 243 updateTableStyles(): void { 244 this.tblPowerDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => { 245 td.style.fontSize = '14px'; 246 td.style.fontWeight = '400'; 247 td.style.opacity = '0.9'; 248 td.style.lineHeight = '16px'; 249 }); 250 } 251 252 setEnergyItems( 253 powerData: unknown, 254 totalEnergy: number, 255 energyName: string, 256 isSimpleEnergy: boolean, 257 type: unknown 258 ): unknown { 259 // @ts-ignore 260 let ratio = (powerData[energyName].getTotalEnergy(isSimpleEnergy) * NUM_100) / totalEnergy; 261 if (totalEnergy === 0) { 262 // @ts-ignore 263 powerData[energyName].energyConsumptionRatio = '0.000 %'; 264 } else { 265 // @ts-ignore 266 powerData[energyName].energyConsumptionRatio = `${ratio.toFixed(NUM_3)} %`; 267 } 268 return this.getEnergyStyle(powerData, energyName, type); 269 } 270 271 getEnergyStyle(powerData: unknown, energyName: string, type: unknown): unknown { 272 // @ts-ignore 273 this.itemType[type].forEach((item: unknown): void => { 274 // @ts-ignore 275 powerData[energyName][item] = '-'; 276 }); 277 if (type === 'energy_type') { 278 if (energyName === 'POWER_IDE_GPU') { 279 // @ts-ignore 280 powerData[energyName].duration = '-'; 281 } else { 282 // @ts-ignore 283 powerData[energyName].usage = '-'; 284 } 285 } else if (type === 'duration_type') { 286 if (energyName !== 'POWER_IDE_CAMERA') { 287 // @ts-ignore 288 powerData[energyName].camera_id = '-'; 289 } 290 } 291 // @ts-ignore 292 return powerData[energyName]; 293 } 294 295 initHtml(): string { 296 return TabPanePowerDetailsHTML; 297 } 298 299 sortByColumn(detail: unknown): void { 300 // @ts-ignore 301 function compare(property, sort, type) { 302 return function (aPowerDetails: PowerDetailsEnergy, bPowerDetails: PowerDetailsEnergy) { 303 if (type === 'number') { 304 return sort === 2 // @ts-ignore 305 ? parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]) - // @ts-ignore 306 parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property]) // @ts-ignore 307 : parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property]) - // @ts-ignore 308 parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]); 309 } else { 310 // @ts-ignore 311 if (bPowerDetails[property] > aPowerDetails[property]) { 312 return sort === 2 ? 1 : -1; 313 } else { 314 // @ts-ignore 315 if (bPowerDetails[property] === aPowerDetails[property]) { 316 return 0; 317 } else { 318 return sort === 2 ? -1 : 1; 319 } 320 } 321 } 322 }; 323 } 324 // @ts-ignore 325 if (detail.key === 'appName') { 326 // @ts-ignore 327 this.sourcePowerDetails.sort(compare(detail.key, detail.sort, 'string')); 328 } else { 329 // @ts-ignore 330 this.sourcePowerDetails.sort(compare(detail.key, detail.sort, 'number')); 331 } 332 this.tblPowerDetails!.recycleDataSource = this.sourcePowerDetails; 333 334 this.tblPowerDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => { 335 td.style.fontSize = '14px'; 336 td.style.fontWeight = '400'; 337 td.style.opacity = '0.9'; 338 td.style.lineHeight = '16px'; 339 }); 340 } 341} 342