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 "battery_stats.h"
17 
18 #include <memory>
19 
20 #include "async_callback_info.h"
21 #include "battery_stats_client.h"
22 #include "battery_stats_info.h"
23 #include "napi_utils.h"
24 #include "stats_common.h"
25 #include "stats_log.h"
26 
27 namespace OHOS {
28 namespace PowerMgr {
BatteryStats(napi_env & env)29 BatteryStats::BatteryStats(napi_env& env) : env_(env) {}
30 
StatsAsyncCallBack(napi_value & value)31 void BatteryStats::StatsAsyncCallBack(napi_value& value)
32 {
33     std::unique_ptr<AsyncCallbackInfo> asyncInfo = std::make_unique<AsyncCallbackInfo>();
34     asyncInfo->CreateCallback(env_, value);
35     napi_value resource = nullptr;
36     NAPI_CALL_RETURN_VOID(env_, napi_create_string_utf8(env_, "StatsAsyncCallBack", NAPI_AUTO_LENGTH, &resource));
37     napi_create_async_work(
38         env_, nullptr, resource,
39         [](napi_env env, void* data) {
40             AsyncCallbackInfo* asCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
41             STATS_RETURN_IF(asCallbackInfo == nullptr);
42             asCallbackInfo->GetError().Error(asCallbackInfo->GetData().GetBatteryStatsInfo());
43         },
44         [](napi_env env, napi_status status, void* data) {
45             AsyncCallbackInfo* asCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
46             STATS_RETURN_IF(asCallbackInfo == nullptr);
47             napi_value arrRes = nullptr;
48             asCallbackInfo->GetData().CreateArrayValue(env, arrRes);
49             asCallbackInfo->CallFunction(env, arrRes);
50             asCallbackInfo->Release(env);
51             delete asCallbackInfo;
52         },
53         reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->GetAsyncWork());
54     NAPI_CALL_RETURN_VOID(
55         env_, napi_queue_async_work_with_qos(env_, asyncInfo->GetAsyncWork(), napi_qos_utility));
56     asyncInfo.release();
57 }
58 
StatsPromise()59 napi_value BatteryStats::StatsPromise()
60 {
61     std::unique_ptr<AsyncCallbackInfo> asyncInfo = std::make_unique<AsyncCallbackInfo>();
62     napi_value promise;
63     asyncInfo->CreatePromise(env_, promise);
64     STATS_RETURN_IF_WITH_RET(promise == nullptr, nullptr);
65 
66     napi_value resourceName = nullptr;
67     NAPI_CALL_BASE(env_, napi_create_string_utf8(env_, "StatsPromise", NAPI_AUTO_LENGTH, &resourceName), promise);
68     napi_create_async_work(
69         env_, nullptr, resourceName,
70         [](napi_env env, void* data) {
71             AsyncCallbackInfo* asCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
72             STATS_RETURN_IF(asCallbackInfo == nullptr);
73             asCallbackInfo->GetError().Error(asCallbackInfo->GetData().GetBatteryStatsInfo());
74         },
75         [](napi_env env, napi_status status, void* data) {
76             AsyncCallbackInfo* asCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(data);
77             STATS_RETURN_IF(asCallbackInfo == nullptr);
78             if (asCallbackInfo->GetError().IsError()) {
79                 napi_reject_deferred(env, asCallbackInfo->GetDeferred(), asCallbackInfo->GetError().GetNapiError(env));
80             } else {
81                 napi_value arrRes = nullptr;
82                 asCallbackInfo->GetData().CreateArrayValue(env, arrRes);
83                 napi_resolve_deferred(env, asCallbackInfo->GetDeferred(), arrRes);
84             }
85             asCallbackInfo->Release(env);
86             delete asCallbackInfo;
87         },
88         reinterpret_cast<void*>(asyncInfo.get()), &asyncInfo->GetAsyncWork());
89     NAPI_CALL_BASE(env_, napi_queue_async_work_with_qos(env_, asyncInfo->GetAsyncWork(), napi_qos_utility), promise);
90     asyncInfo.release();
91     return promise;
92 }
93 
GetAppStatsMah(napi_callback_info & info,uint32_t maxArgc,uint32_t index)94 napi_value BatteryStats::GetAppStatsMah(napi_callback_info& info, uint32_t maxArgc, uint32_t index)
95 {
96     return GetAppOrPartStats(info, maxArgc, index, [&](int32_t uid, NapiError& error) {
97         double appStatsMah = BatteryStatsClient::GetInstance().GetAppStatsMah(uid);
98         error.Error(BatteryStatsClient::GetInstance().GetLastError());
99         STATS_HILOGD(COMP_FWK, "get app stats mah: %{public}lf for uid: %{public}d", appStatsMah, uid);
100         return appStatsMah;
101     });
102 }
103 
GetAppStatsPercent(napi_callback_info & info,uint32_t maxArgc,uint32_t index)104 napi_value BatteryStats::GetAppStatsPercent(napi_callback_info& info, uint32_t maxArgc, uint32_t index)
105 {
106     return GetAppOrPartStats(info, maxArgc, index, [&](int32_t uid, NapiError& error) {
107         double appStatsPercent = BatteryStatsClient::GetInstance().GetAppStatsPercent(uid);
108         error.Error(BatteryStatsClient::GetInstance().GetLastError());
109         STATS_HILOGD(COMP_FWK, "get app stats percent: %{public}lf for uid: %{public}d", appStatsPercent, uid);
110         return appStatsPercent;
111     });
112 }
113 
GetPartStatsMah(napi_callback_info & info,uint32_t maxArgc,uint32_t index)114 napi_value BatteryStats::GetPartStatsMah(napi_callback_info& info, uint32_t maxArgc, uint32_t index)
115 {
116     return GetAppOrPartStats(info, maxArgc, index, [&](int32_t type, NapiError& error) {
117         BatteryStatsInfo::ConsumptionType naviveType = BatteryStatsInfo::ConsumptionType(type);
118         double partStatsMah = BatteryStatsClient::GetInstance().GetPartStatsMah(naviveType);
119         error.Error(BatteryStatsClient::GetInstance().GetLastError());
120         STATS_HILOGD(COMP_FWK, "get part stats mah: %{public}lf for type: %{public}d", partStatsMah, type);
121         return partStatsMah;
122     });
123 }
124 
GetPartStatsPercent(napi_callback_info & info,uint32_t maxArgc,uint32_t index)125 napi_value BatteryStats::GetPartStatsPercent(napi_callback_info& info, uint32_t maxArgc, uint32_t index)
126 {
127     return GetAppOrPartStats(info, maxArgc, index, [&](int32_t type, NapiError& error) {
128         BatteryStatsInfo::ConsumptionType naviveType = BatteryStatsInfo::ConsumptionType(type);
129         double partStatsPercent = BatteryStatsClient::GetInstance().GetPartStatsPercent(naviveType);
130         error.Error(BatteryStatsClient::GetInstance().GetLastError());
131         STATS_HILOGD(COMP_FWK, "get part stats percent: %{public}lf for type: %{public}d", partStatsPercent, type);
132         return partStatsPercent;
133     });
134 }
135 
GetAppOrPartStats(napi_callback_info & info,uint32_t maxArgc,uint32_t index,std::function<double (int32_t,NapiError &)> getAppOrPart)136 napi_value BatteryStats::GetAppOrPartStats(
137     napi_callback_info& info, uint32_t maxArgc, uint32_t index, std::function<double(int32_t, NapiError&)> getAppOrPart)
138 {
139     size_t argc = maxArgc;
140     napi_value argv[argc];
141     NapiUtils::GetCallbackInfo(env_, info, argc, argv);
142     NapiError error;
143 
144     if (argc != maxArgc || !NapiUtils::CheckValueType(env_, argv[index], napi_number)) {
145         return error.ThrowError(env_, StatsError::ERR_PARAM_INVALID);
146     }
147 
148     int32_t jsValue;
149     napi_get_value_int32(env_, argv[index], &jsValue);
150     double statsData = getAppOrPart(jsValue, error);
151     if (error.IsError()) {
152         return error.ThrowError(env_);
153     }
154 
155     napi_value result = nullptr;
156     napi_create_double(env_, statsData, &result);
157     return result;
158 }
159 } // namespace PowerMgr
160 } // namespace OHOS
161