1 /*
2  * Copyright (c) 2023-2024 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 "power_policy_plugin.h"
17 
18 #include "battery_utils.h"
19 #include "edm_data_ability_utils.h"
20 #include "edm_ipc_interface_code.h"
21 #include "edm_log.h"
22 #include "func_code_utils.h"
23 #include "plugin_manager.h"
24 
25 namespace OHOS {
26 namespace EDM {
27 const bool REGISTER_RESULT = PluginManager::GetInstance()->AddPlugin(std::make_shared<PowerPolicyPlugin>());
28 
29 const std::string KEY_POWER_SUSPEND = "settings.power.suspend_sources";
30 const std::string KEY_POWER_AC_SUSPEND = "settings.power.ac.suspend_sources";
31 const std::string KEY_POWER_DC_SUSPEND = "settings.power.dc.suspend_sources";
32 const std::string KEY_ACTION = "action";
33 const std::string KEY_DELAY_TIME = "delayMs";
34 const std::string KEY_TIME_OUT = "timeout";
35 
PowerPolicyPlugin()36 PowerPolicyPlugin::PowerPolicyPlugin()
37 {
38     policyCode_ = EdmInterfaceCode::POWER_POLICY;
39     policyName_ = "power_policy";
40     permissionConfig_.permission = "ohos.permission.ENTERPRISE_MANAGE_SETTINGS";
41     permissionConfig_.permissionType = IPlugin::PermissionType::SUPER_DEVICE_ADMIN;
42     permissionConfig_.apiType = IPlugin::ApiType::PUBLIC;
43     needSave_ = false;
44 }
45 
OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply, HandlePolicyData &policyData, int32_t userId)46 ErrCode PowerPolicyPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
47     HandlePolicyData &policyData, int32_t userId)
48 {
49     uint32_t typeCode = FUNC_TO_OPERATE(funcCode);
50     FuncOperateType type = FuncCodeUtils::ConvertOperateType(typeCode);
51     if (type == FuncOperateType::SET) {
52         return SetPowerPolicy(data);
53     }
54     return EdmReturnErrCode::SYSTEM_ABNORMALLY;
55 }
56 
SetPowerPolicy(MessageParcel &data)57 ErrCode PowerPolicyPlugin::SetPowerPolicy(MessageParcel &data)
58 {
59     uint32_t powerSence = data.ReadUint32();
60     PowerPolicy powerPolicy;
61     if (!PowerPolicy::Unmarshalling(data, powerPolicy)) {
62         EDMLOGE("PowerPolicyPlugin:Unmarshalling parse error");
63         return EdmReturnErrCode::PARAM_ERROR;
64     }
65     std::string policyKey;
66     if (!GetPowerSceneKey(powerSence, policyKey)) {
67         EDMLOGE("PowerPolicyPlugin:GetPowerSceneKey error");
68         return EdmReturnErrCode::PARAM_ERROR;
69     }
70 
71     if (DealPowerSuspendPolicy(policyKey, powerPolicy, true)) {
72         return ERR_OK;
73     }
74     return EdmReturnErrCode::SYSTEM_ABNORMALLY;
75 }
76 
OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply, int32_t userId)77 ErrCode PowerPolicyPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
78     int32_t userId)
79 {
80     uint32_t powerSence = data.ReadUint32();
81     std::string policyKey;
82     if (!GetPowerSceneKey(powerSence, policyKey)) {
83         reply.WriteInt32(EdmReturnErrCode::PARAM_ERROR);
84         return EdmReturnErrCode::PARAM_ERROR;
85     }
86     PowerPolicy powerPolicy;
87     if (!DealPowerSuspendPolicy(policyKey, powerPolicy, false)) {
88         EDMLOGE("PowerPolicyPlugin:PowerPolicy parse error");
89         reply.WriteInt32(EdmReturnErrCode::SYSTEM_ABNORMALLY);
90         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
91     }
92     reply.WriteInt32(ERR_OK);
93     if (!powerPolicy.Marshalling(reply)) {
94         EDMLOGE("PowerPolicyPlugin:OnGetPolicy Marshalling error");
95         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
96     }
97     return ERR_OK;
98 }
99 
DealPowerSuspendPolicy(const std::string &policyKey, PowerPolicy &powerPolicy, bool isSetPolicy)100 bool PowerPolicyPlugin::DealPowerSuspendPolicy(const std::string &policyKey, PowerPolicy &powerPolicy, bool isSetPolicy)
101 {
102     std::string powerSuspend;
103 #ifdef FEATURE_CHARGING_TYPE_SETTING
104     std::string newKey;
105     if (BatteryUtils::GetBatteryPluggedType() == BatteryUtils::PLUGGED_TYPE_AC) {
106         newKey = KEY_POWER_AC_SUSPEND;
107     } else {
108         newKey = KEY_POWER_DC_SUSPEND;
109     }
110     if (FAILED(EdmDataAbilityUtils::GetStringFromSettingsDataShare(
111         BatteryUtils::GetSubUserTableUri(), newKey, powerSuspend))) {
112         return false;
113     }
114 #else
115     if (FAILED(EdmDataAbilityUtils::GetStringFromSettingsDataShare(KEY_POWER_SUSPEND, powerSuspend))) {
116         return false;
117     }
118 #endif
119 
120     Json::Reader reader;
121     Json::Value root;
122     if (!reader.parse(powerSuspend.data(), powerSuspend.data() + powerSuspend.size(), root)) {
123         EDMLOGE("PowerPolicyPlugin:DealPowerSuspendPolicy parse error");
124         return false;
125     }
126     if (!root.isMember(policyKey)) {
127         EDMLOGE("PowerPolicyPlugin:DealPowerSuspendPolicy %{pubilc}s is not root member", policyKey.c_str());
128         return false;
129     }
130     Json::Value::Members members = root.getMemberNames();
131     for (auto iter = members.begin(); iter != members.end(); iter++) {
132         std::string key = *iter;
133         if (key != policyKey) {
134             continue;
135         }
136         if (isSetPolicy) {
137             return UpdateSuspendSettingsData(root, key, powerPolicy);
138         }
139         return SetPowerPolicyObject(root, key, powerPolicy);
140     }
141     return false;
142 }
143 
UpdateSuspendSettingsData(Json::Value &root, const std::string &key, const PowerPolicy &powerPolicy)144 bool PowerPolicyPlugin::UpdateSuspendSettingsData(Json::Value &root, const std::string &key,
145     const PowerPolicy &powerPolicy)
146 {
147     Json::Value valueObj = root[key];
148     if (!valueObj.isObject()) {
149         return false;
150     }
151     valueObj[KEY_ACTION] = static_cast<uint32_t>(powerPolicy.GetPowerPolicyAction());
152     valueObj[KEY_DELAY_TIME] = powerPolicy.GetDealyTime();
153     root[key] = valueObj;
154     std::string jsonStr = root.toStyledString();
155     EDMLOGD("PowerPolicyPlugin:OnSetPolicy jsonStr = %{public}s", jsonStr.c_str());
156 
157 #ifdef FEATURE_CHARGING_TYPE_SETTING
158     if (FAILED(EdmDataAbilityUtils::UpdateSettingsData(
159         BatteryUtils::GetSubUserTableUri(), KEY_POWER_AC_SUSPEND, jsonStr))) {
160         return false;
161     }
162     if (FAILED(EdmDataAbilityUtils::UpdateSettingsData(
163         BatteryUtils::GetSubUserTableUri(), KEY_POWER_DC_SUSPEND, jsonStr))) {
164         return false;
165     }
166 #else
167     if (FAILED(EdmDataAbilityUtils::UpdateSettingsData(KEY_POWER_SUSPEND, jsonStr))) {
168         return false;
169     }
170 #endif
171     return true;
172 }
173 
SetPowerPolicyObject(Json::Value &root, std::string &key, PowerPolicy &powerPolicy)174 bool PowerPolicyPlugin::SetPowerPolicyObject(Json::Value &root, std::string &key, PowerPolicy &powerPolicy)
175 {
176     Json::Value valueObj = root[key];
177     if (!valueObj.isObject()) {
178         return false;
179     }
180     Json::Value actionValue = valueObj[KEY_ACTION];
181     Json::Value delayValue = valueObj[KEY_DELAY_TIME];
182     if (actionValue.isUInt() && delayValue.isUInt()) {
183         if (!powerPolicy.SetPowerPolicyAction(actionValue.asUInt())) {
184             return false;
185         }
186         powerPolicy.SetDelayTime(delayValue.asUInt());
187         return true;
188     }
189     return false;
190 }
191 
GetPowerSceneKey(const uint32_t &powerScene, std::string &sceneKey)192 bool PowerPolicyPlugin::GetPowerSceneKey(const uint32_t &powerScene, std::string &sceneKey)
193 {
194     if (powerScene == static_cast<uint32_t>(PowerScene::TIME_OUT)) {
195         sceneKey = KEY_TIME_OUT;
196         return true;
197     }
198     return false;
199 }
200 } // namespace EDM
201 } // namespace OHOS
202