• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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<any> = [];
31  private itemType: any;
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) => {
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    this.itemType.time_type = this.getTimeTypeValue();
134    this.itemType.duration_type = this.getDurationTypeValue();
135    this.itemType.energy_type = this.getEnergyTypeValue();
136    this.itemType.count_type = this.getCountTypeValue();
137  }
138
139  getPowerData() {
140    return {
141      POWER_IDE_CPU: new PowerDetailsEnergy('CPU'),
142      POWER_IDE_LOCATION: new PowerDetailsEnergy('LOCATION'),
143      POWER_IDE_GPU: new PowerDetailsEnergy('GPU'),
144      POWER_IDE_DISPLAY: new PowerDetailsEnergy('DISPLAY'),
145      POWER_IDE_CAMERA: new PowerDetailsEnergy('CAMERA'),
146      POWER_IDE_BLUETOOTH: new PowerDetailsEnergy('BLUETOOTH'),
147      POWER_IDE_FLASHLIGHT: new PowerDetailsEnergy('FLASHLIGHT'),
148      POWER_IDE_AUDIO: new PowerDetailsEnergy('AUDIO'),
149      POWER_IDE_WIFISCAN: new PowerDetailsEnergy('WIFISCAN'),
150    };
151  }
152
153  getTotalEnergy(powerData: any) {
154    return powerData.POWER_IDE_CPU.getTotalEnergy(false) +
155      powerData.POWER_IDE_LOCATION.getTotalEnergy(false) +
156      powerData.POWER_IDE_GPU.getTotalEnergy(true) +
157      powerData.POWER_IDE_DISPLAY.getTotalEnergy(true) +
158      powerData.POWER_IDE_CAMERA.getTotalEnergy(false) +
159      powerData.POWER_IDE_BLUETOOTH.getTotalEnergy(false) +
160      powerData.POWER_IDE_FLASHLIGHT.getTotalEnergy(false) +
161      powerData.POWER_IDE_AUDIO.getTotalEnergy(false) +
162      powerData.POWER_IDE_WIFISCAN.getTotalEnergy(false);
163  }
164
165  queryDataByDB(val: SelectionParam | any): void {
166    getTabPowerDetailsData(val.leftNs - val.leftNs, val.rightNs).then((items) => {
167      log('getTabPowerDetailsData size :' + items.length);
168      let detailsData: Array<any> = [];
169      let set = new Set();
170      set.add('COUNT');
171      set.add('LOAD');
172      set.add('CHARGE');
173      set.add('CAMERA_ID');
174      let powerData: any = this.getPowerData();
175      let tsMax = 0;
176      let currentAppIndex = -1;
177      items.forEach((item) => {
178        let powerDatum: any = powerData[item.eventName];
179        if (item.appKey.toLocaleLowerCase() === 'appname') {
180          powerDatum.appName = SpHiSysEnergyChart.app_name;
181          currentAppIndex = item.eventValue.split(',').indexOf(SpHiSysEnergyChart.app_name!);
182          tsMax = 0;
183        } else if (currentAppIndex > -1 && (set.has(item.appKey) ? item.startNS >= tsMax : true)) {
184          if (set.has(item.appKey)) {
185            powerDatum[item.appKey.toLocaleLowerCase()] = item.startNS >= tsMax ? (tsMax = item.startNS , item.eventValue) : powerDatum[item.appKey.toLocaleLowerCase()];
186          } else {
187            powerDatum[item.appKey.toLocaleLowerCase()] = (powerDatum[item.appKey.toLocaleLowerCase()] || 0) + parseInt(item.eventValue.split(',')[currentAppIndex]);
188          }
189        }
190      });
191      let totalEnergy = this.getTotalEnergy(powerData);
192      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_CPU', false, 'time_type'));
193      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_LOCATION', false, 'duration_type'));
194      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_GPU', true, 'energy_type'));
195      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_DISPLAY', true, 'energy_type'));
196      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_CAMERA', false, 'duration_type'));
197      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_BLUETOOTH', false, 'duration_type'));
198      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_FLASHLIGHT', false, 'duration_type'));
199      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_AUDIO', false, 'duration_type'));
200      detailsData.push(this.setEnergyItems(powerData, totalEnergy, 'POWER_IDE_WIFISCAN', false, 'count_type'));
201      if (detailsData.length > 0) {
202        this.sourcePowerDetails = detailsData;
203        this.tblPowerDetails!.recycleDataSource = detailsData;
204      } else {
205        this.sourcePowerDetails = [];
206        this.tblPowerDetails!.recycleDataSource = [];
207      }
208      this.updateTableStyles();
209    });
210    let th = this.tblPowerDetails?.shadowRoot?.querySelector<HTMLDivElement>('.th');
211    if (th) {
212      th!.style.gridColumnGap = '5px';
213    }
214  }
215
216  updateTableStyles() {
217    this.tblPowerDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td) => {
218      td.style.fontSize = '14px';
219      td.style.fontWeight = '400';
220      td.style.opacity = '0.9';
221      td.style.lineHeight = '16px';
222    });
223  }
224
225  setEnergyItems(powerData: any, totalEnergy: number, energyName: string, isSimpleEnergy: boolean, type: any): any {
226    let ratio = (powerData[energyName].getTotalEnergy(isSimpleEnergy) * NUM_100) / totalEnergy;
227    if (totalEnergy === 0) {
228      powerData[energyName].energyConsumptionRatio = '0.000 %';
229    } else {
230      powerData[energyName].energyConsumptionRatio = ratio.toFixed(NUM_3) + ' %';
231    }
232    return this.getEnergyStyle(powerData, energyName, type);
233  }
234
235  getEnergyStyle(powerData: any, energyName: string, type: any) {
236    this.itemType[type].forEach((item: any) => {
237      powerData[energyName][item] = '-';
238    });
239    if (type === 'energy_type') {
240      if (energyName === 'POWER_IDE_GPU') {
241        powerData[energyName]['duration'] = '-';
242      } else {
243        powerData[energyName]['usage'] = '-';
244      }
245    } else if (type === 'duration_type') {
246      if (energyName !== 'POWER_IDE_CAMERA') {
247        powerData[energyName]['camera_id'] = '-';
248      }
249    }
250    return powerData[energyName];
251  }
252
253  initHtml(): string {
254    return TabPanePowerDetailsHTML;
255  }
256
257  sortByColumn(detail: any): void {
258    // @ts-ignore
259    function compare(property, sort, type) {
260      return function (aPowerDetails: PowerDetailsEnergy, bPowerDetails: PowerDetailsEnergy) {
261        if (type === 'number') {
262          return sort === 2
263            ? // @ts-ignore
264            parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]) -
265            // @ts-ignore
266            parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property])
267            : // @ts-ignore
268            parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property]) -
269            // @ts-ignore
270            parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]);
271        } else {
272          // @ts-ignore
273          if (bPowerDetails[property] > aPowerDetails[property]) {
274            return sort === 2 ? 1 : -1;
275          } else {
276            // @ts-ignore
277            if (bPowerDetails[property] === aPowerDetails[property]) {
278              return 0;
279            } else {
280              return sort === 2 ? -1 : 1;
281            }
282          }
283        }
284      };
285    }
286
287    if (detail.key === 'appName') {
288      this.sourcePowerDetails.sort(compare(detail.key, detail.sort, 'string'));
289    } else {
290      this.sourcePowerDetails.sort(compare(detail.key, detail.sort, 'number'));
291    }
292    this.tblPowerDetails!.recycleDataSource = this.sourcePowerDetails;
293
294    this.tblPowerDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td) => {
295      td.style.fontSize = '14px';
296      td.style.fontWeight = '400';
297      td.style.opacity = '0.9';
298      td.style.lineHeight = '16px';
299    });
300  }
301}
302