1/*
2 * Copyright (c) 2023 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 "standby_service_client.h"
17
18#include <message_parcel.h>
19
20#include "iservice_registry.h"
21#include "system_ability_definition.h"
22#include "standby_service_errors.h"
23#include "standby_service_log.h"
24#include "standby_service_proxy.h"
25
26namespace OHOS {
27namespace DevStandbyMgr {
28StandbyServiceClient::StandbyServiceClient() {}
29
30StandbyServiceClient::~StandbyServiceClient() {}
31
32StandbyServiceClient& StandbyServiceClient::GetInstance()
33{
34    static StandbyServiceClient StandbyServiceClient;
35    return StandbyServiceClient;
36}
37
38ErrCode StandbyServiceClient::SubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber>& subscriber)
39{
40    std::lock_guard<std::mutex> lock(mutex_);
41    if (!GetStandbyServiceProxy()) {
42        STANDBYSERVICE_LOGE("get standby service proxy failed");
43        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
44    }
45    if (subscriber == nullptr) {
46        STANDBYSERVICE_LOGE("subscriber is nullptr");
47        return ERR_STANDBY_INVALID_PARAM;
48    }
49    return standbyServiceProxy_->SubscribeStandbyCallback(subscriber);
50}
51
52ErrCode StandbyServiceClient::UnsubscribeStandbyCallback(const sptr<IStandbyServiceSubscriber>& subscriber)
53{
54    std::lock_guard<std::mutex> lock(mutex_);
55    if (!GetStandbyServiceProxy()) {
56        STANDBYSERVICE_LOGE("get standby service proxy failed");
57        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
58    }
59    if (subscriber == nullptr) {
60        STANDBYSERVICE_LOGE("subscriber is nullptr");
61        return ERR_STANDBY_INVALID_PARAM;
62    }
63    return standbyServiceProxy_->UnsubscribeStandbyCallback(subscriber);
64}
65
66ErrCode StandbyServiceClient::ApplyAllowResource(const sptr<ResourceRequest>& resourceRequest)
67{
68    std::lock_guard<std::mutex> lock(mutex_);
69    if (!GetStandbyServiceProxy()) {
70        STANDBYSERVICE_LOGE("get standby service proxy failed");
71        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
72    }
73    if (resourceRequest == nullptr) {
74        STANDBYSERVICE_LOGE("resource request is nullptr");
75        return ERR_STANDBY_INVALID_PARAM;
76    }
77    return standbyServiceProxy_->ApplyAllowResource(resourceRequest);
78}
79
80ErrCode StandbyServiceClient::UnapplyAllowResource(const sptr<ResourceRequest>& resourceRequest)
81{
82    std::lock_guard<std::mutex> lock(mutex_);
83    if (!GetStandbyServiceProxy()) {
84        STANDBYSERVICE_LOGE("get standby service proxy failed");
85        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
86    }
87    if (resourceRequest == nullptr) {
88        STANDBYSERVICE_LOGE("resource request is nullptr");
89        return ERR_STANDBY_INVALID_PARAM;
90    }
91    return standbyServiceProxy_->UnapplyAllowResource(resourceRequest);
92}
93
94ErrCode StandbyServiceClient::GetAllowList(uint32_t allowType, std::vector<AllowInfo>& allowInfoArray,
95    uint32_t reasonCode)
96{
97    std::lock_guard<std::mutex> lock(mutex_);
98    if (!GetStandbyServiceProxy()) {
99        STANDBYSERVICE_LOGE("get standby service proxy failed");
100        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
101    }
102    if (!allowInfoArray.empty()) {
103        STANDBYSERVICE_LOGW("allow info array is not empty");
104        allowInfoArray.clear();
105    }
106    return standbyServiceProxy_->GetAllowList(allowType, allowInfoArray, reasonCode);
107}
108
109ErrCode StandbyServiceClient::IsDeviceInStandby(bool& isStandby)
110{
111    std::lock_guard<std::mutex> lock(mutex_);
112    if (!GetStandbyServiceProxy()) {
113        STANDBYSERVICE_LOGE("get standby service proxy failed");
114        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
115    }
116    return standbyServiceProxy_->IsDeviceInStandby(isStandby);
117}
118
119ErrCode StandbyServiceClient::SetNatInterval(uint32_t& type, bool& enable, uint32_t& interval)
120{
121    std::lock_guard<std::mutex> lock(mutex_);
122    if (!GetStandbyServiceProxy()) {
123        STANDBYSERVICE_LOGE("get standby service proxy failed");
124        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
125    }
126    return standbyServiceProxy_->SetNatInterval(type, enable, interval);
127}
128
129ErrCode StandbyServiceClient::HandleEvent(const std::shared_ptr<ResData> &resData)
130{
131    std::lock_guard<std::mutex> lock(mutex_);
132    std::string sceneInfo = resData->payload.dump();
133    if (!GetStandbyServiceProxy()) {
134        STANDBYSERVICE_LOGE("get standby service proxy failed");
135        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
136    }
137    return standbyServiceProxy_->HandleEvent(resData->resType, resData->value, sceneInfo);
138}
139
140ErrCode StandbyServiceClient::ReportWorkSchedulerStatus(bool started, int32_t uid, const std::string& bundleName)
141{
142    std::lock_guard<std::mutex> lock(mutex_);
143    if (!GetStandbyServiceProxy()) {
144        STANDBYSERVICE_LOGE("get standby service proxy failed");
145        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
146    }
147    return standbyServiceProxy_->ReportWorkSchedulerStatus(started, uid, bundleName);
148}
149
150ErrCode StandbyServiceClient::GetRestrictList(uint32_t restrictType, std::vector<AllowInfo>& restrictInfoList,
151    uint32_t reasonCode)
152{
153    std::lock_guard<std::mutex> lock(mutex_);
154    if (!GetStandbyServiceProxy()) {
155        STANDBYSERVICE_LOGE("get standby service proxy failed");
156        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
157    }
158    if (!restrictInfoList.empty()) {
159        STANDBYSERVICE_LOGW("restrict info array is not empty");
160        restrictInfoList.clear();
161    }
162    return standbyServiceProxy_->GetRestrictList(restrictType, restrictInfoList, reasonCode);
163}
164
165ErrCode StandbyServiceClient::IsStrategyEnabled(const std::string& strategyName, bool& isEnabled)
166{
167    std::lock_guard<std::mutex> lock(mutex_);
168    if (!GetStandbyServiceProxy()) {
169        STANDBYSERVICE_LOGE("get standby service proxy failed");
170        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
171    }
172    return standbyServiceProxy_->IsStrategyEnabled(strategyName, isEnabled);
173}
174
175ErrCode StandbyServiceClient::ReportPowerOverused(const std::string &module, uint32_t level)
176{
177    std::lock_guard<std::mutex> lock(mutex_);
178    STANDBYSERVICE_LOGI("[PowerOverused] StandbyClient: power overused, module name: %{public}s, "
179        "level: %{public}u.", module.c_str(), level);
180
181    if (!GetStandbyServiceProxy()) {
182        STANDBYSERVICE_LOGE("get standby service proxy failed");
183        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
184    }
185    return standbyServiceProxy_->ReportPowerOverused(module, level);
186}
187
188ErrCode StandbyServiceClient::ReportDeviceStateChanged(DeviceStateType type, bool enabled)
189{
190    std::lock_guard<std::mutex> lock(mutex_);
191    STANDBYSERVICE_LOGI("device state changed, state type: %{public}d, enabled: %{public}d",
192        static_cast<int32_t>(type), enabled);
193    if (!GetStandbyServiceProxy()) {
194        STANDBYSERVICE_LOGE("get standby service proxy failed");
195        return ERR_STANDBY_SERVICE_NOT_CONNECTED;
196    }
197    return standbyServiceProxy_->ReportDeviceStateChanged(type, enabled);
198}
199
200bool StandbyServiceClient::GetStandbyServiceProxy()
201{
202    if (standbyServiceProxy_ != nullptr) {
203        return true;
204    }
205    sptr<ISystemAbilityManager> systemAbilityManager =
206        SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
207    if (systemAbilityManager == nullptr) {
208        STANDBYSERVICE_LOGE("get standby service proxy failed");
209        return false;
210    }
211
212    sptr<IRemoteObject> remoteObject =
213        systemAbilityManager->GetSystemAbility(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID);
214    if (remoteObject == nullptr) {
215        STANDBYSERVICE_LOGE("get standby service system ability failed");
216        return false;
217    }
218
219    standbyServiceProxy_ = iface_cast<IStandbyService>(remoteObject);
220    if ((standbyServiceProxy_ == nullptr) || (standbyServiceProxy_->AsObject() == nullptr)) {
221        STANDBYSERVICE_LOGE("standby service proxy iface_cast from remote Onject failed");
222        return false;
223    }
224
225    deathRecipient_ = new (std::nothrow) StandbyServiceDeathRecipient(*this);
226    if (deathRecipient_ == nullptr) {
227        return false;
228    }
229
230    standbyServiceProxy_->AsObject()->AddDeathRecipient(deathRecipient_);
231    return true;
232}
233
234void StandbyServiceClient::ResetStandbyServiceClient()
235{
236    std::lock_guard<std::mutex> lock(mutex_);
237    if ((standbyServiceProxy_ != nullptr)&& (standbyServiceProxy_->AsObject() != nullptr)) {
238        standbyServiceProxy_->AsObject()->RemoveDeathRecipient(deathRecipient_);
239    }
240    standbyServiceProxy_ = nullptr;
241}
242
243StandbyServiceClient::StandbyServiceDeathRecipient::StandbyServiceDeathRecipient(
244    StandbyServiceClient& standbyServiceClient)
245    : standbyServiceClient_(standbyServiceClient) {}
246
247StandbyServiceClient::StandbyServiceDeathRecipient::~StandbyServiceDeathRecipient() {}
248
249void StandbyServiceClient::StandbyServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
250{
251    standbyServiceClient_.ResetStandbyServiceClient();
252}
253}  // namespace DevStandbyMgr
254}  // namespace OHOS