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 auto oaid = oaidServiceProxy_->GetOAID();
150 if (oaid == "") {
151 OAID_HILOGE(OAID_MODULE_CLIENT, "Get OAID failed.");
152 return OAID_ALLZERO_STR;
153 }
154 OAID_HILOGI(OAID_MODULE_SERVICE, "Get OAID id %{public}zu.", oaid.size());
155 return oaid;
156 }
157
ResetOAID()158 int32_t OAIDServiceClient::ResetOAID()
159 {
160 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin.");
161
162 if (!LoadService()) {
163 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
164 LoadService();
165 }
166
167 if (oaidServiceProxy_ == nullptr) {
168 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
169 return RESET_OAID_DEFAULT_CODE;
170 }
171
172 int32_t resetResult = oaidServiceProxy_->ResetOAID();
173 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
174
175 return resetResult;
176 }
177
RegisterObserver(const sptr<IRemoteConfigObserver> & observer)178 int32_t OAIDServiceClient::RegisterObserver(const sptr<IRemoteConfigObserver>& observer)
179 {
180 OAID_HILOGI(OAID_MODULE_CLIENT, "Begin RegisterObserver.");
181
182 if (!LoadService()) {
183 OAID_HILOGW(OAID_MODULE_CLIENT, "Redo load oaid service.");
184 LoadService();
185 }
186
187 if (oaidServiceProxy_ == nullptr) {
188 OAID_HILOGE(OAID_MODULE_CLIENT, "Quit because redoing load oaid service failed.");
189 return RESET_OAID_DEFAULT_CODE;
190 }
191
192 int32_t resetResult = oaidServiceProxy_->RegisterObserver(observer);
193 OAID_HILOGI(OAID_MODULE_SERVICE, "End.resetResult = %{public}d", resetResult);
194
195 return resetResult;
196 }
197
OnRemoteSaDied(const wptr<IRemoteObject> & remote)198 void OAIDServiceClient::OnRemoteSaDied(const wptr<IRemoteObject>& remote)
199 {
200 OAID_HILOGE(OAID_MODULE_CLIENT, "OnRemoteSaDied");
201 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
202 if (oaidServiceProxy_ != nullptr) {
203 auto remoteObject = oaidServiceProxy_->AsObject();
204 if (remoteObject != nullptr && deathRecipient_ != nullptr) {
205 remoteObject->RemoveDeathRecipient(deathRecipient_);
206 }
207 oaidServiceProxy_ = nullptr;
208 }
209 loadServiceReady_ = false;
210 }
211
LoadServerSuccess(const sptr<IRemoteObject> & remoteObject)212 void OAIDServiceClient::LoadServerSuccess(const sptr<IRemoteObject>& remoteObject)
213 {
214 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
215 if (remoteObject == nullptr) {
216 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service is null.");
217 return;
218 }
219
220 if (deathRecipient_ != nullptr) {
221 remoteObject->AddDeathRecipient(deathRecipient_);
222 }
223 oaidServiceProxy_ = iface_cast<IOAIDService>(remoteObject);
224 loadServiceReady_ = true;
225 loadServiceCondition_.notify_one();
226 OAID_HILOGI(OAID_MODULE_CLIENT, "Load OAID service success.");
227 }
228
LoadServerFail()229 void OAIDServiceClient::LoadServerFail()
230 {
231 std::unique_lock<std::mutex> lock(loadServiceConditionLock_);
232 loadServiceReady_ = false;
233 OAID_HILOGE(OAID_MODULE_CLIENT, "Load OAID service fail.");
234 }
235
OAIDSaDeathRecipient()236 OAIDSaDeathRecipient::OAIDSaDeathRecipient() {}
237
OnRemoteDied(const wptr<IRemoteObject> & object)238 void OAIDSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
239 {
240 OAID_HILOGW(OAID_MODULE_CLIENT, "Remote systemAbility died.");
241 OAIDServiceClient::GetInstance()->OnRemoteSaDied(object);
242 }
243 } // namespace Cloud
244 } // namespace OHOS
245