• 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 { TraficEnum } from './utils/QueryEnum';
17import { energyList } from './utils/AllMemoryCache';
18import { Args } from './CommonArgs';
19
20export const systemDataSql = (args: Args): string => {
21  return `SELECT S.id,
22                 S.ts - ${
23                   args.recordStartNS
24                 }                                                                   AS startNs,
25                 D.data                                                                                         AS eventName,
26                 (case when D.data = 'POWER_RUNNINGLOCK' then 1 when D.data = 'GNSS_STATE' then 2 else 0 end) AS appKey,
27                 contents                                                                                       AS eventValue,
28                 ((S.ts - ${args.recordStartNS}) / (${Math.floor((args.endNS - args.startNS) / args.width)}))   as px
29          FROM hisys_all_event AS S
30                   LEFT JOIN data_dict AS D ON S.event_name_id = D.id
31                   LEFT JOIN data_dict AS D2 ON S.domain_id = D2.id
32          WHERE eventName IN ('POWER_RUNNINGLOCK', 'GNSS_STATE', 'WORK_START', 'WORK_REMOVE', 'WORK_STOP', 'WORK_ADD')
33            and startNs >= ${Math.floor(args.startNS)}
34            and startNs <= ${Math.floor(args.endNS)}
35          group by px;`;
36};
37
38export const systemDataMemSql = (args: Args): string => {
39  return `SELECT S.id,
40                 S.ts - ${args.recordStartNS}                                                                         AS startNs,
41                 D.data                                                                                               AS eventName,
42                 (case when D.data = 'POWER_RUNNINGLOCK' then '1' when D.data = 'GNSS_STATE' then '2' else '0' end) AS appKey,
43                 contents                                                                                             AS eventValue
44          FROM hisys_all_event AS S
45                   LEFT JOIN data_dict AS D ON S.event_name_id = D.id
46                   LEFT JOIN data_dict AS D2 ON S.domain_id = D2.id
47          WHERE eventName IN
48                ('POWER_RUNNINGLOCK', 'GNSS_STATE', 'WORK_START', 'WORK_REMOVE', 'WORK_STOP', 'WORK_ADD');`;
49};
50
51export const chartEnergyAnomalyDataSql = (args: Args): string => {
52  return `
53      select S.id,
54             S.ts - ${args.recordStartNS}                  as startNs,
55             D.data                                        as eventName,
56             D2.data                                       as appKey,
57             (case
58                  when S.type==1 then group_concat(S.string_value, ',')
59                  else group_concat(S.int_value, ',') end) as eventValue
60      from hisys_event_measure as S
61               left join data_dict as D
62                         on D.id = S.name_id
63               left join app_name as APP on APP.id = S.key_id
64               left join data_dict as D2 on D2.id = APP.app_key
65      where D.data in
66            ('ANOMALY_SCREEN_OFF_ENERGY', 'ANOMALY_KERNEL_WAKELOCK', 'ANOMALY_CPU_HIGH_FREQUENCY', 'ANOMALY_WAKEUP')
67         or (D.data in ('ANOMALY_RUNNINGLOCK', 'ANORMALY_APP_ENERGY', 'ANOMALY_GNSS_ENERGY', 'ANOMALY_CPU_ENERGY',
68                        'ANOMALY_ALARM_WAKEUP')
69          and D2.data in ('APPNAME'))
70      group by S.serial, D.data`;
71};
72export const queryPowerValueSql = (args: Args): string => {
73  return `
74      SELECT S.id,
75             S.ts - ${args.recordStartNS}                                                        as startNs,
76             D.data                                                                              AS eventName,
77             D2.data                                                                             AS appKey,
78             group_concat((CASE WHEN S.type = 1 THEN S.string_value ELSE S.int_value END), ',') AS eventValue
79      FROM hisys_event_measure AS S
80               LEFT JOIN data_dict AS D
81                         ON D.id = S.name_id
82               LEFT JOIN app_name AS APP
83                         ON APP.id = S.key_id
84               LEFT JOIN data_dict AS D2
85                         ON D2.id = APP.app_key
86      where D.data in ('POWER_IDE_CPU', 'POWER_IDE_LOCATION', 'POWER_IDE_GPU', 'POWER_IDE_DISPLAY', 'POWER_IDE_CAMERA',
87                       'POWER_IDE_BLUETOOTH', 'POWER_IDE_FLASHLIGHT', 'POWER_IDE_AUDIO', 'POWER_IDE_WIFISCAN')
88        and D2.data in
89            ('BACKGROUND_ENERGY', 'FOREGROUND_ENERGY', 'SCREEN_ON_ENERGY', 'SCREEN_OFF_ENERGY', 'ENERGY', 'APPNAME')
90      GROUP BY S.serial,
91               APP.app_key,
92               D.data,
93               D2.data
94      ORDER BY eventName;`;
95};
96
97export const queryStateDataSql = (args: Args): string => {
98  return `
99      select S.id,
100             S.ts - ${args.recordStartNS} as startNs,
101             D.data                       as eventName,
102             D2.data                      as appKey,
103             S.int_value                  as eventValue
104      from hisys_event_measure as S
105               left join data_dict as D on D.id = S.name_id
106               left join app_name as APP on APP.id = S.key_id
107               left join data_dict as D2 on D2.id = APP.app_key
108      where (case when 'SENSOR_STATE'== '${args.eventName}' then D.data like '%SENSOR%' else D.data = '${args.eventName}' end)
109        and D2.data in ('BRIGHTNESS', 'STATE', 'VALUE', 'LEVEL', 'VOLUME', 'OPER_TYPE', 'VOLUME')
110      group by S.serial, APP.app_key, D.data, D2.data;`;
111};
112
113export const queryStateProtoDataSql = (args: Args): string => {
114  return `
115      SELECT S.id,
116             S.ts - ${args.recordStartNS} AS startNs,
117             D.data                       AS eventName,
118             ''                           AS appKey,
119             contents                     AS eventValue
120      FROM hisys_all_event AS S
121               LEFT JOIN data_dict AS D ON S.event_name_id = D.id
122               LEFT JOIN data_dict AS D2 ON S.domain_id = D2.id
123      WHERE eventName = ${args.eventName}`;
124};
125let systemList: Array<unknown> = [];
126let anomalyList: Array<unknown> = [];
127let powerList: Array<unknown> = [];
128
129export function resetEnergyEvent(): void {
130  systemList = [];
131  anomalyList = [];
132  powerList = [];
133}
134
135export function energySysEventReceiver(data: unknown, proc: Function): void {
136  // @ts-ignore
137  if (data.params.trafic === TraficEnum.Memory) {
138    if (systemList.length === 0) {
139      // @ts-ignore
140      systemList = proc(systemDataMemSql(data.params));
141    }
142    // @ts-ignore
143    systemBufferHandler(data, systemList, data.params.trafic !== TraficEnum.SharedArrayBuffer);
144    // @ts-ignore
145  } else if (data.params.trafic === TraficEnum.ProtoBuffer) {
146    // @ts-ignore
147    let sql = systemDataSql(data.params);
148    let res = proc(sql);
149    // @ts-ignore
150    systemBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
151  }
152}
153
154export function hiSysEnergyAnomalyDataReceiver(data: unknown, proc: Function): void {
155  // @ts-ignore
156  if (data.params.trafic === TraficEnum.Memory) {
157    if (anomalyList.length === 0) {
158      // @ts-ignore
159      anomalyList = proc(chartEnergyAnomalyDataSql(data.params));
160    }
161    // @ts-ignore
162    anomalyBufferHandler(data, anomalyList, data.params.trafic !== TraficEnum.SharedArrayBuffer);
163    // @ts-ignore
164  } else if (data.params.trafic === TraficEnum.ProtoBuffer) {
165    // @ts-ignore
166    let sql = chartEnergyAnomalyDataSql(data.params);
167    let res = proc(sql);
168    // @ts-ignore
169    anomalyBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
170  }
171}
172
173export function hiSysEnergyPowerReceiver(data: unknown, proc: Function): void {
174  // @ts-ignore
175  if (data.params.trafic === TraficEnum.Memory) {
176    if (powerList.length === 0) {
177      // @ts-ignore
178      powerList = proc(queryPowerValueSql(data.params));
179    }
180    // @ts-ignore
181    powerBufferHandler(data, powerList, data.params.trafic !== TraficEnum.SharedArrayBuffer);
182    // @ts-ignore
183  } else if (data.params.trafic === TraficEnum.ProtoBuffer) {
184    // @ts-ignore
185    let sql = queryPowerValueSql(data.params);
186    let res = proc(sql);
187    // @ts-ignore
188    powerBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
189  }
190}
191
192export function hiSysEnergyStateReceiver(data: unknown, proc: Function): void {
193  // @ts-ignore
194  if (data.params.trafic === TraficEnum.Memory) {
195    let res: unknown[];
196    let list: unknown[];
197    // @ts-ignore
198    if (!energyList.has(data.params.eventName)) {
199      // @ts-ignore
200      list = proc(queryStateDataSql(data.params));
201      // @ts-ignore
202      energyList.set(data.params.eventName, list);
203    } else {
204      // @ts-ignore
205      list = energyList.get(data.params.eventName) || [];
206    }
207    res = list;
208    // @ts-ignore
209    stateBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer);
210    // @ts-ignore
211  } else if (data.params.trafic === TraficEnum.ProtoBuffer) {
212    // @ts-ignore
213    let stateDataSql = queryStateDataSql(data.params);
214    let stateDataRes = proc(stateDataSql);
215    // @ts-ignore
216    stateBufferHandler(data, stateDataRes, data.params.trafic !== TraficEnum.SharedArrayBuffer);
217  }
218}
219
220function systemBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
221  let hiSysEnergy = new HiSysEnergy(data, res, transfer);
222  let systemDataList: unknown = [];
223  let workCountMap: Map<string, number> = new Map<string, number>();
224  let nameIdMap: Map<string, Array<unknown>> = new Map<string, []>();
225  res.forEach((it, index) => {
226    // @ts-ignore
227    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.energyData);
228    // @ts-ignore
229    let parsedData = it.eventValue;
230    // @ts-ignore
231    if (typeof it.eventValue === 'string') {
232      try {
233        // @ts-ignore
234        parsedData = JSON.parse(it.eventValue);
235      } catch (error) {}
236    }
237    // @ts-ignore
238    it.eventValue = parsedData;
239    let beanData: unknown = {};
240    // @ts-ignore
241    if (it.appKey === '1') {
242      // @ts-ignore
243      eventNameWithPowerRunninglock(beanData, it, systemDataList);
244      // @ts-ignore
245    } else if (it.appKey === '2') {
246      // @ts-ignore
247      eventNameWithGnssState(beanData, it, systemDataList);
248    } else {
249      // @ts-ignore
250      beanData.dataType = 3;
251      // @ts-ignore
252      if (it.eventValue.NAME) {
253        // @ts-ignore
254        beanData.appName = it.NAME;
255      }
256      // @ts-ignore
257      if (it.eventValue.WORKID) {
258        // @ts-ignore
259        beanData.workId = it.WORKID;
260      }
261      // @ts-ignore
262      if (it.eventName === 'WORK_START') {
263        // @ts-ignore
264        eventNameWithWorkStart(nameIdMap, beanData, workCountMap, it, systemDataList);
265        // @ts-ignore
266      } else if (it.eventName === 'WORK_STOP') {
267        // @ts-ignore
268        eventNameWithWorkStop(nameIdMap, beanData, workCountMap, it, systemDataList);
269      }
270    }
271    // @ts-ignore
272    hiSysEnergy.id[index] = beanData.id;
273    // @ts-ignore
274    hiSysEnergy.startNs[index] = beanData.startNs;
275    // @ts-ignore
276    hiSysEnergy.count[index] = beanData.count;
277    // @ts-ignore
278    hiSysEnergy.type[index] = beanData.dataType;
279    // @ts-ignore
280    hiSysEnergy.token[index] = beanData.token;
281    // @ts-ignore
282    hiSysEnergy.dataType[index] = beanData.dataType;
283  });
284  postMessage(data, transfer, hiSysEnergy, res.length);
285}
286
287function eventNameWithPowerRunninglock(beanData: unknown, it: unknown, systemDataList: Array<unknown>): void {
288  let lockCount = 0;
289  let tokedIds: Array<string> = [];
290  // @ts-ignore
291  beanData.dataType = 1;
292  // @ts-ignore
293  if (it.eventValue.TAG.endsWith('_ADD')) {
294    // @ts-ignore
295    beanData.startNs = it.startNs;
296    lockCount++;
297    // @ts-ignore
298    beanData.id = it.id;
299    // @ts-ignore
300    beanData.count = lockCount;
301    // @ts-ignore
302    beanData.token = it.eventValue.MESSAGE.split('=')[1];
303    // @ts-ignore
304    beanData.type = 1;
305    // @ts-ignore
306    tokedIds.push(beanData.token);
307    systemDataList.push(beanData);
308  } else {
309    // @ts-ignore
310    beanData.id = it.id;
311    // @ts-ignore
312    beanData.startNs = it.startNs;
313    // @ts-ignore
314    let toked = it.eventValue.MESSAGE.split('=')[1];
315    let number = tokedIds.indexOf(toked);
316    if (number > -1) {
317      lockCount--;
318      // @ts-ignore
319      beanData.count = lockCount;
320      // @ts-ignore
321      beanData.token = it.eventValue.MESSAGE.split('=')[1];
322      // @ts-ignore
323      beanData.type = 1;
324      systemDataList.push(beanData);
325      tokedIds.splice(number);
326    }
327  }
328}
329
330function eventNameWithGnssState(beanData: unknown, it: unknown, systemDataList: Array<unknown>): void {
331  let locationIndex = -1;
332  let locationCount = 0;
333  // @ts-ignore
334  beanData.dataType = 2;
335  // @ts-ignore
336  if (it.eventValue.STATE === 'stop') {
337    if (locationIndex === -1) {
338      // @ts-ignore
339      beanData.startNs = 0;
340      // @ts-ignore
341      beanData.count = 1;
342    } else {
343      // @ts-ignore
344      beanData.startNs = it.startNs;
345      locationCount--;
346      // @ts-ignore
347      beanData.count = locationCount;
348    }
349    // @ts-ignore
350    beanData.state = 'stop';
351  } else {
352    // @ts-ignore
353    beanData.startNs = it.startNs;
354    locationCount++;
355    // @ts-ignore
356    beanData.count = locationCount;
357    // @ts-ignore
358    beanData.state = 'start';
359  }
360  locationIndex = 0;
361  // @ts-ignore
362  beanData.type = 2;
363  systemDataList.push(beanData);
364}
365
366function eventNameWithWorkStart(
367  nameIdMap: Map<string, Array<unknown>>,
368  beanData: unknown,
369  workCountMap: Map<string, number>,
370  it: unknown,
371  systemDataList: Array<unknown>
372): void {
373  // @ts-ignore
374  let nameIdList = nameIdMap.get(beanData.appName);
375  let workCount = 0;
376  if (nameIdList === undefined) {
377    workCount = 1;
378    // @ts-ignore
379    nameIdMap.set(beanData.appName, [beanData.workId]);
380  } else {
381    // @ts-ignore
382    nameIdList.push(beanData.workId);
383    workCount = nameIdList.length;
384  }
385  // @ts-ignore
386  let count = workCountMap.get(beanData.appName);
387  if (count === undefined) {
388    // @ts-ignore
389    workCountMap.set(beanData.appName, 1);
390  } else {
391    // @ts-ignore
392    workCountMap.set(beanData.appName, count + 1);
393  }
394  // @ts-ignore
395  beanData.startNs = it.startNs;
396  // @ts-ignore
397  beanData.count = workCount;
398  // @ts-ignore
399  beanData.type = 0;
400  systemDataList.push(beanData);
401}
402
403function eventNameWithWorkStop(
404  nameIdMap: Map<string, Array<unknown>>,
405  beanData: unknown,
406  workCountMap: Map<string, number>,
407  it: unknown,
408  systemDataList: Array<unknown>
409): void {
410  // @ts-ignore
411  let nameIdList: unknown = nameIdMap.get(beanData.appName);
412  // @ts-ignore
413  let index = nameIdList.indexOf(beanData.workId);
414  if (nameIdList !== undefined && index > -1) {
415    // @ts-ignore
416    nameIdList.splice(index);
417    // @ts-ignore
418    let workCount = workCountMap.get(beanData.appName);
419    if (workCount !== undefined) {
420      workCount = workCount - 1;
421      // @ts-ignore
422      workCountMap.set(beanData.appName, workCount);
423      // @ts-ignore
424      beanData.startNs = it.startNs;
425      // @ts-ignore
426      beanData.count = workCount;
427      // @ts-ignore
428      beanData.type = 0;
429      systemDataList.push(beanData);
430    }
431  }
432}
433
434function postMessage(data: unknown, transfer: boolean, hiSysEnergy: HiSysEnergy, len: number): void {
435  (self as unknown as Worker).postMessage(
436    {
437      // @ts-ignore
438      id: data.id,
439      // @ts-ignore
440      action: data.action,
441      results: transfer
442        ? {
443            id: hiSysEnergy.id.buffer,
444            startNs: hiSysEnergy.startNs.buffer,
445            count: hiSysEnergy.count.buffer,
446            type: hiSysEnergy.type.buffer,
447            token: hiSysEnergy.token.buffer,
448            dataType: hiSysEnergy.dataType.buffer,
449          }
450        : {},
451      len: len,
452      transfer: transfer,
453    },
454    transfer
455      ? [
456          hiSysEnergy.id.buffer,
457          hiSysEnergy.startNs.buffer,
458          hiSysEnergy.count.buffer,
459          hiSysEnergy.type.buffer,
460          hiSysEnergy.token.buffer,
461          hiSysEnergy.dataType.buffer,
462        ]
463      : []
464  );
465}
466
467class HiSysEnergy {
468  id: Uint16Array;
469  startNs: Float64Array;
470  count: Uint32Array;
471  type: Uint32Array;
472  token: Float64Array;
473  dataType: Uint16Array;
474
475  constructor(data: unknown, res: unknown[], transfer: boolean) {
476    // @ts-ignore
477    this.id = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.id);
478    // @ts-ignore
479    this.startNs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNs);
480    // @ts-ignore
481    this.count = new Uint32Array(transfer ? res.length : data.params.sharedArrayBuffers.count);
482    // @ts-ignore
483    this.type = new Uint32Array(transfer ? res.length : data.params.sharedArrayBuffers.type);
484    // @ts-ignore
485    this.token = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.token);
486    // @ts-ignore
487    this.dataType = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.dataType);
488  }
489}
490
491function anomalyBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
492  // @ts-ignore
493  let id = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.id);
494  // @ts-ignore
495  let startNs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNs);
496  res.forEach((it, index) => {
497    // @ts-ignore
498    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.energyData);
499    // @ts-ignore
500    id[index] = it.id;
501    // @ts-ignore
502    startNs[index] = it.startNs;
503  });
504  (self as unknown as Worker).postMessage(
505    {
506      // @ts-ignore
507      id: data.id,
508      // @ts-ignore
509      action: data.action,
510      results: transfer
511        ? {
512            id: id.buffer,
513            startNs: startNs.buffer,
514          }
515        : {},
516      len: res.length,
517      transfer: transfer,
518    },
519    transfer ? [startNs.buffer, id.buffer] : []
520  );
521}
522
523function powerBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
524  // @ts-ignore
525  let id = new Uint32Array(transfer ? res.length : data.params.sharedArrayBuffers.id);
526  // @ts-ignore
527  let startNs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNs);
528  res.forEach((it, index) => {
529    // @ts-ignore
530    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.energyData);
531    // @ts-ignore
532    id[index] = it.id;
533    // @ts-ignore
534    startNs[index] = it.startNs;
535  });
536  (self as unknown as Worker).postMessage(
537    {
538      // @ts-ignore
539      id: data.id,
540      // @ts-ignore
541      action: data.action,
542      results: transfer
543        ? {
544            id: id.buffer,
545            startNs: startNs.buffer,
546          }
547        : {},
548      len: res.length,
549      transfer: transfer,
550    },
551    transfer ? [id.buffer, startNs.buffer] : []
552  );
553}
554
555function stateBufferHandler(data: unknown, res: unknown[], transfer: boolean): void {
556  // @ts-ignore
557  let startNs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNs);
558  // @ts-ignore
559  let eventValue = new Float32Array(transfer ? res.length : data.params.sharedArrayBuffers.eventValue);
560  // @ts-ignore
561  let id = new Uint32Array(transfer ? res.length : data.params.sharedArrayBuffers.id);
562  res.forEach((it, index) => {
563    // @ts-ignore
564    data.params.trafic === TraficEnum.ProtoBuffer && (it = it.energyData);
565    // @ts-ignore
566    id[index] = it.id;
567    // @ts-ignore
568    startNs[index] = it.startNs;
569    // @ts-ignore
570    let eventName = it.eventName.toLocaleLowerCase();
571    if (eventName.includes('sensor')) {
572      if (eventName.includes('enable')) {
573        eventValue[index] = 0;
574      } else {
575        eventValue[index] = 1;
576      }
577    } else {
578      // @ts-ignore
579      eventValue[index] = it.eventValue;
580    }
581  });
582  (self as unknown as Worker).postMessage(
583    {
584      // @ts-ignore
585      id: data.id,
586      // @ts-ignore
587      action: data.action,
588      results: transfer
589        ? {
590            id: id.buffer,
591            startNs: startNs.buffer,
592            eventValue: eventValue.buffer,
593          }
594        : {},
595      len: res.length,
596      transfer: transfer,
597    },
598    transfer ? [id.buffer, startNs.buffer, eventValue.buffer] : []
599  );
600}
601