• 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 { BaseStruct, isFrameContainPoint, drawLoadingFrame, ns2x, Render } from './ProcedureWorkerCommon';
17import { TraceRow } from '../../component/trace/base/TraceRow';
18
19export class EnergyStateRender extends Render {
20  renderMainThread(
21    req: {
22      useCache: boolean;
23      context: CanvasRenderingContext2D;
24      type: string;
25      maxState: number;
26      maxStateName: string;
27    },
28    row: TraceRow<EnergyStateStruct>
29  ) {
30    let stateList = row.dataList;
31    let stateFilter = row.dataListCache;
32    state(
33      stateList,
34      stateFilter,
35      TraceRow.range!.startNS || 0,
36      TraceRow.range!.endNS || 0,
37      TraceRow.range!.totalNS || 0,
38      row.frame,
39      req.useCache || !TraceRow.range!.refresh
40    );
41    drawLoadingFrame(req.context, row.dataListCache, row);
42    req.context.beginPath();
43    let find = false;
44    for (let i = 0; i < stateFilter.length; i++) {
45      let re = stateFilter[i];
46      EnergyStateStruct.draw(req.context, re, req.maxState, req.maxStateName);
47      if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) {
48        EnergyStateStruct.hoverEnergyStateStruct = re;
49        find = true;
50      }
51    }
52    if (!find && row.isHover) EnergyStateStruct.hoverEnergyStateStruct = undefined;
53    if (req.maxStateName != 'enable' && req.maxStateName != 'disable' && req.maxStateName != '-1') {
54      let s = req.maxStateName;
55      let textMetrics = req.context.measureText(s);
56      req.context.globalAlpha = 1.0;
57      req.context.fillStyle = '#f0f0f0';
58      req.context.fillRect(0, 5, textMetrics.width + 8, 18);
59      req.context.fillStyle = '#333';
60      req.context.textBaseline = 'middle';
61      req.context.fillText(s, 4, 5 + 9);
62    }
63    req.context.closePath();
64  }
65}
66
67export function state(
68  stateList: Array<any>,
69  res: Array<any>,
70  startNS: number,
71  endNS: number,
72  totalNS: number,
73  frame: any,
74  use: boolean
75) {
76  if (use && res.length > 0) {
77    for (let i = 0; i < res.length; i++) {
78      let stateItem = res[i];
79      if (i === res.length - 1) {
80        stateItem.dur = endNS - (stateItem.startNs || 0);
81      } else {
82        stateItem.dur = (res[i + 1].startNs || 0) - (stateItem.startNs || 0);
83      }
84      if ((stateItem.startNs || 0) + (stateItem.dur || 0) > startNS && (stateItem.startNs || 0) < endNS) {
85        EnergyStateStruct.setStateFrame(res[i], 5, startNS, endNS, totalNS, frame);
86      }
87    }
88    return;
89  }
90  res.length = 0;
91  stateFilter(stateList, startNS, endNS, totalNS, frame, res);
92}
93function stateFilter(
94  stateList: Array<any>,
95  startNS: number,
96  endNS: number,
97  totalNS: number,
98  frame: any,
99  res: Array<any>
100): void {
101  if (stateList) {
102    for (let index = 0; index < stateList.length; index++) {
103      let item = stateList[index];
104      item.dur =
105        index === stateList.length - 1
106          ? endNS - (item.startNs || 0)
107          : (stateList[index + 1].startNs || 0) - (item.startNs || 0);
108      if ((item.startNs || 0) + (item.dur || 0) > startNS && (item.startNs || 0) < endNS) {
109        EnergyStateStruct.setStateFrame(stateList[index], 5, startNS, endNS, totalNS, frame);
110        if (
111          !(
112            index > 0 &&
113            (stateList[index - 1].frame?.x || 0) == (stateList[index].frame?.x || 0) &&
114            (stateList[index - 1].frame?.width || 0) == (stateList[index].frame?.width || 0)
115          )
116        ) {
117          res.push(item);
118        }
119      }
120    }
121  }
122}
123
124export class EnergyStateStruct extends BaseStruct {
125  static maxState: number = 0;
126  static maxStateName: string = '0';
127  static hoverEnergyStateStruct: EnergyStateStruct | undefined;
128  static selectEnergyStateStruct: EnergyStateStruct | undefined;
129  type: string | undefined;
130  value: number | undefined;
131  startNs: number | undefined;
132  dur: number | undefined;
133
134  sensorType: number | undefined;
135  pkg_name: string | undefined;
136  deviceState: number | undefined;
137  deviceType: number | undefined;
138
139  static draw(
140    energyStateContext: CanvasRenderingContext2D,
141    data: EnergyStateStruct,
142    maxState: number,
143    maxStateName: string
144  ) {
145    if (data.frame) {
146      let width = data.frame.width || 0;
147      let drawColor = this.setDrawColor(data.type!);
148      energyStateContext.fillStyle = drawColor;
149      energyStateContext.strokeStyle = drawColor;
150      energyStateContext.globalAlpha = 1.0;
151      energyStateContext.lineWidth = 1;
152      let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0)) / maxState);
153      if (maxStateName === 'enable' || maxStateName === 'disable') {
154        if (data.value == 0) {
155          drawHeight = data.frame.height;
156          energyStateContext.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height);
157        }
158      } else {
159        energyStateContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight + 4, width, drawHeight);
160      }
161      if (data.startNs === EnergyStateStruct.hoverEnergyStateStruct?.startNs) {
162        let pointy = data.frame.y + data.frame.height + 4;
163        if (data.value == 0) {
164          pointy -= drawHeight;
165        }
166        energyStateContext.beginPath();
167        energyStateContext.arc(data.frame.x, pointy, 3, 0, 2 * Math.PI, true);
168        energyStateContext.fill();
169        energyStateContext.globalAlpha = 1.0;
170        energyStateContext.stroke();
171        energyStateContext.beginPath();
172        energyStateContext.moveTo(data.frame.x + 3, pointy);
173        energyStateContext.lineWidth = 3;
174        energyStateContext.lineTo(data.frame.x + width, pointy);
175        energyStateContext.stroke();
176      }
177    }
178    energyStateContext.globalAlpha = 1.0;
179    energyStateContext.lineWidth = 1;
180  }
181
182  static setStateFrame(stateNode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) {
183    let stateStartPointX: number, stateEndPointX: number;
184
185    if ((stateNode.startNs || 0) < startNS) {
186      stateStartPointX = 0;
187    } else {
188      stateStartPointX = ns2x(stateNode.startNs || 0, startNS, endNS, totalNS, frame);
189    }
190    if ((stateNode.startNs || 0) + (stateNode.dur || 0) > endNS) {
191      stateEndPointX = frame.width;
192    } else {
193      stateEndPointX = ns2x((stateNode.startNs || 0) + (stateNode.dur || 0), startNS, endNS, totalNS, frame);
194    }
195    let frameWidth: number = stateEndPointX - stateStartPointX <= 1 ? 1 : stateEndPointX - stateStartPointX;
196    if (!stateNode.frame) {
197      stateNode.frame = {};
198    }
199    stateNode.frame.x = Math.floor(stateStartPointX);
200    stateNode.frame.y = frame.y + padding;
201    stateNode.frame.width = Math.ceil(frameWidth);
202    stateNode.frame.height = Math.floor(frame.height - padding * 2);
203  }
204
205  static setDrawColor(eventType: string): string {
206    switch (eventType) {
207      case 'BRIGHTNESS_NIT':
208        return '#92D6CC';
209      case 'SIGNAL_LEVEL':
210        return '#61CFBE';
211      case 'WIFI_EVENT_RECEIVED':
212        return '#46B1E3';
213      case 'AUDIO_STREAM_CHANGE':
214        return '#ED6F21';
215      case 'WIFI_STATE':
216        return '#61CFBE';
217      case 'LOCATION_SWITCH_STATE':
218        return '#61CFBE';
219      case 'SENSOR_STATE':
220        return '#61CFBE';
221      default:
222        return '#61CFBE';
223    }
224  }
225}
226