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 "oaid_service_client.h"
17
18 #include <cinttypes>
19 #include <mutex>
20
21 #include "oaid_common.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 #include "system_ability_load_callback_stub.h"
25
26 namespace OHOS {
27 namespace Cloud {
28 namespace {
29 static const int32_t OAID_SYSTME_ID = 6101; // The system component ID of the OAID is 6101.
30
31 static const std::string OAID_ALLZERO_STR = "00000000-0000-0000-0000-000000000000";
32
33 /**
34 * load time out: 10s
35 */
36 static const int8_t LOAD_TIME_OUT = 10;
37
38 static const int8_t RESET_OAID_DEFAULT_CODE = 0;
39 } // namespace
40
41 std::mutex OAIDServiceClient::instanceLock_;
42 sptr<OAIDServiceClient> OAIDServiceClient::instance_;
43
44 class OAIDServiceLoadCallback : public SystemAbilityLoadCallbackStub {
45 public:
OnLoadSystemAbilitySuccess(int32_t systemAbilityId,const sptr<IRemoteObject> & remoteObject)46 void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr<IRemoteObject>& remoteObject) override
47 {
48 if (systemAbilityId != OAID_SYSTME_ID) {
49 OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
50 return;
51 }
52
53 OAIDServiceClient::GetInstance()->LoadServerSuccess(remoteObject);
54 }
55
OnLoadSystemAbilityFail(int32_t systemAbilityId)56 void OnLoadSystemAbilityFail(int32_t systemAbilityId) override
57 {
58 if (systemAbilityId != OAID_SYSTME_ID) {
59 OAID_HILOGE(OAID_MODULE_SERVICE, "Start systemAbility is not oaid service: %{public}d.", systemAbilityId);
60 return;
61 }
62
63 OAIDServiceClient::GetInstance()->LoadServerFail();
64 }
65 };
66
OAIDServiceClient()67 OAIDServiceClient::OAIDServiceClient()
68 {
69 deathRecipient_ = new (std::nothrow) OAIDSaDeathRecipient();
70 }
71
~OAIDServiceClient()72 OAIDServiceClient::~OAIDServiceClient()
73 {
74 if (oaidServiceProxy_ != nullptr) {
75 auto remoteObject = oaidServiceProxy_->AsObject();
76 if (remoteObject != nullptr && deathRecipient_ != nullptr) {
77 remoteObject->RemoveDeathRecipient(deathRecipient_);
78 }
79 }
80 }
81
GetInstance()82 sptr<OAIDServiceClient> OAIDServiceClient::GetInstance()
83 {
84 if (instance_ == nullptr) {
85 std::lock_guard<std::mutex> autoLock(instanceLock_);
86 if (instance_ == nullptr) {
87 instance_ = new OAIDServiceClient;
88 }
89 }
90 return instance_;
91 }
92
LoadService()93 bool OAIDServiceClient::LoadService()
94 {
95 if (loadServiceReady_) {
96 return true;
97 }
98
99 std::lock_guard<std::mutex> lock(loadServiceLock_);
100 if (loadServiceReady_) {
101 return true;
102 }
103
104 sptr<ISystemAbilityManager> systemAbilityManager =
105 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
106 if (systemAbilityManager == nullptr) {
107 OAID_HILOGE(OAID_MODULE_CLIENT, "Getting SystemAbilityManager failed.");
108 return false;
109 }
110
111 sptr<OAIDServiceLoadCallback> loadCallback = new (std::nothrow) OAIDServiceLoadCallback();
112 if (loadCallback == nullptr) {
113 OAID_HILOGE(OAID_MODULE_CLIENT, "New OAIDServiceLoadCallback failed.");
114 return false;
115 }
116
117 int32_t result = systemAbilityManager->LoadSystemAbility(OAID_SYSTME_ID, loadCallback);
118 if (result != ERR_OK) {
119 OAID_HILOGE(
120 OAID_MODULE_CLIENT, "LoadSystemAbility %{public}d failed, result: %{public}d.", OAID_SYSTME_ID, result);
121 return false;
122 }
123
124 std::unique_lock<std::mutex> conditionLock(loadServiceConditionLock_);
125 auto waitStatus = loadServiceCondition_.wait_for(
126 conditionLock, std::chrono::seconds(LOAD_TIME_OUT), [this]() { return loadServiceReady_; });
127 if (!waitStatus) {
128 OAID_HILOGE(OAID_MODULE_CLIENT, "LoadSystemAbility timeout.");
129 return false;
130 }
131
132 return true;
133 }
134
GetOAID()135 std::string OAIDServiceClient::GetOAID()
136 {
137 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
138
139 if (!LoadService()) {
140 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
141 LoadService();
142 }
143
144 if (oaidServiceProxy_ == nullptr) {
145 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
146 return OAID_ALLZERO_STR;
147 }
148
149 std::unique_lock<std::mutex> lock(getOaidProxyMutex_);
150 auto oaid = oaidServiceProxy_->GetOAID();
151 if (oaid == "") {
152 OAID_HILOGE(OAID_MODULE_CLIENT, "Get OAID failed.");
153 return OAID_ALLZERO_STR;
154 }
155 OAID_HILOGI(OAID_MODULE_SERVICE, "Get OAID id %{public}zu.", oaid.size());
156 return oaid;
157 }
158
ResetOAID()159 int32_t OAIDServiceClient::ResetOAID()
160 {
161 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
162
163 if (!LoadService()) {
164 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
165 LoadService();
166 }
167
168 if (oaidServiceProxy_ == nullptr) {
169 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
170 return RESET_OAID_DEFAULT_CODE;
171 }
172
173 int32_t resetResult = oaidServiceProxy_->ResetOAID();
174 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
175
176 return resetResult;
177 }
178
RegisterObserver(const sptr<IRemoteConfigObserver> & observer)179 int32_t OAIDServiceClient::RegisterObserver(const sptr<IRemoteConfigObserver>& observer)
180 {
181 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin RegisterObserver.");
182
183 if (!LoadService()) {
184 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
185 LoadService();
186 }
187
188 if (oaidServiceProxy_ == nullptr) {
189 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
190 return RESET_OAID_DEFAULT_CODE;
191 }
192
193 int32_t resetResult = oaidServiceProxy_->RegisterObserver(observer);
194 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
195
196 return resetResult;
197 }
198
OnRemoteSaDied(const wptr<IRemoteObject> & remote)199 void OAIDServiceClient::OnRemoteSaDied(const wptr<IRemoteObject>& remote)
200 {
201 OAID_HILOGE(OAID_MODULE_CLIENT, "OnRemoteSaDied");
202 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
203 if (oaidServiceProxy_ != nullptr) {
204 auto remoteObject = oaidServiceProxy_->AsObject();
205 if (remoteObject != nullptr && deathRecipient_ != nullptr) {
206 remoteObject->RemoveDeathRecipient(deathRecipient_);
207 }
208 oaidServiceProxy_ = nullptr;
209 }
210 loadServiceReady_ = false;
211 }
212
LoadServerSuccess(const sptr<IRemoteObject> & remoteObject)213 void OAIDServiceClient::LoadServerSuccess(const sptr<IRemoteObject>& remoteObject)
214 {
215 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
216 if (remoteObject == nullptr) {
217 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service is null.");
218 return;
219 }
220
221 if (deathRecipient_ != nullptr) {
222 remoteObject->AddDeathRecipient(deathRecipient_);
223 }
224 oaidServiceProxy_ = iface_cast<IOAIDService>(remoteObject);
225 loadServiceReady_ = true;
226 loadServiceCondition_.notify_one();
227 OAID_HILOGI(OAID_MODULE_CLIENT, "Load OAID service success.");
228 }
229
LoadServerFail()230 void OAIDServiceClient::LoadServerFail()
231 {
232 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
233 loadServiceReady_ = false;
234 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service fail.");
235 }
236
OAIDSaDeathRecipient()237 OAIDSaDeathRecipient::OAIDSaDeathRecipient() {}
238
OnRemoteDied(const wptr<IRemoteObject> & object)239 void OAIDSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
240 {
241 OAID_HILOGW(OAID_MODULE_CLIENT, "Remote systemAbility died.");
242 OAIDServiceClient::GetInstance()->OnRemoteSaDied(object);
243 }
244 } // namespace Cloud
245 } // namespace OHOS
246