1d590543dSopenharmony_ci/*
2d590543dSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3d590543dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d590543dSopenharmony_ci * you may not use this file except in compliance with the License.
5d590543dSopenharmony_ci * You may obtain a copy of the License at
6d590543dSopenharmony_ci *
7d590543dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d590543dSopenharmony_ci *
9d590543dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d590543dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d590543dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d590543dSopenharmony_ci * See the License for the specific language governing permissions and
13d590543dSopenharmony_ci * limitations under the License.
14d590543dSopenharmony_ci */
15d590543dSopenharmony_ci
16d590543dSopenharmony_ci#include "entities/phone_entity.h"
17d590543dSopenharmony_ci
18d590543dSopenharmony_ci#include <cinttypes>
19d590543dSopenharmony_ci
20d590543dSopenharmony_ci#include "battery_stats_service.h"
21d590543dSopenharmony_ci#include "stats_log.h"
22d590543dSopenharmony_ci
23d590543dSopenharmony_cinamespace OHOS {
24d590543dSopenharmony_cinamespace PowerMgr {
25d590543dSopenharmony_cinamespace {
26d590543dSopenharmony_ci}
27d590543dSopenharmony_ci
28d590543dSopenharmony_ciPhoneEntity::PhoneEntity()
29d590543dSopenharmony_ci{
30d590543dSopenharmony_ci    consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_PHONE;
31d590543dSopenharmony_ci}
32d590543dSopenharmony_ci
33d590543dSopenharmony_ciint64_t PhoneEntity::GetActiveTimeMs(StatsUtils::StatsType statsType, int16_t level)
34d590543dSopenharmony_ci{
35d590543dSopenharmony_ci    int64_t activeTimeMs = StatsUtils::DEFAULT_VALUE;
36d590543dSopenharmony_ci    switch (statsType) {
37d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_ACTIVE: {
38d590543dSopenharmony_ci            if (level != StatsUtils::INVALID_VALUE) {
39d590543dSopenharmony_ci                auto iter = phoneOnTimerMap_.find(level);
40d590543dSopenharmony_ci                if (iter != phoneOnTimerMap_.end() && iter->second != nullptr) {
41d590543dSopenharmony_ci                    activeTimeMs = iter->second->GetRunningTimeMs();
42d590543dSopenharmony_ci                    STATS_HILOGD(COMP_SVC, "Get phone on time: %{public}" PRId64 "ms of signal level: %{public}d",
43d590543dSopenharmony_ci                        activeTimeMs, level);
44d590543dSopenharmony_ci                    break;
45d590543dSopenharmony_ci                }
46d590543dSopenharmony_ci                STATS_HILOGD(COMP_SVC, "No phone on timer found, return 0");
47d590543dSopenharmony_ci                break;
48d590543dSopenharmony_ci            }
49d590543dSopenharmony_ci            activeTimeMs = GetTotalTimeMs(StatsUtils::STATS_TYPE_PHONE_ACTIVE);
50d590543dSopenharmony_ci            STATS_HILOGD(COMP_SVC, "Get phone on total time: %{public}" PRId64 "ms", activeTimeMs);
51d590543dSopenharmony_ci            break;
52d590543dSopenharmony_ci        }
53d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_DATA: {
54d590543dSopenharmony_ci            if (level != StatsUtils::INVALID_VALUE) {
55d590543dSopenharmony_ci                auto iter = phoneDataTimerMap_.find(level);
56d590543dSopenharmony_ci                if (iter != phoneDataTimerMap_.end() && iter->second != nullptr) {
57d590543dSopenharmony_ci                    activeTimeMs = iter->second->GetRunningTimeMs();
58d590543dSopenharmony_ci                    STATS_HILOGD(COMP_SVC, "Get phone data time: %{public}" PRId64 "ms of signal level: %{public}d",
59d590543dSopenharmony_ci                        activeTimeMs, level);
60d590543dSopenharmony_ci                    break;
61d590543dSopenharmony_ci                }
62d590543dSopenharmony_ci                STATS_HILOGD(COMP_SVC, "No phone data timer found, return 0");
63d590543dSopenharmony_ci                break;
64d590543dSopenharmony_ci            }
65d590543dSopenharmony_ci            activeTimeMs = GetTotalTimeMs(StatsUtils::STATS_TYPE_PHONE_DATA);
66d590543dSopenharmony_ci            STATS_HILOGD(COMP_SVC, "Get phone data total time: %{public}" PRId64 "ms", activeTimeMs);
67d590543dSopenharmony_ci            break;
68d590543dSopenharmony_ci        }
69d590543dSopenharmony_ci        default:
70d590543dSopenharmony_ci            break;
71d590543dSopenharmony_ci    }
72d590543dSopenharmony_ci    return activeTimeMs;
73d590543dSopenharmony_ci}
74d590543dSopenharmony_ci
75d590543dSopenharmony_ciint64_t PhoneEntity::GetTotalTimeMs(StatsUtils::StatsType statsType)
76d590543dSopenharmony_ci{
77d590543dSopenharmony_ci    int64_t totalTimeMs = StatsUtils::DEFAULT_VALUE;
78d590543dSopenharmony_ci    switch (statsType) {
79d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_ACTIVE: {
80d590543dSopenharmony_ci            for (auto timerIter : phoneOnTimerMap_) {
81d590543dSopenharmony_ci                totalTimeMs += timerIter.second->GetRunningTimeMs();
82d590543dSopenharmony_ci            }
83d590543dSopenharmony_ci            break;
84d590543dSopenharmony_ci        }
85d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_DATA: {
86d590543dSopenharmony_ci            for (auto timerIter : phoneDataTimerMap_) {
87d590543dSopenharmony_ci                totalTimeMs += timerIter.second->GetRunningTimeMs();
88d590543dSopenharmony_ci            }
89d590543dSopenharmony_ci            break;
90d590543dSopenharmony_ci        }
91d590543dSopenharmony_ci        default:
92d590543dSopenharmony_ci            break;
93d590543dSopenharmony_ci    }
94d590543dSopenharmony_ci    return totalTimeMs;
95d590543dSopenharmony_ci}
96d590543dSopenharmony_ci
97d590543dSopenharmony_civoid PhoneEntity::Calculate(int32_t uid)
98d590543dSopenharmony_ci{
99d590543dSopenharmony_ci    auto bss = BatteryStatsService::GetInstance();
100d590543dSopenharmony_ci    // Calculate phone on power
101d590543dSopenharmony_ci    double phoneOnPowerMah = StatsUtils::DEFAULT_VALUE;
102d590543dSopenharmony_ci    for (int32_t i = 0; i < StatsUtils::RADIO_SIGNAL_BIN; i++) {
103d590543dSopenharmony_ci        auto phoneOnAverageMa =
104d590543dSopenharmony_ci            bss->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_RADIO_ON, i);
105d590543dSopenharmony_ci        auto phoneOnLevelTimeMs = GetActiveTimeMs(StatsUtils::STATS_TYPE_PHONE_ACTIVE, i);
106d590543dSopenharmony_ci        double phoneOnLevelPowerMah = phoneOnAverageMa * phoneOnLevelTimeMs / StatsUtils::MS_IN_HOUR;
107d590543dSopenharmony_ci        phoneOnPowerMah += phoneOnLevelPowerMah;
108d590543dSopenharmony_ci    }
109d590543dSopenharmony_ci
110d590543dSopenharmony_ci    // Calculate phone data power
111d590543dSopenharmony_ci    double phoneDataPowerMah = StatsUtils::DEFAULT_VALUE;
112d590543dSopenharmony_ci    for (int32_t i = 0; i < StatsUtils::RADIO_SIGNAL_BIN; i++) {
113d590543dSopenharmony_ci        auto phoneDataAverageMa =
114d590543dSopenharmony_ci            bss->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_RADIO_DATA, i);
115d590543dSopenharmony_ci        auto phoneDataLevelTimeMs = GetActiveTimeMs(StatsUtils::STATS_TYPE_PHONE_DATA, i);
116d590543dSopenharmony_ci        double phoneDataLevelPowerMah = phoneDataAverageMa * phoneDataLevelTimeMs / StatsUtils::MS_IN_HOUR;
117d590543dSopenharmony_ci        phoneDataPowerMah += phoneDataLevelPowerMah;
118d590543dSopenharmony_ci    }
119d590543dSopenharmony_ci    phonePowerMah_ = phoneOnPowerMah + phoneDataPowerMah;
120d590543dSopenharmony_ci    totalPowerMah_ += phonePowerMah_;
121d590543dSopenharmony_ci    std::shared_ptr<BatteryStatsInfo> statsInfo = std::make_shared<BatteryStatsInfo>();
122d590543dSopenharmony_ci    statsInfo->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_PHONE);
123d590543dSopenharmony_ci    statsInfo->SetPower(phonePowerMah_);
124d590543dSopenharmony_ci    statsInfoList_.push_back(statsInfo);
125d590543dSopenharmony_ci    STATS_HILOGD(COMP_SVC, "Calculate phone active power consumption: %{public}lfmAh", phonePowerMah_);
126d590543dSopenharmony_ci}
127d590543dSopenharmony_ci
128d590543dSopenharmony_cidouble PhoneEntity::GetEntityPowerMah(int32_t uidOrUserId)
129d590543dSopenharmony_ci{
130d590543dSopenharmony_ci    return phonePowerMah_;
131d590543dSopenharmony_ci}
132d590543dSopenharmony_ci
133d590543dSopenharmony_cidouble PhoneEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid)
134d590543dSopenharmony_ci{
135d590543dSopenharmony_ci    return phonePowerMah_;
136d590543dSopenharmony_ci}
137d590543dSopenharmony_ci
138d590543dSopenharmony_cistd::shared_ptr<StatsHelper::ActiveTimer> PhoneEntity::GetOrCreateTimer(StatsUtils::StatsType statsType, int16_t level)
139d590543dSopenharmony_ci{
140d590543dSopenharmony_ci    std::shared_ptr<StatsHelper::ActiveTimer> timer = nullptr;
141d590543dSopenharmony_ci    if (level <= StatsUtils::INVALID_VALUE || level > StatsUtils::RADIO_SIGNAL_BIN) {
142d590543dSopenharmony_ci        STATS_HILOGD(COMP_SVC, "Illegal signal level");
143d590543dSopenharmony_ci        return timer;
144d590543dSopenharmony_ci    }
145d590543dSopenharmony_ci
146d590543dSopenharmony_ci    switch (statsType) {
147d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_ACTIVE: {
148d590543dSopenharmony_ci            auto onIter = phoneOnTimerMap_.find(level);
149d590543dSopenharmony_ci            if (onIter != phoneOnTimerMap_.end()) {
150d590543dSopenharmony_ci                STATS_HILOGD(COMP_SVC, "Get phone on timer for level: %{public}d", level);
151d590543dSopenharmony_ci                timer = onIter->second;
152d590543dSopenharmony_ci                break;
153d590543dSopenharmony_ci            }
154d590543dSopenharmony_ci            STATS_HILOGD(COMP_SVC, "Create phone on timer for level: %{public}d", level);
155d590543dSopenharmony_ci            std::shared_ptr<StatsHelper::ActiveTimer> phoneOnTimer = std::make_shared<StatsHelper::ActiveTimer>();
156d590543dSopenharmony_ci            phoneOnTimerMap_.insert(
157d590543dSopenharmony_ci                std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(level, phoneOnTimer));
158d590543dSopenharmony_ci            timer = phoneOnTimer;
159d590543dSopenharmony_ci            break;
160d590543dSopenharmony_ci        }
161d590543dSopenharmony_ci        case StatsUtils::STATS_TYPE_PHONE_DATA: {
162d590543dSopenharmony_ci            auto dataIter = phoneDataTimerMap_.find(level);
163d590543dSopenharmony_ci            if (dataIter != phoneDataTimerMap_.end()) {
164d590543dSopenharmony_ci                STATS_HILOGD(COMP_SVC, "Get phone data timer for level: %{public}d", level);
165d590543dSopenharmony_ci                timer = dataIter->second;
166d590543dSopenharmony_ci                break;
167d590543dSopenharmony_ci            }
168d590543dSopenharmony_ci            STATS_HILOGD(COMP_SVC, "Create phone data timer for level: %{public}d", level);
169d590543dSopenharmony_ci            std::shared_ptr<StatsHelper::ActiveTimer> phoneDataTimer = std::make_shared<StatsHelper::ActiveTimer>();
170d590543dSopenharmony_ci            phoneDataTimerMap_.insert(
171d590543dSopenharmony_ci                std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(level, phoneDataTimer));
172d590543dSopenharmony_ci            timer = phoneDataTimer;
173d590543dSopenharmony_ci            break;
174d590543dSopenharmony_ci        }
175d590543dSopenharmony_ci        default:
176d590543dSopenharmony_ci            STATS_HILOGW(COMP_SVC, "Create phone timer failed");
177d590543dSopenharmony_ci            break;
178d590543dSopenharmony_ci    }
179d590543dSopenharmony_ci    return timer;
180d590543dSopenharmony_ci}
181d590543dSopenharmony_ci
182d590543dSopenharmony_civoid PhoneEntity::Reset()
183d590543dSopenharmony_ci{
184d590543dSopenharmony_ci    // Reset app Phone total power consumption
185d590543dSopenharmony_ci    phonePowerMah_ = StatsUtils::DEFAULT_VALUE;
186d590543dSopenharmony_ci
187d590543dSopenharmony_ci    // Reset Phone on timer
188d590543dSopenharmony_ci    for (auto& iter : phoneOnTimerMap_) {
189d590543dSopenharmony_ci        if (iter.second) {
190d590543dSopenharmony_ci            iter.second->Reset();
191d590543dSopenharmony_ci        }
192d590543dSopenharmony_ci    }
193d590543dSopenharmony_ci
194d590543dSopenharmony_ci    // Reset Phone data timer
195d590543dSopenharmony_ci    for (auto& iter : phoneDataTimerMap_) {
196d590543dSopenharmony_ci        if (iter.second) {
197d590543dSopenharmony_ci            iter.second->Reset();
198d590543dSopenharmony_ci        }
199d590543dSopenharmony_ci    }
200d590543dSopenharmony_ci}
201d590543dSopenharmony_ci
202d590543dSopenharmony_civoid PhoneEntity::DumpInfo(std::string& result, int32_t uid)
203d590543dSopenharmony_ci{
204d590543dSopenharmony_ci    int64_t phoneOnTime = StatsUtils::DEFAULT_VALUE;
205d590543dSopenharmony_ci    int64_t phoneDataTime = StatsUtils::DEFAULT_VALUE;
206d590543dSopenharmony_ci    for (int32_t i = 0; i < StatsUtils::RADIO_SIGNAL_BIN; i++) {
207d590543dSopenharmony_ci        phoneOnTime += GetActiveTimeMs(StatsUtils::STATS_TYPE_PHONE_ACTIVE, i);
208d590543dSopenharmony_ci        phoneDataTime += GetActiveTimeMs(StatsUtils::STATS_TYPE_PHONE_DATA, i);
209d590543dSopenharmony_ci    }
210d590543dSopenharmony_ci
211d590543dSopenharmony_ci    result.append("Phone dump:\n")
212d590543dSopenharmony_ci        .append("Phone active time: ")
213d590543dSopenharmony_ci        .append(ToString(phoneOnTime))
214d590543dSopenharmony_ci        .append("ms\n")
215d590543dSopenharmony_ci        .append("Phone data time: ")
216d590543dSopenharmony_ci        .append(ToString(phoneDataTime))
217d590543dSopenharmony_ci        .append("ms")
218d590543dSopenharmony_ci        .append("\n");
219d590543dSopenharmony_ci}
220d590543dSopenharmony_ci} // namespace PowerMgr
221d590543dSopenharmony_ci} // namespace OHOS