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/uid_entity.h" 17 18#ifdef SYS_MGR_CLIENT_ENABLE 19#include <bundle_constants.h> 20#include <bundle_mgr_interface.h> 21#include <ipc_skeleton.h> 22#include <system_ability_definition.h> 23#include <sys_mgr_client.h> 24#endif 25 26#include <ohos_account_kits_impl.h> 27#include "battery_stats_service.h" 28#include "stats_log.h" 29 30namespace OHOS { 31namespace PowerMgr { 32namespace { 33} 34 35UidEntity::UidEntity() 36{ 37 consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_APP; 38} 39 40void UidEntity::UpdateUidMap(int32_t uid) 41{ 42 std::lock_guard<std::mutex> lock(uidEntityMutex_); 43 if (uid > StatsUtils::INVALID_VALUE) { 44 auto iter = uidPowerMap_.find(uid); 45 if (iter != uidPowerMap_.end()) { 46 STATS_HILOGD(COMP_SVC, "Uid has already been added, ignore"); 47 } else { 48 STATS_HILOGD(COMP_SVC, "Update %{public}d to uid power map", uid); 49 uidPowerMap_.insert(std::pair<int32_t, double>(uid, StatsUtils::DEFAULT_VALUE)); 50 } 51 } 52} 53 54std::vector<int32_t> UidEntity::GetUids() 55{ 56 std::lock_guard<std::mutex> lock(uidEntityMutex_); 57 std::vector<int32_t> uids; 58 std::transform(uidPowerMap_.begin(), uidPowerMap_.end(), std::back_inserter(uids), [](const auto& item) { 59 return item.first; 60 }); 61 return uids; 62} 63 64double UidEntity::CalculateForConnectivity(int32_t uid) 65{ 66 double power = StatsUtils::DEFAULT_VALUE; 67 auto bss = BatteryStatsService::GetInstance(); 68 auto core = bss->GetBatteryStatsCore(); 69 auto bluetoothEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH); 70 71 // Calculate bluetooth power consumption 72 bluetoothEntity->Calculate(uid); 73 power += bluetoothEntity->GetEntityPowerMah(uid); 74 STATS_HILOGD(COMP_SVC, "Connectivity power consumption: %{public}lfmAh for uid: %{public}d", power, uid); 75 return power; 76} 77 78double UidEntity::CalculateForCommon(int32_t uid) 79{ 80 double power = StatsUtils::DEFAULT_VALUE; 81 auto bss = BatteryStatsService::GetInstance(); 82 auto core = bss->GetBatteryStatsCore(); 83 auto cameraEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CAMERA); 84 auto flashlightEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_FLASHLIGHT); 85 auto audioEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_AUDIO); 86 auto sensorEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR); 87 auto gnssEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_GNSS); 88 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU); 89 auto wakelockEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_WAKELOCK); 90 auto alarmEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_ALARM); 91 92 // Calculate camera power consumption 93 cameraEntity->Calculate(uid); 94 power += cameraEntity->GetEntityPowerMah(uid); 95 // Calculate flashlight power consumption 96 flashlightEntity->Calculate(uid); 97 power += flashlightEntity->GetEntityPowerMah(uid); 98 // Calculate audio power consumption 99 audioEntity->Calculate(uid); 100 power += audioEntity->GetEntityPowerMah(uid); 101 // Calculate sensor power consumption 102 sensorEntity->Calculate(uid); 103 power += sensorEntity->GetEntityPowerMah(uid); 104 // Calculate gnss power consumption 105 gnssEntity->Calculate(uid); 106 power += gnssEntity->GetEntityPowerMah(uid); 107 // Calculate cpu power consumption 108 cpuEntity->Calculate(uid); 109 power += cpuEntity->GetEntityPowerMah(uid); 110 // Calculate cpu power consumption 111 wakelockEntity->Calculate(uid); 112 power += wakelockEntity->GetEntityPowerMah(uid); 113 // Calculate alarm power consumption 114 alarmEntity->Calculate(uid); 115 power += alarmEntity->GetEntityPowerMah(uid); 116 117 STATS_HILOGD(COMP_SVC, "Common power consumption: %{public}lfmAh for uid: %{public}d", power, uid); 118 return power; 119} 120 121void UidEntity::Calculate(int32_t uid) 122{ 123 auto bss = BatteryStatsService::GetInstance(); 124 std::lock_guard<std::mutex> lock(uidEntityMutex_); 125 auto core = bss->GetBatteryStatsCore(); 126 auto userEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_USER); 127 for (auto& iter : uidPowerMap_) { 128 double power = StatsUtils::DEFAULT_VALUE; 129 power += CalculateForConnectivity(iter.first); 130 power += CalculateForCommon(iter.first); 131 iter.second = power; 132 totalPowerMah_ += power; 133 AddtoStatsList(iter.first, power); 134 int32_t uid = iter.first; 135 int32_t userId = AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid); 136 if (userEntity != nullptr) { 137 userEntity->AggregateUserPowerMah(userId, power); 138 } 139 } 140} 141 142void UidEntity::AddtoStatsList(int32_t uid, double power) 143{ 144 std::shared_ptr<BatteryStatsInfo> statsInfo = std::make_shared<BatteryStatsInfo>(); 145 statsInfo->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_APP); 146 statsInfo->SetUid(uid); 147 statsInfo->SetPower(power); 148 statsInfoList_.push_back(statsInfo); 149} 150 151double UidEntity::GetEntityPowerMah(int32_t uidOrUserId) 152{ 153 std::lock_guard<std::mutex> lock(uidEntityMutex_); 154 double power = StatsUtils::DEFAULT_VALUE; 155 auto iter = uidPowerMap_.find(uidOrUserId); 156 if (iter != uidPowerMap_.end()) { 157 power = iter->second; 158 STATS_HILOGD(COMP_SVC, "Get app uid power consumption: %{public}lfmAh for uid: %{public}d", 159 power, uidOrUserId); 160 } else { 161 STATS_HILOGD(COMP_SVC, 162 "No app uid power consumption related to uid: %{public}d was found, return 0", uidOrUserId); 163 } 164 return power; 165} 166 167double UidEntity::GetPowerForConnectivity(StatsUtils::StatsType statsType, int32_t uid) 168{ 169 double power = StatsUtils::DEFAULT_VALUE; 170 auto bss = BatteryStatsService::GetInstance(); 171 auto core = bss->GetBatteryStatsCore(); 172 auto bluetoothEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH); 173 174 if (statsType == StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN) { 175 power = bluetoothEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN, uid); 176 } else if (statsType == StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN) { 177 power = bluetoothEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN, uid); 178 } 179 return power; 180} 181 182double UidEntity::GetPowerForCommon(StatsUtils::StatsType statsType, int32_t uid) 183{ 184 double power = StatsUtils::DEFAULT_VALUE; 185 auto bss = BatteryStatsService::GetInstance(); 186 auto core = bss->GetBatteryStatsCore(); 187 auto cameraEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CAMERA); 188 auto flashlightEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_FLASHLIGHT); 189 auto audioEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_AUDIO); 190 auto sensorEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR); 191 auto gnssEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_GNSS); 192 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU); 193 auto wakelockEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_WAKELOCK); 194 auto alarmEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_ALARM); 195 196 if (statsType == StatsUtils::STATS_TYPE_CAMERA_ON) { 197 power = cameraEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CAMERA_ON, uid); 198 } else if (statsType == StatsUtils::STATS_TYPE_FLASHLIGHT_ON) { 199 power = flashlightEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_FLASHLIGHT_ON, uid); 200 } else if (statsType == StatsUtils::STATS_TYPE_GNSS_ON) { 201 power = gnssEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_GNSS_ON, uid); 202 } else if (statsType == StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON) { 203 power = sensorEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON, uid); 204 } else if (statsType == StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON) { 205 power = sensorEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON, uid); 206 } else if (statsType == StatsUtils::STATS_TYPE_AUDIO_ON) { 207 power = audioEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_AUDIO_ON, uid); 208 } else if (statsType == StatsUtils::STATS_TYPE_WAKELOCK_HOLD) { 209 power = wakelockEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_WAKELOCK_HOLD, uid); 210 } else if (statsType == StatsUtils::STATS_TYPE_CPU_CLUSTER) { 211 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_CLUSTER, uid); 212 } else if (statsType == StatsUtils::STATS_TYPE_CPU_SPEED) { 213 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_SPEED, uid); 214 } else if (statsType == StatsUtils::STATS_TYPE_CPU_ACTIVE) { 215 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_ACTIVE, uid); 216 } else if (statsType == StatsUtils::STATS_TYPE_ALARM) { 217 power = alarmEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_ALARM, uid); 218 } 219 return power; 220} 221 222double UidEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid) 223{ 224 double power = StatsUtils::DEFAULT_VALUE; 225 226 switch (statsType) { 227 case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN: 228 case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN: 229 power = GetPowerForConnectivity(statsType, uid); 230 break; 231 case StatsUtils::STATS_TYPE_CAMERA_ON: 232 case StatsUtils::STATS_TYPE_FLASHLIGHT_ON: 233 case StatsUtils::STATS_TYPE_GNSS_ON: 234 case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON: 235 case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON: 236 case StatsUtils::STATS_TYPE_AUDIO_ON: 237 case StatsUtils::STATS_TYPE_WAKELOCK_HOLD: 238 case StatsUtils::STATS_TYPE_CPU_CLUSTER: 239 case StatsUtils::STATS_TYPE_CPU_SPEED: 240 case StatsUtils::STATS_TYPE_CPU_ACTIVE: 241 case StatsUtils::STATS_TYPE_ALARM: 242 power = GetPowerForCommon(statsType, uid); 243 break; 244 default: 245 STATS_HILOGW(COMP_SVC, "Invalid or illegal type got, return 0"); 246 break; 247 } 248 249 STATS_HILOGD(COMP_SVC, "Get %{public}s power: %{public}lfmAh for uid: %{public}d", 250 StatsUtils::ConvertStatsType(statsType).c_str(), power, uid); 251 return power; 252} 253 254void UidEntity::Reset() 255{ 256 std::lock_guard<std::mutex> lock(uidEntityMutex_); 257 // Reset app Uid total power consumption 258 for (auto& iter : uidPowerMap_) { 259 iter.second = StatsUtils::DEFAULT_VALUE; 260 } 261} 262 263void UidEntity::DumpForBluetooth(int32_t uid, std::string& result) 264{ 265 auto bss = BatteryStatsService::GetInstance(); 266 // Dump for bluetooth realted info 267 auto core = bss->GetBatteryStatsCore(); 268 int64_t bluetoothBrScanTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN); 269 int64_t bluetoothBleScanTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN); 270 271 result.append("Bluetooth Br scan time: ") 272 .append(ToString(bluetoothBrScanTime)) 273 .append("ms\n") 274 .append("Bluetooth Ble scan time: ") 275 .append(ToString(bluetoothBleScanTime)) 276 .append("ms\n"); 277} 278 279void UidEntity::DumpForCommon(int32_t uid, std::string& result) 280{ 281 auto bss = BatteryStatsService::GetInstance(); 282 auto core = bss->GetBatteryStatsCore(); 283 // Dump for camera related info 284 int64_t cameraTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_CAMERA_ON); 285 286 // Dump for flashlight related info 287 int64_t flashlightTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_FLASHLIGHT_ON); 288 289 // Dump for gnss related info 290 int64_t gnssTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_GNSS_ON); 291 292 // Dump for gravity sensor related info 293 int64_t gravityTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON); 294 295 // Dump for proximity sensor related info 296 int64_t proximityTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON); 297 298 // Dump for audio related info 299 int64_t audioTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_AUDIO_ON); 300 301 // Dump for wakelock related info 302 int64_t wakelockTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_WAKELOCK_HOLD); 303 304 // Dump for alarm related info 305 int64_t alarmCount = core->GetTotalConsumptionCount(StatsUtils::STATS_TYPE_ALARM, uid); 306 307 result.append("Camera on time: ") 308 .append(ToString(cameraTime)) 309 .append("ms\n") 310 .append("Flashlight scan time: ") 311 .append(ToString(flashlightTime)) 312 .append("ms\n") 313 .append("GNSS scan time: ") 314 .append(ToString(gnssTime)) 315 .append("ms\n") 316 .append("Gravity sensor on time: ") 317 .append(ToString(gravityTime)) 318 .append("ms\n") 319 .append("Proximity sensor on time: ") 320 .append(ToString(proximityTime)) 321 .append("ms\n") 322 .append("Audio on time: ") 323 .append(ToString(audioTime)) 324 .append("ms\n") 325 .append("Wakelock hold time: ") 326 .append(ToString(wakelockTime)) 327 .append("ms\n") 328 .append("Alarm trigger count: ") 329 .append(ToString(alarmCount)) 330 .append("times\n"); 331} 332 333void UidEntity::DumpInfo(std::string& result, int32_t uid) 334{ 335 auto bss = BatteryStatsService::GetInstance(); 336 std::lock_guard<std::mutex> lock(uidEntityMutex_); 337 auto core = bss->GetBatteryStatsCore(); 338 for (auto& iter : uidPowerMap_) { 339 std::string bundleName = "NULL"; 340#ifdef SYS_MGR_CLIENT_ENABLE 341 auto bundleObj = 342 DelayedSingleton<AppExecFwk::SysMrgClient>::GetInstance() 343 ->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 344 if (bundleObj == nullptr) { 345 STATS_HILOGE(COMP_SVC, "Failed to get bundle manager service"); 346 } else { 347 sptr<AppExecFwk::IBundleMgr> bmgr = iface_cast<AppExecFwk::IBundleMgr>(bundleObj); 348 if (bmgr == nullptr) { 349 STATS_HILOGE(COMP_SVC, "Failed to get bundle manager proxy"); 350 } else { 351 std::string identity = IPCSkeleton::ResetCallingIdentity(); 352 ErrCode res = bmgr->GetNameForUid(iter.first, bundleName); 353 IPCSkeleton::SetCallingIdentity(identity); 354 if (res != ERR_OK) { 355 STATS_HILOGE(COMP_SVC, "Failed to get bundle name for uid=%{public}d, ErrCode=%{public}d", 356 iter.first, static_cast<int32_t>(res)); 357 } 358 } 359 } 360#endif 361 result.append("\n") 362 .append(ToString(iter.first)) 363 .append("(Bundle name: ") 364 .append(bundleName) 365 .append(")") 366 .append(":") 367 .append("\n"); 368 DumpForBluetooth(iter.first, result); 369 DumpForCommon(iter.first, result); 370 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU); 371 if (cpuEntity) { 372 cpuEntity->DumpInfo(result, iter.first); 373 } 374 } 375} 376} // namespace PowerMgr 377} // namespace OHOS