• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "account_iam_client.h"
17 
18 #include "accesstoken_kit.h"
19 #include "account_error_no.h"
20 #include "account_iam_callback_service.h"
21 #include "account_log_wrapper.h"
22 #include "account_proxy.h"
23 #include "account_permission_manager.h"
24 #include "ipc_skeleton.h"
25 #include "ohos_account_kits_impl.h"
26 #include "os_account_manager.h"
27 #ifdef HAS_PIN_AUTH_PART
28 #include "pinauth_register.h"
29 #endif
30 
31 namespace OHOS {
32 namespace AccountSA {
33 namespace {
34 const std::string PERMISSION_ACCESS_PIN_AUTH = "ohos.permission.ACCESS_PIN_AUTH";
35 const std::string PERMISSION_MANAGE_USER_IDM = "ohos.permission.MANAGE_USER_IDM";
36 const std::string PERMISSION_ACCESS_USER_AUTH_INTERNAL = "ohos.permission.ACCESS_USER_AUTH_INTERNAL";
37 }
38 
GetInstance()39 AccountIAMClient &AccountIAMClient::GetInstance()
40 {
41     static AccountIAMClient *instance = new (std::nothrow) AccountIAMClient();
42     return *instance;
43 }
44 
OpenSession(int32_t userId,std::vector<uint8_t> & challenge)45 int32_t AccountIAMClient::OpenSession(int32_t userId, std::vector<uint8_t> &challenge)
46 {
47     auto proxy = GetAccountIAMProxy();
48     if (proxy == nullptr) {
49         return ERR_ACCOUNT_COMMON_GET_PROXY;
50     }
51     return proxy->OpenSession(userId, challenge);
52 }
53 
CloseSession(int32_t userId)54 int32_t AccountIAMClient::CloseSession(int32_t userId)
55 {
56     auto proxy = GetAccountIAMProxy();
57     if (proxy == nullptr) {
58         return ERR_ACCOUNT_COMMON_GET_PROXY;
59     }
60     return proxy->CloseSession(userId);
61 }
62 
AddCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)63 void AccountIAMClient::AddCredential(
64     int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
65 {
66     if (callback == nullptr) {
67         ACCOUNT_LOGE("the callback for adding credential is nullptr");
68         return;
69     }
70     Attributes emptyResult;
71     auto proxy = GetAccountIAMProxy();
72     if (proxy == nullptr) {
73         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
74         return;
75     }
76     if ((userId == -1) && (!GetCurrentUserId(userId))) {
77         ACCOUNT_LOGE("fail to add credential for invalid userId");
78         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
79         return;
80     }
81     if (credInfo.authType == AuthType::PIN) {
82         SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
83     }
84     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
85     proxy->AddCredential(userId, credInfo, wrapper);
86 }
87 
UpdateCredential(int32_t userId,const CredentialParameters & credInfo,const std::shared_ptr<IDMCallback> & callback)88 void AccountIAMClient::UpdateCredential(
89     int32_t userId, const CredentialParameters& credInfo, const std::shared_ptr<IDMCallback> &callback)
90 {
91     if (callback == nullptr) {
92         ACCOUNT_LOGE("the callback for updating credential is nullptr");
93         return;
94     }
95     Attributes emptyResult;
96     auto proxy = GetAccountIAMProxy();
97     if (proxy == nullptr) {
98         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
99         return;
100     }
101     if ((userId == -1) && (!GetCurrentUserId(userId))) {
102         ACCOUNT_LOGE("fail to update credential for invalid userId");
103         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
104         return;
105     }
106     if (credInfo.authType == AuthType::PIN) {
107         SetAuthSubType(userId, static_cast<int32_t>(credInfo.pinType.value_or(PinSubType::PIN_MAX)));
108     }
109     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
110     proxy->UpdateCredential(userId, credInfo, wrapper);
111 }
112 
DelCred(int32_t userId,uint64_t credentialId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)113 void AccountIAMClient::DelCred(int32_t userId, uint64_t credentialId, const std::vector<uint8_t> &authToken,
114     const std::shared_ptr<IDMCallback>& callback)
115 {
116     if (callback == nullptr) {
117         ACCOUNT_LOGE("the callback for deleting credential is nullptr");
118         return;
119     }
120     Attributes emptyResult;
121     auto proxy = GetAccountIAMProxy();
122     if (proxy == nullptr) {
123         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
124         return;
125     }
126     if ((userId == -1) && (!GetCurrentUserId(userId))) {
127         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
128         return;
129     }
130     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
131     proxy->DelCred(userId, credentialId, authToken, wrapper);
132 }
133 
DelUser(int32_t userId,const std::vector<uint8_t> & authToken,const std::shared_ptr<IDMCallback> & callback)134 void AccountIAMClient::DelUser(
135     int32_t userId, const std::vector<uint8_t> &authToken, const std::shared_ptr<IDMCallback> &callback)
136 {
137     if (callback == nullptr) {
138         ACCOUNT_LOGE("the callback for deleting user is nullptr");
139         return;
140     }
141     Attributes emptyResult;
142     auto proxy = GetAccountIAMProxy();
143     if (proxy == nullptr) {
144         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
145         return;
146     }
147     if ((userId == -1) && (!GetCurrentUserId(userId))) {
148         callback->OnResult(ERR_ACCOUNT_COMMON_INVALID_PARAMETER, emptyResult);
149         return;
150     }
151     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(userId, callback);
152     proxy->DelUser(userId, authToken, wrapper);
153 }
154 
GetCredentialInfo(int32_t userId,AuthType authType,const std::shared_ptr<GetCredInfoCallback> & callback)155 int32_t AccountIAMClient::GetCredentialInfo(
156     int32_t userId, AuthType authType, const std::shared_ptr<GetCredInfoCallback> &callback)
157 {
158     auto proxy = GetAccountIAMProxy();
159     if (proxy == nullptr) {
160         return ERR_ACCOUNT_COMMON_GET_PROXY;
161     }
162     sptr<IGetCredInfoCallback> wrapper = new (std::nothrow) GetCredInfoCallbackService(callback);
163     ErrCode result = proxy->GetCredentialInfo(userId, authType, wrapper);
164     if ((result != ERR_OK) && (callback != nullptr)) {
165         std::vector<CredentialInfo> infoList;
166         callback->OnCredentialInfo(result, infoList);
167     }
168     return result;
169 }
170 
Cancel(int32_t userId)171 int32_t AccountIAMClient::Cancel(int32_t userId)
172 {
173     auto proxy = GetAccountIAMProxy();
174     if (proxy == nullptr) {
175         return ERR_ACCOUNT_COMMON_GET_PROXY;
176     }
177     return proxy->Cancel(userId);
178 }
179 
180 #ifdef HAS_PIN_AUTH_PART
StartDomainAuth(int32_t userId,const std::shared_ptr<IDMCallback> & callback)181 uint64_t AccountIAMClient::StartDomainAuth(int32_t userId, const std::shared_ptr<IDMCallback> &callback)
182 {
183     std::lock_guard<std::mutex> lock(domainMutex_);
184     Attributes emptyResult;
185     if (domainInputer_ == nullptr) {
186         ACCOUNT_LOGE("the registered inputer is not found or invalid");
187         callback->OnResult(ERR_ACCOUNT_IAM_KIT_INPUTER_NOT_REGISTERED, emptyResult);
188         return 0;
189     }
190     domainInputer_->OnGetData(IAMAuthType::DOMAIN, std::vector<uint8_t>(),
191         std::make_shared<DomainCredentialRecipient>(userId, callback));
192     return 0;
193 }
194 #endif
195 
PrepareRemoteAuth(const std::string & remoteNetworkId,const std::shared_ptr<PreRemoteAuthCallback> & callback)196 int32_t AccountIAMClient::PrepareRemoteAuth(
197     const std::string &remoteNetworkId, const std::shared_ptr<PreRemoteAuthCallback> &callback)
198 {
199     if (callback == nullptr) {
200         ACCOUNT_LOGE("Callback for PrepareRemoteAuth is nullptr.");
201         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
202     }
203     auto proxy = GetAccountIAMProxy();
204     if (proxy == nullptr) {
205         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY);
206         return ERR_ACCOUNT_COMMON_GET_PROXY;
207     }
208     sptr<IPreRemoteAuthCallback> wrapper = new (std::nothrow) PreRemoteAuthCallbackService(callback);
209     return proxy->PrepareRemoteAuth(remoteNetworkId, wrapper);
210 }
211 
Auth(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)212 uint64_t AccountIAMClient::Auth(AuthOptions& authOptions, const std::vector<uint8_t> &challenge,
213     AuthType authType, AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
214 {
215     return AuthUser(authOptions, challenge, authType, authTrustLevel, callback);
216 }
217 
AuthUser(AuthOptions & authOptions,const std::vector<uint8_t> & challenge,AuthType authType,AuthTrustLevel authTrustLevel,const std::shared_ptr<IDMCallback> & callback)218 uint64_t AccountIAMClient::AuthUser(
219     AuthOptions &authOptions, const std::vector<uint8_t> &challenge, AuthType authType,
220     AuthTrustLevel authTrustLevel, const std::shared_ptr<IDMCallback> &callback)
221 {
222     uint64_t contextId = 0;
223     if (callback == nullptr) {
224         ACCOUNT_LOGE("callback is nullptr");
225         return contextId;
226     }
227     auto proxy = GetAccountIAMProxy();
228     if (proxy == nullptr) {
229         return contextId;
230     }
231     if ((!authOptions.hasRemoteAuthOptions) && (authOptions.accountId == -1) &&
232         (!GetCurrentUserId(authOptions.accountId))) {
233         return contextId;
234     }
235 #ifdef HAS_PIN_AUTH_PART
236     if (static_cast<int32_t>(authType) == static_cast<int32_t>(IAMAuthType::DOMAIN)) {
237         return StartDomainAuth(authOptions.accountId, callback);
238     }
239 #endif
240     sptr<IIDMCallback> wrapper = new (std::nothrow) IDMCallbackService(authOptions.accountId, callback);
241     AuthParam authParam;
242     authParam.challenge = challenge;
243     authParam.authType = authType;
244     authParam.authTrustLevel = authTrustLevel;
245     authParam.userId = authOptions.accountId;
246     authParam.authIntent = authOptions.authIntent;
247     if (authOptions.hasRemoteAuthOptions) {
248         authParam.remoteAuthParam = RemoteAuthParam();
249         if (authOptions.remoteAuthOptions.hasVerifierNetworkId) {
250             authParam.remoteAuthParam.value().verifierNetworkId = authOptions.remoteAuthOptions.verifierNetworkId;
251         }
252         if (authOptions.remoteAuthOptions.hasCollectorNetworkId) {
253             authParam.remoteAuthParam.value().collectorNetworkId = authOptions.remoteAuthOptions.collectorNetworkId;
254         }
255         if (authOptions.remoteAuthOptions.hasCollectorTokenId) {
256             authParam.remoteAuthParam.value().collectorTokenId = authOptions.remoteAuthOptions.collectorTokenId;
257         }
258     }
259     ErrCode result = proxy->AuthUser(authParam, wrapper, contextId);
260     if (result != ERR_OK) {
261         Attributes emptyResult;
262         callback->OnResult(result, emptyResult);
263     }
264     return contextId;
265 }
266 
CancelAuth(uint64_t contextId)267 int32_t AccountIAMClient::CancelAuth(uint64_t contextId)
268 {
269     auto proxy = GetAccountIAMProxy();
270     if (proxy == nullptr) {
271         return ERR_ACCOUNT_COMMON_GET_PROXY;
272     }
273     return proxy->CancelAuth(contextId);
274 }
275 
GetAvailableStatus(AuthType authType,AuthTrustLevel authTrustLevel,int32_t & status)276 int32_t AccountIAMClient::GetAvailableStatus(AuthType authType, AuthTrustLevel authTrustLevel, int32_t &status)
277 {
278     auto proxy = GetAccountIAMProxy();
279     if (proxy == nullptr) {
280         return ERR_ACCOUNT_COMMON_GET_PROXY;
281     }
282     if (authTrustLevel < UserIam::UserAuth::ATL1 || authTrustLevel > UserIam::UserAuth::ATL4) {
283         ACCOUNT_LOGE("authTrustLevel is not in correct range");
284         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
285     }
286     if (authType < UserIam::UserAuth::ALL) {
287         ACCOUNT_LOGE("authType is not in correct range");
288         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
289     }
290     return proxy->GetAvailableStatus(authType, authTrustLevel, status);
291 }
292 
GetProperty(int32_t userId,const GetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)293 void AccountIAMClient::GetProperty(
294     int32_t userId, const GetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
295 {
296     if (callback == nullptr) {
297         ACCOUNT_LOGE("the callback for getting property is nullptr");
298         return;
299     }
300     Attributes emptyResult;
301     auto proxy = GetAccountIAMProxy();
302     if (proxy == nullptr) {
303         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
304         return;
305     }
306     sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
307     proxy->GetProperty(userId, request, wrapper);
308 }
309 
SetProperty(int32_t userId,const SetPropertyRequest & request,const std::shared_ptr<GetSetPropCallback> & callback)310 void AccountIAMClient::SetProperty(
311     int32_t userId, const SetPropertyRequest &request, const std::shared_ptr<GetSetPropCallback> &callback)
312 {
313     if (callback == nullptr) {
314         ACCOUNT_LOGE("the callback for setting property is nullptr");
315         return;
316     }
317     Attributes emptyResult;
318     auto proxy = GetAccountIAMProxy();
319     if (proxy == nullptr) {
320         callback->OnResult(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
321         return;
322     }
323     sptr<IGetSetPropCallback> wrapper = new (std::nothrow) GetSetPropCallbackService(callback);
324     proxy->SetProperty(userId, request, wrapper);
325 }
326 
GetEnrolledId(int32_t accountId,AuthType authType,const std::shared_ptr<GetEnrolledIdCallback> & callback)327 void AccountIAMClient::GetEnrolledId(
328     int32_t accountId, AuthType authType, const std::shared_ptr<GetEnrolledIdCallback> &callback)
329 {
330     if (callback == nullptr) {
331         ACCOUNT_LOGE("The callback for get enrolled id is nullptr");
332         return;
333     }
334     uint64_t emptyResult = 0;
335     auto proxy = GetAccountIAMProxy();
336     if (proxy == nullptr) {
337         callback->OnEnrolledId(ERR_ACCOUNT_COMMON_GET_PROXY, emptyResult);
338         return;
339     }
340     sptr<IGetEnrolledIdCallback> wrapper = new (std::nothrow) GetEnrolledIdCallbackService(callback);
341     if (wrapper == nullptr) {
342         callback->OnEnrolledId(ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, emptyResult);
343         return;
344     }
345     proxy->GetEnrolledId(accountId, authType, wrapper);
346 }
347 
CheckSelfPermission(const std::string & permissionName)348 bool AccountIAMClient::CheckSelfPermission(const std::string &permissionName)
349 {
350     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetSelfTokenID();
351     ErrCode result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, permissionName);
352     return result == Security::AccessToken::TypePermissionState::PERMISSION_GRANTED;
353 }
354 
355 #ifdef HAS_PIN_AUTH_PART
RegisterPINInputer(const std::shared_ptr<IInputer> & inputer)356 ErrCode AccountIAMClient::RegisterPINInputer(const std::shared_ptr<IInputer> &inputer)
357 {
358     std::lock_guard<std::mutex> lock(pinMutex_);
359     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
360     if (result != ERR_OK) {
361         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
362         return result;
363     }
364     if (pinInputer_ != nullptr) {
365         ACCOUNT_LOGE("inputer is already registered");
366         return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
367     }
368     int32_t userId = -1;
369     if (!GetCurrentUserId(userId)) {
370         return ERR_ACCOUNT_IAM_KIT_GET_USERID_FAIL;
371     }
372     auto iamInputer = std::make_shared<IAMInputer>(userId, inputer);
373     if (UserIam::PinAuth::PinAuthRegister::GetInstance().RegisterInputer(iamInputer)) {
374         pinInputer_ = inputer;
375         return ERR_OK;
376     }
377     return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
378 }
379 
RegisterDomainInputer(const std::shared_ptr<IInputer> & inputer)380 ErrCode AccountIAMClient::RegisterDomainInputer(const std::shared_ptr<IInputer> &inputer)
381 {
382     std::lock_guard<std::mutex> lock(domainMutex_);
383     if (domainInputer_ != nullptr) {
384         ACCOUNT_LOGE("inputer is already registered");
385         return ERR_ACCOUNT_IAM_KIT_INPUTER_ALREADY_REGISTERED;
386     }
387     domainInputer_ = inputer;
388     return ERR_OK;
389 }
390 
RegisterInputer(int32_t authType,const std::shared_ptr<IInputer> & inputer)391 ErrCode AccountIAMClient::RegisterInputer(int32_t authType, const std::shared_ptr<IInputer> &inputer)
392 {
393     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
394     if (result != ERR_OK) {
395         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
396         return result;
397     }
398     if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
399         (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
400         ACCOUNT_LOGE("failed to check permission");
401         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
402     }
403     if (inputer == nullptr) {
404         ACCOUNT_LOGE("inputer is nullptr");
405         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
406     }
407     switch (authType) {
408         case IAMAuthType::DOMAIN:
409             return RegisterDomainInputer(inputer);
410         default:
411             return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
412     }
413 }
414 
UnregisterInputer(int32_t authType)415 ErrCode AccountIAMClient::UnregisterInputer(int32_t authType)
416 {
417     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
418     if (result != ERR_OK) {
419         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
420         return result;
421     }
422     if ((!CheckSelfPermission(PERMISSION_ACCESS_USER_AUTH_INTERNAL)) &&
423         (!CheckSelfPermission(PERMISSION_MANAGE_USER_IDM))) {
424         ACCOUNT_LOGE("failed to check permission");
425         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
426     }
427     switch (authType) {
428         case IAMAuthType::DOMAIN:
429             return UnregisterDomainInputer();
430         default:
431             return ERR_ACCOUNT_IAM_UNSUPPORTED_AUTH_TYPE;
432     }
433     return ERR_OK;
434 }
435 
UnregisterPINInputer()436 ErrCode AccountIAMClient::UnregisterPINInputer()
437 {
438     ErrCode result = AccountPermissionManager::CheckSystemApp(false);
439     if (result != ERR_OK) {
440         ACCOUNT_LOGE("is not system application, result = %{public}u.", result);
441         return result;
442     }
443     if (!CheckSelfPermission(PERMISSION_ACCESS_PIN_AUTH)) {
444         ACCOUNT_LOGE("failed to check permission");
445         return ERR_ACCOUNT_COMMON_PERMISSION_DENIED;
446     }
447     UserIam::PinAuth::PinAuthRegister::GetInstance().UnRegisterInputer();
448     std::lock_guard<std::mutex> lock(pinMutex_);
449     pinInputer_ = nullptr;
450     return ERR_OK;
451 }
452 
UnregisterDomainInputer()453 ErrCode AccountIAMClient::UnregisterDomainInputer()
454 {
455     std::lock_guard<std::mutex> lock(domainMutex_);
456     domainInputer_ = nullptr;
457     return ERR_OK;
458 }
459 #endif
460 
GetAccountState(int32_t userId)461 IAMState AccountIAMClient::GetAccountState(int32_t userId)
462 {
463     auto proxy = GetAccountIAMProxy();
464     if (proxy == nullptr) {
465         return IDLE;
466     }
467     return proxy->GetAccountState(userId);
468 }
469 
SetAuthSubType(int32_t userId,int32_t authSubType)470 void AccountIAMClient::SetAuthSubType(int32_t userId, int32_t authSubType)
471 {
472     std::lock_guard<std::mutex> lock(mutex_);
473     auto it = credentialMap_.find(userId);
474     if (it != credentialMap_.end()) {
475         return;
476     }
477     credentialMap_[userId] = {
478         .type = authSubType
479     };
480 }
481 
GetAuthSubType(int32_t userId)482 int32_t AccountIAMClient::GetAuthSubType(int32_t userId)
483 {
484     std::lock_guard<std::mutex> lock(mutex_);
485     auto it = credentialMap_.find(userId);
486     if (it != credentialMap_.end()) {
487         return it->second.type;
488     }
489     return 0;
490 }
491 
GetCurrentUserId(int32_t & userId)492 bool AccountIAMClient::GetCurrentUserId(int32_t &userId)
493 {
494     std::vector<int32_t> userIds;
495     if ((OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK) || userIds.empty()) {
496         ACCOUNT_LOGE("fail to get activated os account ids");
497         return false;
498     }
499     userId = userIds[0];
500     return true;
501 }
502 
ResetAccountIAMProxy(const wptr<IRemoteObject> & remote)503 void AccountIAMClient::ResetAccountIAMProxy(const wptr<IRemoteObject>& remote)
504 {
505     std::lock_guard<std::mutex> lock(mutex_);
506     if (proxy_ == nullptr) {
507         ACCOUNT_LOGE("proxy is nullptr");
508         return;
509     }
510     auto serviceRemote = proxy_->AsObject();
511     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
512         serviceRemote->RemoveDeathRecipient(deathRecipient_);
513         proxy_ = nullptr;
514     }
515 }
516 
OnRemoteDied(const wptr<IRemoteObject> & remote)517 void AccountIAMClient::AccountIAMDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
518 {
519     if (remote == nullptr) {
520         ACCOUNT_LOGE("remote is nullptr");
521         return;
522     }
523     AccountIAMClient::GetInstance().ResetAccountIAMProxy(remote);
524 }
525 
GetAccountIAMProxy()526 sptr<IAccountIAM> AccountIAMClient::GetAccountIAMProxy()
527 {
528     std::lock_guard<std::mutex> lock(mutex_);
529     if (proxy_ != nullptr) {
530         return proxy_;
531     }
532     sptr<IRemoteObject> object = OhosAccountKitsImpl::GetInstance().GetAccountIAMService();
533     if (object == nullptr) {
534         ACCOUNT_LOGE("failed to get account iam service");
535         return nullptr;
536     }
537     deathRecipient_ = new (std::nothrow) AccountIAMDeathRecipient();
538     if (deathRecipient_ == nullptr) {
539         ACCOUNT_LOGE("failed to create account iam death recipient");
540         return nullptr;
541     }
542     if (!object->AddDeathRecipient(deathRecipient_)) {
543         ACCOUNT_LOGE("failed to add account iam death recipient");
544         deathRecipient_ = nullptr;
545         return nullptr;
546     }
547     proxy_ = iface_cast<IAccountIAM>(object);
548     if (proxy_ == nullptr) {
549         ACCOUNT_LOGE("failed to get account iam proxy");
550     }
551     return proxy_;
552 }
553 }  // namespace AccountSA
554 }  // namespace OHOS
555