1 /*
2 * Copyright (c) 2025-2025 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 #include "suspend_manager_base_client.h"
16 #include "nlohmann/json.hpp"
17 #include "iservice_registry.h"
18 #include "system_ability_definition.h"
19 #include "suspend_manager_base_log.h"
20
21 namespace OHOS {
22 namespace ResourceSchedule {
GetInstance()23 SuspendManagerBaseClient &SuspendManagerBaseClient::GetInstance()
24 {
25 static SuspendManagerBaseClient instance;
26 return instance;
27 }
28
GetSuspendStateByUid(const int32_t uid,bool & isFrozen)29 ErrCode SuspendManagerBaseClient::GetSuspendStateByUid(const int32_t uid, bool &isFrozen)
30 {
31 std::lock_guard<std::mutex> lock(mutex_);
32 if (!GetSuspendManagerProxy()) {
33 SUSPEND_MSG_LOGE("Failed to register suspend observer, get proxy err.");
34 return ERR_INVALID_OPERATION;
35 }
36 int32_t funcResult = ERR_OK;
37 suspendManagerBaseProxy_->GetSuspendStateByUid(uid, isFrozen, funcResult);
38 return funcResult;
39 }
40
GetSuspendStateByPid(const int32_t pid,bool & isFrozen)41 ErrCode SuspendManagerBaseClient::GetSuspendStateByPid(const int32_t pid, bool &isFrozen)
42 {
43 std::lock_guard<std::mutex> lock(mutex_);
44 if (!GetSuspendManagerProxy()) {
45 SUSPEND_MSG_LOGE("Failed to register suspend observer, get proxy err.");
46 return ERR_INVALID_OPERATION;
47 }
48 int32_t funcResult = ERR_OK;
49 suspendManagerBaseProxy_->GetSuspendStateByPid(pid, isFrozen, funcResult);
50 return funcResult;
51 }
52
ResetClient()53 __attribute__((no_sanitize("cfi"))) void SuspendManagerBaseClient::ResetClient()
54 {
55 std::lock_guard<std::mutex> lock(mutex_);
56 if (suspendManagerBaseProxy_ && suspendManagerBaseProxy_->AsObject()) {
57 suspendManagerBaseProxy_->AsObject()->RemoveDeathRecipient(recipient_);
58 }
59 suspendManagerBaseProxy_ = nullptr;
60 recipient_ = nullptr;
61 }
62
~SuspendManagerBaseClient()63 SuspendManagerBaseClient::~SuspendManagerBaseClient()
64 {
65 SUSPEND_MSG_LOGI("libsuspend_manager_base_client.z.so will remove, clear death recipient!");
66 ResetClient();
67 }
68
SuspendManagerDeathRecipient(SuspendManagerBaseClient & suspendManagerBaseClient)69 SuspendManagerBaseClient::SuspendManagerDeathRecipient::SuspendManagerDeathRecipient(
70 SuspendManagerBaseClient &suspendManagerBaseClient) : suspendManagerBaseClient_(suspendManagerBaseClient) {}
71
~SuspendManagerDeathRecipient()72 SuspendManagerBaseClient::SuspendManagerDeathRecipient::~SuspendManagerDeathRecipient() {}
73
OnRemoteDied(const wptr<IRemoteObject> & remote)74 void SuspendManagerBaseClient::SuspendManagerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
75 {
76 suspendManagerBaseClient_.ResetClient();
77 }
78
GetSuspendManagerProxy()79 bool SuspendManagerBaseClient::GetSuspendManagerProxy()
80 {
81 if (suspendManagerBaseProxy_) {
82 return true;
83 }
84 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
85 if (!samgr) {
86 SUSPEND_MSG_LOGE("Failed to get SystemAbilityManager.");
87 return false;
88 }
89 sptr<IRemoteObject> object = samgr->CheckSystemAbility(RES_SCHED_SYS_ABILITY_ID);
90 if (!object) {
91 SUSPEND_MSG_LOGE("Failed to get SystemAbility[1901].");
92 return false;
93 }
94
95 suspendManagerBaseProxy_ = iface_cast<IResSchedService>(object);
96 if (!suspendManagerBaseProxy_ || !suspendManagerBaseProxy_->AsObject()) {
97 SUSPEND_MSG_LOGE("Failed to get SystemAbility.");
98 return false;
99 }
100
101 recipient_ = new (std::nothrow) SuspendManagerDeathRecipient(*this);
102 if (!recipient_) {
103 return false;
104 }
105 suspendManagerBaseProxy_->AsObject()->AddDeathRecipient(recipient_);
106
107 return true;
108 }
109
RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer)110 ErrCode SuspendManagerBaseClient::RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer)
111 {
112 if (observer == nullptr) {
113 SUSPEND_MSG_LOGE("Failed to register suspend observer, observer is null.");
114 return ERR_INVALID_VALUE;
115 }
116
117 std::lock_guard<std::mutex> lock(mutex_);
118 if (!GetSuspendManagerProxy()) {
119 SUSPEND_MSG_LOGE("Failed to register suspend observer, get proxy err.");
120 return ERR_INVALID_OPERATION;
121 }
122 int32_t funcResult = ERR_OK;
123 suspendManagerBaseProxy_->RegisterSuspendObserver(observer, funcResult);
124 return funcResult;
125 }
126
UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer)127 ErrCode SuspendManagerBaseClient::UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer)
128 {
129 if (observer == nullptr) {
130 SUSPEND_MSG_LOGE("Failed to unregister suspend observer, observer is null.");
131 return ERR_INVALID_VALUE;
132 }
133
134 std::lock_guard<std::mutex> lock(mutex_);
135 if (!GetSuspendManagerProxy()) {
136 SUSPEND_MSG_LOGE("Failed to unregister suspend observer, get proxy err.");
137 return ERR_INVALID_OPERATION;
138 }
139 int32_t funcResult = ERR_OK;
140 suspendManagerBaseProxy_->UnregisterSuspendObserver(observer, funcResult);
141 return funcResult;
142 }
143 } // namespace ResourceSchedule
144 } // namespace OHOS