1 /*
2 * Copyright (c) 2021-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
16 #include "entities/sensor_entity.h"
17
18 #include <cinttypes>
19
20 #include "battery_stats_service.h"
21 #include "stats_log.h"
22
23 namespace OHOS {
24 namespace PowerMgr {
25 namespace {
26 auto g_statsService = DelayedStatsSpSingleton<BatteryStatsService>::GetInstance();
27 }
28
SensorEntity()29 SensorEntity::SensorEntity()
30 {
31 consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR;
32 }
33
GetActiveTimeMs(int32_t uid,StatsUtils::StatsType statsType,int16_t level)34 int64_t SensorEntity::GetActiveTimeMs(int32_t uid, StatsUtils::StatsType statsType, int16_t level)
35 {
36 int64_t activeTimeMs = StatsUtils::DEFAULT_VALUE;
37 switch (statsType) {
38 case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON: {
39 auto gravityIter = gravityTimerMap_.find(uid);
40 if (gravityIter != gravityTimerMap_.end()) {
41 activeTimeMs = gravityIter->second->GetRunningTimeMs();
42 STATS_HILOGD(COMP_SVC, "Get gravity on time: %{public}" PRId64 "ms for uid: %{public}d",
43 activeTimeMs, uid);
44 break;
45 }
46 STATS_HILOGD(COMP_SVC, "Didn't find related timer for uid: %{public}d, return 0", uid);
47 break;
48 }
49 case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON: {
50 auto proximityIter = proximityTimerMap_.find(uid);
51 if (proximityIter != proximityTimerMap_.end()) {
52 activeTimeMs = proximityIter->second->GetRunningTimeMs();
53 STATS_HILOGD(COMP_SVC, "Get proximity on time: %{public}" PRId64 "ms for uid: %{public}d",
54 activeTimeMs, uid);
55 break;
56 }
57 STATS_HILOGD(COMP_SVC, "Didn't find related timer for uid: %{public}d, return 0", uid);
58 break;
59 }
60 default:
61 break;
62 }
63 return activeTimeMs;
64 }
65
CalculateGravity(int32_t uid)66 double SensorEntity::CalculateGravity(int32_t uid)
67 {
68 auto gravityOnAverageMa =
69 g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_SENSOR_GRAVITY);
70 auto gravityOnTimeMs = GetActiveTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON);
71 auto gravityOnPowerMah = gravityOnAverageMa * gravityOnTimeMs / StatsUtils::MS_IN_HOUR;
72 auto gravityIter = gravityPowerMap_.find(uid);
73 if (gravityIter != gravityPowerMap_.end()) {
74 STATS_HILOGD(COMP_SVC, "Update gravity on power consumption: %{public}lfmAh for uid: %{public}d",
75 gravityOnAverageMa, uid);
76 gravityIter->second = gravityOnPowerMah;
77 } else {
78 STATS_HILOGD(COMP_SVC, "Create gravity on power consumption: %{public}lfmAh for uid: %{public}d",
79 gravityOnAverageMa, uid);
80 gravityPowerMap_.insert(std::pair<int32_t, double>(uid, gravityOnPowerMah));
81 }
82 return gravityOnPowerMah;
83 }
84
CalculateProximity(int32_t uid)85 double SensorEntity::CalculateProximity(int32_t uid)
86 {
87 auto proximityOnAverageMa =
88 g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_SENSOR_PROXIMITY);
89 auto proximityOnTimeMs = GetActiveTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON);
90 auto proximityOnPowerMah = proximityOnAverageMa * proximityOnTimeMs / StatsUtils::MS_IN_HOUR;
91 auto proximityIter = proximityPowerMap_.find(uid);
92 if (proximityIter != proximityPowerMap_.end()) {
93 STATS_HILOGD(COMP_SVC, "Update proximity on power consumption: %{public}lfmAh for uid: %{public}d",
94 proximityOnAverageMa, uid);
95 proximityIter->second = proximityOnPowerMah;
96 } else {
97 STATS_HILOGD(COMP_SVC, "Create proximity on power consumption: %{public}lfmAh for uid: %{public}d",
98 proximityOnAverageMa, uid);
99 proximityPowerMap_.insert(std::pair<int32_t, double>(uid, proximityOnPowerMah));
100 }
101 return proximityOnPowerMah;
102 }
103
Calculate(int32_t uid)104 void SensorEntity::Calculate(int32_t uid)
105 {
106 auto gravityOnPowerMah = CalculateGravity(uid);
107 auto proximityOnPowerMah = CalculateProximity(uid);
108
109 double sensorTotalPowerMah = gravityOnPowerMah + proximityOnPowerMah;
110 auto sensorIter = sensorTotalPowerMap_.find(uid);
111 if (sensorIter != sensorTotalPowerMap_.end()) {
112 STATS_HILOGD(COMP_SVC, "Update sensor total power consumption: %{public}lfmAh for uid: %{public}d",
113 sensorTotalPowerMah, uid);
114 sensorIter->second = sensorTotalPowerMah;
115 } else {
116 STATS_HILOGD(COMP_SVC, "Create sensor total power consumption: %{public}lfmAh for uid: %{public}d",
117 sensorTotalPowerMah, uid);
118 sensorTotalPowerMap_.insert(std::pair<int32_t, double>(uid, sensorTotalPowerMah));
119 }
120 }
121
GetEntityPowerMah(int32_t uidOrUserId)122 double SensorEntity::GetEntityPowerMah(int32_t uidOrUserId)
123 {
124 double power = StatsUtils::DEFAULT_VALUE;
125 auto iter = sensorTotalPowerMap_.find(uidOrUserId);
126 if (iter != sensorTotalPowerMap_.end()) {
127 power = iter->second;
128 STATS_HILOGD(COMP_SVC, "Get app sensor power consumption: %{public}lfmAh for uid: %{public}d",
129 power, uidOrUserId);
130 } else {
131 STATS_HILOGD(COMP_SVC,
132 "No app sensor power consumption related to uid: %{public}d was found, return 0", uidOrUserId);
133 }
134 return power;
135 }
136
GetStatsPowerMah(StatsUtils::StatsType statsType,int32_t uid)137 double SensorEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid)
138 {
139 double power = StatsUtils::DEFAULT_VALUE;
140 if (statsType == StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON) {
141 auto gravityOnIter = gravityPowerMap_.find(uid);
142 if (gravityOnIter != gravityPowerMap_.end()) {
143 power = gravityOnIter->second;
144 STATS_HILOGD(COMP_SVC, "Get gravity on power consumption: %{public}lfmAh for uid: %{public}d",
145 power, uid);
146 } else {
147 STATS_HILOGD(COMP_SVC,
148 "No gravity on power consumption related to uid: %{public}d was found, return 0", uid);
149 }
150 } else if (statsType == StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON) {
151 auto proximityOnIter = proximityPowerMap_.find(uid);
152 if (proximityOnIter != proximityPowerMap_.end()) {
153 power = proximityOnIter->second;
154 STATS_HILOGD(COMP_SVC, "Get proximity on power consumption: %{public}lfmAh for uid: %{public}d",
155 power, uid);
156 } else {
157 STATS_HILOGD(COMP_SVC,
158 "No proximity on power consumption related to uid: %{public}d was found, return 0", uid);
159 }
160 }
161 return power;
162 }
163
GetOrCreateTimer(int32_t uid,StatsUtils::StatsType statsType,int16_t level)164 std::shared_ptr<StatsHelper::ActiveTimer> SensorEntity::GetOrCreateTimer(int32_t uid, StatsUtils::StatsType statsType,
165 int16_t level)
166 {
167 std::shared_ptr<StatsHelper::ActiveTimer> timer = nullptr;
168 switch (statsType) {
169 case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON: {
170 auto gravityOnIter = gravityTimerMap_.find(uid);
171 if (gravityOnIter != gravityTimerMap_.end()) {
172 STATS_HILOGD(COMP_SVC, "Get gravity on timer for uid: %{public}d", uid);
173 timer = gravityOnIter->second;
174 break;
175 }
176 STATS_HILOGD(COMP_SVC, "Create gravity on timer for uid: %{public}d", uid);
177 std::shared_ptr<StatsHelper::ActiveTimer> gravityTimer = std::make_shared<StatsHelper::ActiveTimer>();
178 gravityTimerMap_.insert(
179 std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(uid, gravityTimer));
180 timer = gravityTimer;
181 break;
182 }
183 case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON: {
184 auto proximityOnIter = proximityTimerMap_.find(uid);
185 if (proximityOnIter != proximityTimerMap_.end()) {
186 STATS_HILOGD(COMP_SVC, "Get proximity on timer for uid: %{public}d", uid);
187 timer = proximityOnIter->second;
188 break;
189 }
190 STATS_HILOGD(COMP_SVC, "Create proximity on timer for uid: %{public}d", uid);
191 std::shared_ptr<StatsHelper::ActiveTimer> proximityTimer = std::make_shared<StatsHelper::ActiveTimer>();
192 proximityTimerMap_.insert(
193 std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(uid, proximityTimer));
194 timer = proximityTimer;
195 break;
196 }
197 default:
198 STATS_HILOGW(COMP_SVC, "Create active timer failed");
199 break;
200 }
201 return timer;
202 }
203
Reset()204 void SensorEntity::Reset()
205 {
206 // Reset app sensor total power consumption
207 for (auto& iter : sensorTotalPowerMap_) {
208 iter.second = StatsUtils::DEFAULT_VALUE;
209 }
210
211 // Reset app gravity on total power consumption
212 for (auto& iter : gravityPowerMap_) {
213 iter.second = StatsUtils::DEFAULT_VALUE;
214 }
215
216 // Reset app proximity on total power consumption
217 for (auto& iter : proximityPowerMap_) {
218 iter.second = StatsUtils::DEFAULT_VALUE;
219 }
220
221 // Reset gravity on timer
222 for (auto& iter : gravityTimerMap_) {
223 if (iter.second) {
224 iter.second->Reset();
225 }
226 }
227
228 // Reset proximity on timer
229 for (auto& iter : proximityTimerMap_) {
230 if (iter.second) {
231 iter.second->Reset();
232 }
233 }
234 }
235 } // namespace PowerMgr
236 } // namespace OHOS