1 /*
2 * Copyright (c) 2021 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 "ohos_account_kits_impl.h"
17 #include "account_error_no.h"
18 #include "account_log_wrapper.h"
19 #include "account_proxy.h"
20 #include "if_system_ability_manager.h"
21 #include "system_ability_status_change_listener.h"
22
23 namespace OHOS {
24 namespace AccountSA {
ohosCallbackFunc()25 std::function<void(int32_t, const std::string &)> ohosCallbackFunc()
26 {
27 return [](int32_t systemAbilityId, const std::string &dvid) {
28 if (systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
29 OhosAccountKitsImpl::GetInstance().RestoreSubscribe();
30 }
31 };
32 }
33
GetInstance()34 OhosAccountKitsImpl &OhosAccountKitsImpl::GetInstance()
35 {
36 static OhosAccountKitsImpl *instance = new (std::nothrow) OhosAccountKitsImpl();
37 return *instance;
38 }
39
ResetService(const wptr<IRemoteObject> & remote)40 void OhosAccountKitsImpl::ResetService(const wptr<IRemoteObject>& remote)
41 {
42 ACCOUNT_LOGI("Remote is dead, reset service instance");
43
44 std::lock_guard<std::mutex> lock(accountProxyLock_);
45 if (accountProxy_ != nullptr) {
46 sptr<IRemoteObject> object = accountProxy_->AsObject();
47 if ((object != nullptr) && (remote == object)) {
48 object->RemoveDeathRecipient(deathRecipient_);
49 accountProxy_ = nullptr;
50 }
51 }
52 if (!isSubscribeSA_) {
53 isSubscribeSA_ = true;
54 SubscribeSystemAbility(ohosCallbackFunc());
55 }
56 }
57
GetService()58 sptr<IAccount> OhosAccountKitsImpl::GetService()
59 {
60 std::lock_guard<std::mutex> lock(accountProxyLock_);
61 if (accountProxy_ != nullptr) {
62 return accountProxy_;
63 }
64
65 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
66 if (samgr == nullptr) {
67 ACCOUNT_LOGE("Get samgr failed");
68 return nullptr;
69 }
70 sptr<IRemoteObject> object = samgr->GetSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN);
71 if (object == nullptr) {
72 ACCOUNT_LOGE("Get account object from samgr failed");
73 return nullptr;
74 }
75
76 if (deathRecipient_ == nullptr) {
77 deathRecipient_ = new (std::nothrow) DeathRecipient();
78 if (deathRecipient_ == nullptr) {
79 ACCOUNT_LOGE("deathRecipient_ is nullptr.");
80 return nullptr;
81 }
82 }
83
84 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
85 ACCOUNT_LOGE("Failed to add death recipient");
86 }
87
88 accountProxy_ = iface_cast<AccountProxy>(object);
89 if (accountProxy_ == nullptr) {
90 ACCOUNT_LOGE("account iface_cast failed");
91 }
92 return accountProxy_;
93 }
94
OnRemoteDied(const wptr<IRemoteObject> & remote)95 void OhosAccountKitsImpl::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
96 {
97 OhosAccountKitsImpl::GetInstance().ResetService(remote);
98 }
99
UpdateOhosAccountInfo(const std::string & accountName,const std::string & uid,const std::string & eventStr)100 ErrCode OhosAccountKitsImpl::UpdateOhosAccountInfo(const std::string& accountName, const std::string& uid,
101 const std::string& eventStr)
102 {
103 auto accountProxy = GetService();
104 if (accountProxy == nullptr) {
105 ACCOUNT_LOGE("Get proxy failed");
106 return ERR_ACCOUNT_COMMON_GET_PROXY;
107 }
108 return accountProxy->UpdateOhosAccountInfo(accountName, uid, eventStr);
109 }
110
SetOhosAccountInfo(const OhosAccountInfo & ohosAccountInfo,const std::string & eventStr)111 ErrCode OhosAccountKitsImpl::SetOhosAccountInfo(
112 const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
113 {
114 auto accountProxy = GetService();
115 if (accountProxy == nullptr) {
116 ACCOUNT_LOGE("Get proxy failed");
117 return ERR_ACCOUNT_COMMON_GET_PROXY;
118 }
119 if (!ohosAccountInfo.IsValid()) {
120 ACCOUNT_LOGE("OhosAccountInfo check failed");
121 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
122 }
123 return accountProxy->SetOhosAccountInfo(ohosAccountInfo, eventStr);
124 }
125
SetOsAccountDistributedInfo(const int32_t localId,const OhosAccountInfo & ohosAccountInfo,const std::string & eventStr)126 ErrCode OhosAccountKitsImpl::SetOsAccountDistributedInfo(
127 const int32_t localId, const OhosAccountInfo& ohosAccountInfo, const std::string& eventStr)
128 {
129 auto accountProxy = GetService();
130 if (accountProxy == nullptr) {
131 ACCOUNT_LOGE("Get proxy failed");
132 return ERR_ACCOUNT_COMMON_GET_PROXY;
133 }
134 if (!ohosAccountInfo.IsValid()) {
135 ACCOUNT_LOGE("OhosAccountInfo check failed");
136 return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
137 }
138 return accountProxy->SetOsAccountDistributedInfo(localId, ohosAccountInfo, eventStr);
139 }
140
QueryOhosAccountInfo()141 std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOhosAccountInfo()
142 {
143 OhosAccountInfo accountInfo;
144 ErrCode result = QueryOhosAccountInfo(accountInfo);
145 return std::make_pair(result == ERR_OK, accountInfo);
146 }
147
QueryDistributedVirtualDeviceId(std::string & dvid)148 ErrCode OhosAccountKitsImpl::QueryDistributedVirtualDeviceId(std::string &dvid)
149 {
150 auto accountProxy = GetService();
151 if (accountProxy == nullptr) {
152 ACCOUNT_LOGE("Get proxy failed");
153 return ERR_ACCOUNT_COMMON_GET_PROXY;
154 }
155
156 return accountProxy->QueryDistributedVirtualDeviceId(dvid);
157 }
158
QueryDistributedVirtualDeviceId(const std::string & bundleName,int32_t localId,std::string & dvid)159 ErrCode OhosAccountKitsImpl::QueryDistributedVirtualDeviceId(const std::string &bundleName, int32_t localId,
160 std::string &dvid)
161 {
162 auto accountProxy = GetService();
163 if (accountProxy == nullptr) {
164 ACCOUNT_LOGE("Get proxy failed");
165 return ERR_ACCOUNT_COMMON_GET_PROXY;
166 }
167
168 return accountProxy->QueryDistributedVirtualDeviceId(bundleName, localId, dvid);
169 }
170
QueryOhosAccountInfo(OhosAccountInfo & accountInfo)171 ErrCode OhosAccountKitsImpl::QueryOhosAccountInfo(OhosAccountInfo &accountInfo)
172 {
173 auto accountProxy = GetService();
174 if (accountProxy == nullptr) {
175 ACCOUNT_LOGE("Get proxy failed");
176 return ERR_ACCOUNT_COMMON_GET_PROXY;
177 }
178
179 return accountProxy->QueryOhosAccountInfo(accountInfo);
180 }
181
GetOhosAccountInfo(OhosAccountInfo & accountInfo)182 ErrCode OhosAccountKitsImpl::GetOhosAccountInfo(OhosAccountInfo &accountInfo)
183 {
184 auto accountProxy = GetService();
185 if (accountProxy == nullptr) {
186 ACCOUNT_LOGE("Get proxy failed");
187 return ERR_ACCOUNT_COMMON_GET_PROXY;
188 }
189
190 return accountProxy->GetOhosAccountInfo(accountInfo);
191 }
192
GetOsAccountDistributedInfo(int32_t localId,OhosAccountInfo & accountInfo)193 ErrCode OhosAccountKitsImpl::GetOsAccountDistributedInfo(int32_t localId, OhosAccountInfo &accountInfo)
194 {
195 auto accountProxy = GetService();
196 if (accountProxy == nullptr) {
197 ACCOUNT_LOGE("Get proxy failed");
198 return ERR_ACCOUNT_COMMON_GET_PROXY;
199 }
200
201 return accountProxy->GetOsAccountDistributedInfo(localId, accountInfo);
202 }
203
QueryOsAccountDistributedInfo(std::int32_t localId)204 std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOsAccountDistributedInfo(std::int32_t localId)
205 {
206 OhosAccountInfo accountInfo;
207 ErrCode result = QueryOsAccountDistributedInfo(localId, accountInfo);
208 return std::make_pair(result == ERR_OK, accountInfo);
209 }
210
QueryOsAccountDistributedInfo(std::int32_t localId,OhosAccountInfo & accountInfo)211 ErrCode OhosAccountKitsImpl::QueryOsAccountDistributedInfo(std::int32_t localId, OhosAccountInfo &accountInfo)
212 {
213 auto accountProxy = GetService();
214 if (accountProxy == nullptr) {
215 ACCOUNT_LOGE("Get proxy failed");
216 return ERR_ACCOUNT_COMMON_GET_PROXY;
217 }
218
219 return accountProxy->QueryOsAccountDistributedInfo(localId, accountInfo);
220 }
221
QueryDeviceAccountId(std::int32_t & accountId)222 ErrCode OhosAccountKitsImpl::QueryDeviceAccountId(std::int32_t& accountId)
223 {
224 auto accountProxy = GetService();
225 if (accountProxy == nullptr) {
226 ACCOUNT_LOGE("Get proxy failed");
227 return ERR_ACCOUNT_COMMON_GET_PROXY;
228 }
229
230 return accountProxy->QueryDeviceAccountId(accountId);
231 }
232
SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback)233 ErrCode OhosAccountKitsImpl::SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
234 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback)
235 {
236 ACCOUNT_LOGI("Subscribe distributed account event in client.");
237 if (callback == nullptr) {
238 ACCOUNT_LOGE("Callback is nullptr.");
239 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
240 }
241
242 auto accountProxy = GetService();
243 if (accountProxy == nullptr) {
244 ACCOUNT_LOGE("Get proxy failed.");
245 return ERR_ACCOUNT_COMMON_GET_PROXY;
246 }
247
248 sptr<IRemoteObject> listener = nullptr;
249 ErrCode result = CreateDistributedAccountEventService(type, callback, listener);
250
251 if (listener == nullptr) {
252 ACCOUNT_LOGE("Create event service failed.");
253 return ERR_OHOSACCOUNT_KIT_SUBSCRIBE_ERROR;
254 }
255 if (result == ERR_OHOSACCOUNT_KIT_CALLBACK_ALREADY_REGISTERED_ERROR) {
256 ACCOUNT_LOGE("Callback already registered.");
257 return ERR_OK;
258 }
259
260 result = accountProxy->SubscribeDistributedAccountEvent(type, listener);
261 if (result != ERR_OK) {
262 std::lock_guard<std::mutex> lock(eventListenersMutex_);
263 eventListeners_.erase(callback);
264 }
265 return result;
266 }
267
UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback)268 ErrCode OhosAccountKitsImpl::UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
269 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback)
270 {
271 ACCOUNT_LOGI("Unsubscribe distributed account event in client.");
272 if (callback == nullptr) {
273 ACCOUNT_LOGE("Callback is nullptr.");
274 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
275 }
276
277 auto accountProxy = GetService();
278 if (accountProxy == nullptr) {
279 ACCOUNT_LOGE("Get proxy failed.");
280 return ERR_ACCOUNT_COMMON_GET_PROXY;
281 }
282
283 std::lock_guard<std::mutex> lock(eventListenersMutex_);
284 auto eventListener = eventListeners_.find(callback);
285 if (eventListener == eventListeners_.end()) {
286 ACCOUNT_LOGE("No specified callback has been registered.");
287 return ERR_OHOSACCOUNT_KIT_NO_SPECIFIED_CALLBACK_HAS_BEEN_REGISTERED;
288 }
289
290 if (!(eventListener->second->IsTypeExist(type))) {
291 ACCOUNT_LOGE("No specified callback has been registered.");
292 return ERR_OHOSACCOUNT_KIT_NO_SPECIFIED_CALLBACK_HAS_BEEN_REGISTERED;
293 }
294 ErrCode result = accountProxy->UnsubscribeDistributedAccountEvent(type, eventListener->second->AsObject());
295 if (result == ERR_OK) {
296 eventListener->second->DeleteType(type);
297 if (eventListener->second->GetTypeSize() == 0) {
298 eventListeners_.erase(eventListener);
299 }
300 }
301 return result;
302 }
303
CreateDistributedAccountEventService(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,const std::shared_ptr<DistributedAccountSubscribeCallback> & callback,sptr<IRemoteObject> & subscribeListener)304 ErrCode OhosAccountKitsImpl::CreateDistributedAccountEventService(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
305 const std::shared_ptr<DistributedAccountSubscribeCallback> &callback,
306 sptr<IRemoteObject> &subscribeListener)
307 {
308 if (callback == nullptr) {
309 ACCOUNT_LOGE("Callback is nullptr");
310 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
311 }
312
313 std::lock_guard<std::mutex> lock(eventListenersMutex_);
314 auto eventListener = eventListeners_.find(callback);
315 if (eventListener != eventListeners_.end()) {
316 subscribeListener = eventListener->second->AsObject();
317 if (eventListener->second->IsTypeExist(type)) {
318 ACCOUNT_LOGI("Callback already has distributed account event listener.");
319 return ERR_OHOSACCOUNT_KIT_CALLBACK_ALREADY_REGISTERED_ERROR;
320 }
321 eventListener->second->AddType(type);
322 return ERR_OK;
323 }
324 if (eventListeners_.size() == Constants::DISTRIBUTED_SUBSCRIBER_MAX_SIZE) {
325 ACCOUNT_LOGE("The maximum number of eventListeners has been reached.");
326 return ERR_OHOSACCOUNT_KIT_SUBSCRIBE_MAX_SIZE_ERROR;
327 }
328 sptr<DistributedAccountEventService> listener = new (std::nothrow) DistributedAccountEventService(
329 type, callback);
330 if (listener == nullptr) {
331 ACCOUNT_LOGE("Memory allocation for listener failed!");
332 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
333 }
334 subscribeListener = listener->AsObject();
335 eventListeners_[callback] = listener;
336 return ERR_OK;
337 }
338
RestoreSubscribe()339 void OhosAccountKitsImpl::RestoreSubscribe()
340 {
341 auto accountProxy = GetService();
342 if (accountProxy == nullptr) {
343 ACCOUNT_LOGE("Get proxy failed.");
344 return ;
345 }
346
347 std::lock_guard<std::mutex> lock(eventListenersMutex_);
348 for (auto it = eventListeners_.begin(); it != eventListeners_.end(); ++it) {
349 std::vector<DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE> typeList;
350 it->second->GetAllType(typeList);
351 for (auto type : typeList) {
352 ErrCode subscribeState = accountProxy->SubscribeDistributedAccountEvent(type, it->second);
353 if (subscribeState != ERR_OK) {
354 ACCOUNT_LOGE("Restore subscribe failed, res=%{public}d.", subscribeState);
355 }
356 }
357 }
358 }
359
GetDeviceAccountIdByUID(std::int32_t & uid)360 std::int32_t OhosAccountKitsImpl::GetDeviceAccountIdByUID(std::int32_t& uid)
361 {
362 std::int32_t accountID = uid / UID_TRANSFORM_DIVISOR;
363 return accountID;
364 }
365
SubscribeSystemAbility(const DomainAccountSubscribeSACallbackFunc & callbackFunc)366 ErrCode OhosAccountKitsImpl::SubscribeSystemAbility(const DomainAccountSubscribeSACallbackFunc& callbackFunc)
367 {
368 sptr<ISystemAbilityStatusChange> statusChangeListener =
369 new (std::nothrow) SystemAbilityStatusChangeListener(callbackFunc);
370 if (statusChangeListener == nullptr) {
371 ACCOUNT_LOGE("statusChangeListener is nullptr");
372 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
373 }
374 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
375 if (samgrProxy == NULL) {
376 ACCOUNT_LOGE("samgrProxy is NULL");
377 return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
378 }
379 int32_t ret = samgrProxy->SubscribeSystemAbility(SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN, statusChangeListener);
380 if (ret != ERR_OK) {
381 ACCOUNT_LOGE("SubscribeSystemAbility is failed");
382 return ret;
383 }
384 return ERR_OK;
385 }
386
GetDomainAccountService()387 sptr<IRemoteObject> OhosAccountKitsImpl::GetDomainAccountService()
388 {
389 auto accountProxy = GetService();
390 if (accountProxy == nullptr) {
391 ACCOUNT_LOGE("Get proxy failed");
392 return nullptr;
393 }
394 return accountProxy->GetDomainAccountService();
395 }
396
GetOsAccountService()397 sptr<IRemoteObject> OhosAccountKitsImpl::GetOsAccountService()
398 {
399 auto accountProxy = GetService();
400 if (accountProxy == nullptr) {
401 ACCOUNT_LOGE("Get proxy failed");
402 return nullptr;
403 }
404 return accountProxy->GetOsAccountService();
405 }
406
GetAppAccountService()407 sptr<IRemoteObject> OhosAccountKitsImpl::GetAppAccountService()
408 {
409 auto accountProxy = GetService();
410 if (accountProxy == nullptr) {
411 ACCOUNT_LOGE("Get proxy failed");
412 return nullptr;
413 }
414 return accountProxy->GetAppAccountService();
415 }
416
GetAccountIAMService()417 sptr<IRemoteObject> OhosAccountKitsImpl::GetAccountIAMService()
418 {
419 auto accountProxy = GetService();
420 if (accountProxy == nullptr) {
421 ACCOUNT_LOGE("Get proxy failed");
422 return nullptr;
423 }
424 return accountProxy->GetAccountIAMService();
425 }
426 } // namespace AccountSA
427 } // namespace OHOS
428