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.js"; 17import {LitTable} from "../../../../../base-ui/table/lit-table.js"; 18import {SelectionParam} from "../../../../bean/BoxSelection.js"; 19import {getTabPowerDetailsData} from "../../../../database/SqlLite.js"; 20import {log} from "../../../../../log/Log.js"; 21import {PowerDetailsEnergy} from "../../../../bean/EnergyStruct.js"; 22import {SpHiSysEventChart} from "../../../chart/SpHiSysEventChart.js"; 23 24@element('tabpane-power-details') 25export class TabPanePowerDetails extends BaseElement { 26 private tbl: LitTable | null | undefined; 27 private source: Array<any> = []; 28 private itemType: any 29 30 set data(val: SelectionParam | any) { 31 this.queryDataByDB(val) 32 } 33 34 connectedCallback() { 35 super.connectedCallback(); 36 new ResizeObserver((entries) => { 37 if (this.parentElement?.clientHeight != 0) { 38 // @ts-ignore 39 this.tbl!.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 45) + "px" 40 this.tbl!.reMeauseHeight() 41 } 42 }).observe(this.parentElement!); 43 } 44 45 initElements(): void { 46 this.tbl = this.shadowRoot?.querySelector<LitTable>('#tb-power-details-energy'); 47 this.tbl!.addEventListener('column-click', (evt) => { 48 // @ts-ignore 49 this.sortByColumn(evt.detail) 50 }); 51 this.source = [] 52 this.itemType = { 53 "time_type": ["foreground_duration", "background_duration", "screen_on_duration", "screen_off_duration", 54 "foreground_count", "background_count", "screen_on_count", "screen_off_count", "duration", "energy", 55 "usage", "camera_id"], 56 "duration_type": ["background_time", "screen_on_time", "screen_off_time", "load", "uid", "usage", "charge", 57 "foreground_count", "background_count", "screen_on_count", "screen_off_count", "energy", "duration"], 58 "energy_type": ["background_time", "screen_on_time", "screen_off_time", "load", "charge", 59 "foreground_count", "background_count", "screen_on_count", "screen_off_count", "camera_id", "uid", 60 "foreground_duration", "foreground_energy", "background_duration", "background_energy", 61 "screen_on_duration", "screen_on_energy", "screen_off_duration", "screen_off_energy"], 62 "count_type": ["background_time", "screen_on_time", "screen_off_time", "load", "energy", "usage", 63 "foreground_duration", "background_duration", "screen_on_duration", "screen_off_duration", 64 "camera_id", "uid", "duration", "charge"] 65 } 66 } 67 68 queryDataByDB(val: SelectionParam | any) { 69 getTabPowerDetailsData(val.leftNs - val.leftNs, val.rightNs).then(items => { 70 log("getTabPowerDetailsData size :" + items.length); 71 let detailsData: Array<any> = [] 72 let set = new Set() 73 set.add("COUNT") 74 set.add("LOAD") 75 set.add("CHARGE") 76 set.add("CAMERA_ID") 77 78 let powerData: any = { 79 "POWER_IDE_CPU": new PowerDetailsEnergy("CPU"), 80 "POWER_IDE_LOCATION": new PowerDetailsEnergy("LOCATION"), 81 "POWER_IDE_GPU": new PowerDetailsEnergy("GPU"), 82 "POWER_IDE_DISPLAY": new PowerDetailsEnergy("DISPLAY"), 83 "POWER_IDE_CAMERA": new PowerDetailsEnergy("CAMERA"), 84 "POWER_IDE_BLUETOOTH": new PowerDetailsEnergy("BLUETOOTH"), 85 "POWER_IDE_FLASHLIGHT": new PowerDetailsEnergy("FLASHLIGHT"), 86 "POWER_IDE_AUDIO": new PowerDetailsEnergy("AUDIO"), 87 "POWER_IDE_WIFISCAN": new PowerDetailsEnergy("WIFISCAN") 88 }; 89 let tsMax = 0 90 let currentAppIndex = -1 91 items.forEach(item => { 92 let powerDatum: any = powerData[item.eventName]; 93 if (item.appKey.toLocaleLowerCase() === "appname") { 94 powerDatum['appName'] = SpHiSysEventChart.app_name 95 currentAppIndex = item.eventValue.split(",").indexOf(SpHiSysEventChart.app_name!); 96 tsMax = 0 97 } else if (currentAppIndex > -1) { 98 if (set.has(item.appKey)) { 99 if (item.startNS >= tsMax) { 100 powerDatum[item.appKey.toLocaleLowerCase()] = item.eventValue 101 tsMax = item.startNS 102 } 103 } else { 104 powerDatum[item.appKey.toLocaleLowerCase()] += parseInt(item.eventValue.split(",")[currentAppIndex]) 105 } 106 } 107 }) 108 109 let totalEnergy = powerData["POWER_IDE_CPU"].getTotalEnergy(false) 110 + powerData["POWER_IDE_LOCATION"].getTotalEnergy(false) 111 + powerData["POWER_IDE_GPU"].getTotalEnergy(true) 112 + powerData["POWER_IDE_DISPLAY"].getTotalEnergy(true) 113 + powerData["POWER_IDE_CAMERA"].getTotalEnergy(false) 114 + powerData["POWER_IDE_BLUETOOTH"].getTotalEnergy(false) 115 + powerData["POWER_IDE_FLASHLIGHT"].getTotalEnergy(false) 116 + powerData["POWER_IDE_AUDIO"].getTotalEnergy(false) 117 + powerData["POWER_IDE_WIFISCAN"].getTotalEnergy(false) 118 119 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_CPU", false, "time_type")) 120 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_LOCATION", false, "duration_type")) 121 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_GPU", true, "energy_type")) 122 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_DISPLAY", true, "energy_type")) 123 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_CAMERA", false, "duration_type")) 124 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_BLUETOOTH", false, "duration_type")) 125 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_FLASHLIGHT", false, "duration_type")) 126 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_AUDIO", false, "duration_type")) 127 detailsData.push(this.setEnergyItems(powerData, totalEnergy, "POWER_IDE_WIFISCAN", false, "count_type")) 128 129 if (detailsData.length > 0) { 130 this.source = detailsData 131 this.tbl!.recycleDataSource = detailsData 132 } else { 133 this.source = [] 134 this.tbl!.recycleDataSource = [] 135 } 136 this.tbl?.shadowRoot?.querySelectorAll<HTMLDivElement>(".td").forEach(td => { 137 td.style.fontSize = "14px" 138 td.style.fontWeight = "400" 139 td.style.opacity = '0.9' 140 td.style.lineHeight = "16px" 141 }) 142 }) 143 let th = this.tbl?.shadowRoot?.querySelector<HTMLDivElement>(".th") 144 if (th) { 145 th!.style.gridColumnGap = "5px"; 146 } 147 } 148 149 setEnergyItems(powerData: any, totalEnergy: number, energyName: string, isSimpleEnergy: boolean, type: any): any { 150 let ratio = powerData[energyName] 151 .getTotalEnergy(isSimpleEnergy) * 100 / totalEnergy 152 if (totalEnergy == 0) { 153 powerData[energyName].energyConsumptionRatio = "0.000 %" 154 } else { 155 powerData[energyName].energyConsumptionRatio = ratio.toFixed(3) + " %" 156 } 157 return this.getEnergyStyle(powerData, energyName, type) 158 } 159 160 getEnergyStyle(powerData: any, energyName: string, type: any) { 161 this.itemType[type].forEach((item: any) => { 162 powerData[energyName][item] = "-" 163 }) 164 if (type === "energy_type") { 165 if (energyName == "POWER_IDE_GPU") { 166 powerData[energyName]["duration"] = "-" 167 } else { 168 powerData[energyName]["usage"] = "-" 169 } 170 } else if (type === "duration_type") { 171 if (energyName != "POWER_IDE_CAMERA") { 172 powerData[energyName]["camera_id"] = "-" 173 } 174 } 175 return powerData[energyName] 176 } 177 178 initHtml(): string { 179 return ` 180 <style> 181 :host{ 182 display: flex; 183 flex-direction: column; 184 padding: 10px 10px; 185 } 186 187 </style> 188 <lit-table id="tb-power-details-energy" style="height: auto"> 189 <lit-table-column order width="100px" title="" data-index="event" key="event" align="flex-start" > 190 </lit-table-column> 191 <lit-table-column order width="60px" title="UId" data-index="uid" key="uid" align="flex-start" > 192 </lit-table-column> 193 <lit-table-column order width="80px" title="Charge" data-index="charge" key="charge" align="flex-start" > 194 </lit-table-column> 195 <lit-table-column order width="180px" title="Foreground Duration" data-index="foreground_duration" key="foreground_duration" align="flex-start" > 196 </lit-table-column> 197 <lit-table-column order width="180px" title="Foreground Energy" data-index="foreground_energy" key="foreground_energy" align="flex-start" > 198 </lit-table-column> 199 <lit-table-column order width="180px" title="Background Duration" data-index="background_duration" key="background_duration" align="flex-start" > 200 </lit-table-column> 201 <lit-table-column order width="180px" title="Background Energy" data-index="background_energy" key="background_energy" align="flex-start" > 202 </lit-table-column> 203 <lit-table-column order width="180px" title="Screen On Duration" data-index="screen_on_duration" key="screen_on_duration" align="flex-start" > 204 </lit-table-column> 205 <lit-table-column order width="180px" title="Screen On Energy" data-index="screen_on_energy" key="screen_on_energy" align="flex-start" > 206 </lit-table-column> 207 <lit-table-column order width="180px" title="Screen Off Duration" data-index="screen_off_duration" key="screen_off_duration" align="flex-start" > 208 </lit-table-column> 209 <lit-table-column order width="180px" title="Screen Off Energy" data-index="screen_off_energy" key="screen_off_energy" align="flex-start" > 210 </lit-table-column> 211 <lit-table-column order width="180px" title="Foreground Count" data-index="foreground_count" key="foreground_count" align="flex-start" > 212 </lit-table-column> 213 <lit-table-column order width="180px" title="Background Count" data-index="background_count" key="background_count" align="flex-start" > 214 </lit-table-column> 215 <lit-table-column order width="180px" title="Screen On Count" data-index="screen_on_count" key="screen_on_count" align="flex-start" > 216 </lit-table-column> 217 <lit-table-column order width="180px" title="Screen Off Count" data-index="screen_off_count" key="screen_off_count" align="flex-start" > 218 </lit-table-column> 219 <lit-table-column order width="180px" title="Background Time" data-index="background_time" key="background_time" align="flex-start" > 220 </lit-table-column> 221 <lit-table-column order width="180px" title="Screen On Time" data-index="screen_on_time" key="screen_on_time" align="flex-start" > 222 </lit-table-column> 223 <lit-table-column order width="180px" title="Screen Off Time" data-index="screen_off_time" key="screen_off_time" align="flex-start" > 224 </lit-table-column> 225 <lit-table-column order width="80px" title="Energy" data-index="energy" key="energy" align="flex-start" > 226 </lit-table-column> 227 <lit-table-column order width="80px" title="Load" data-index="load" key="load" align="flex-start" > 228 </lit-table-column> 229 <lit-table-column order width="80px" title="Usage" data-index="usage" key="usage" align="flex-start" > 230 </lit-table-column> 231 <lit-table-column order width="80px" title="Duration" data-index="duration" key="duration" align="flex-start" > 232 </lit-table-column> 233 <lit-table-column order width="100px" title="Camera Id" data-index="camera_id" key="camera_id" align="flex-start" > 234 </lit-table-column> 235 <lit-table-column order width="80px" title="Count" data-index="count" key="count" align="flex-start" > 236 </lit-table-column> 237 <lit-table-column order width="200px" title="energyPercent" data-index="energyConsumptionRatio" key="energyConsumptionRatio" align="flex-start" > 238 </lit-table-column> 239 </lit-table> 240 `; 241 } 242 243 sortByColumn(detail: any) { 244 // @ts-ignore 245 function compare(property, sort, type) { 246 return function (a: PowerDetailsEnergy, b: PowerDetailsEnergy) { 247 if (type === 'number') { 248 // @ts-ignore 249 return sort === 2 ? parseFloat(b[property] == "-" ? 0 : b[property]) - parseFloat(a[property] == "-" ? 0 : a[property]) : parseFloat(a[property] == "-" ? 0 : a[property]) - parseFloat(b[property] == "-" ? 0 : b[property]); 250 } else { 251 // @ts-ignore 252 if (b[property] > a[property]) { 253 return sort === 2 ? 1 : -1; 254 } else { // @ts-ignore 255 if (b[property] == a[property]) { 256 return 0; 257 } else { 258 return sort === 2 ? -1 : 1; 259 } 260 } 261 } 262 } 263 } 264 265 if (detail.key === 'appName') { 266 this.source.sort(compare(detail.key, detail.sort, 'string')) 267 } else { 268 this.source.sort(compare(detail.key, detail.sort, 'number')) 269 } 270 this.tbl!.recycleDataSource = this.source; 271 } 272} 273