• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #include "os_account_interface.h"
16 
17 #include <cerrno>
18 #include <condition_variable>
19 #include <thread>
20 
21 #include "ability_manager_adapter.h"
22 #include "account_log_wrapper.h"
23 #include "bundle_manager_adapter.h"
24 #ifdef HAS_CES_PART
25 #include "common_event_manager.h"
26 #include "common_event_support.h"
27 #endif // HAS_CES_PART
28 #include "datetime_ex.h"
29 #include "account_hisysevent_adapter.h"
30 #include "hitrace_adapter.h"
31 #include "if_system_ability_manager.h"
32 #include "iservice_registry.h"
33 #ifdef HAS_STORAGE_PART
34 #include "istorage_manager.h"
35 #endif
36 #include "os_account_constants.h"
37 #include "os_account_delete_user_idm_callback.h"
38 #include "os_account_user_callback.h"
39 #include "os_account_subscribe_manager.h"
40 #ifdef HAS_STORAGE_PART
41 #include "storage_manager_proxy.h"
42 #include "storage_service_errno.h"
43 #endif
44 #include "iinner_os_account_manager.h"
45 #include "system_ability_definition.h"
46 #ifdef HAS_USER_IDM_PART
47 #include "user_idm_client.h"
48 #endif // HAS_USER_IDM_PART
49 #ifdef HAS_CES_PART
50 #include "want.h"
51 #endif // HAS_CES_PART
52 
53 
54 namespace OHOS {
55 namespace AccountSA {
56 namespace {
57 const char OPERATION_START[] = "start";
58 
59 #ifdef HAS_STORAGE_PART
60 constexpr uint32_t CRYPTO_FLAG_EL1 = 1;
61 constexpr uint32_t CRYPTO_FLAG_EL2 = 2;
62 #endif
63 
64 constexpr int32_t DELAY_FOR_EXCEPTION = 100;
65 constexpr int32_t MAX_RETRY_TIMES = 10;
66 constexpr int32_t MAX_GETBUNDLE_WAIT_TIMES = 10 * 1000 * 1000;
67 constexpr int32_t GET_MSG_FREQ = 100 * 1000;
68 constexpr int32_t DEAL_TIMES = MAX_GETBUNDLE_WAIT_TIMES / GET_MSG_FREQ;
69 }
70 
SendToAMSAccountStart(OsAccountInfo & osAccountInfo,const OsAccountStartCallbackFunc & callbackFunc,bool isAppRecovery)71 ErrCode OsAccountInterface::SendToAMSAccountStart(OsAccountInfo &osAccountInfo,
72     const OsAccountStartCallbackFunc &callbackFunc, bool isAppRecovery)
73 {
74     int32_t localId = osAccountInfo.GetLocalId();
75     ACCOUNT_LOGI("Start OS account %{public}d", localId);
76     sptr<OsAccountUserCallback> osAccountStartUserCallback = new (std::nothrow) OsAccountUserCallback(callbackFunc);
77     if (osAccountStartUserCallback == nullptr) {
78         ACCOUNT_LOGE("Alloc memory for start user callback failed!");
79         ReportOsAccountOperationFail(localId, OPERATION_START,
80             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
81         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
82     }
83     StartTraceAdapter("AbilityManagerAdapter StartUser");
84 
85     ErrCode code = AbilityManagerAdapter::GetInstance()->StartUser(localId,
86         osAccountStartUserCallback, isAppRecovery);
87     if (code != ERR_OK) {
88         ACCOUNT_LOGE("AbilityManagerAdapter StartUser failed! errcode is %{public}d", code);
89         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE, code,
90             "AbilityManager failed to start user");
91         FinishTraceAdapter();
92         return code;
93     }
94     std::unique_lock<std::mutex> lock(osAccountStartUserCallback->mutex_);
95     osAccountStartUserCallback->onStartCondition_.wait(
96         lock, [osAccountStartUserCallback] { return osAccountStartUserCallback->isCalled_; });
97     FinishTraceAdapter();
98     if (osAccountStartUserCallback->resultCode_ != ERR_OK) {
99         ACCOUNT_LOGE("Failed to AbilityManagerService in call back");
100         ReportOsAccountOperationFail(localId, OPERATION_START, osAccountStartUserCallback->resultCode_,
101                                      "AbilityManager failed to start user in callback");
102         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
103     }
104     ACCOUNT_LOGI("End, succeed %{public}d", localId);
105     return code;
106 }
107 
SendToAMSAccountStop(OsAccountInfo & osAccountInfo)108 ErrCode OsAccountInterface::SendToAMSAccountStop(OsAccountInfo &osAccountInfo)
109 {
110     int32_t localId = osAccountInfo.GetLocalId();
111     ACCOUNT_LOGI("Stop OS account %{public}d", localId);
112     sptr<OsAccountUserCallback> osAccountStopUserCallback = new (std::nothrow) OsAccountUserCallback();
113     if (osAccountStopUserCallback == nullptr) {
114         ACCOUNT_LOGE("Alloc memory for stop user callback failed!");
115         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
116             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
117         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
118     }
119     StartTraceAdapter("AbilityManagerAdapter StopUser");
120 
121     ErrCode code = AbilityManagerAdapter::GetInstance()->StopUser(localId, osAccountStopUserCallback);
122     if (code != ERR_OK) {
123         ACCOUNT_LOGE("Failed to AbilityManagerAdapter stop errcode is %{public}d", code);
124         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP, code,
125             "AbilityManager failed to stop user");
126         FinishTraceAdapter();
127         return code;
128     }
129     std::unique_lock<std::mutex> lock(osAccountStopUserCallback->mutex_);
130     osAccountStopUserCallback->onStopCondition_.wait(lock, [osAccountStopUserCallback] {
131         return osAccountStopUserCallback->isCalled_;
132     });
133     FinishTraceAdapter();
134     if (osAccountStopUserCallback->resultCode_ != ERR_OK) {
135         ACCOUNT_LOGE("Failed to AbilityManagerService in call back");
136         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
137             osAccountStopUserCallback->resultCode_, "AbilityManager failed to stop user in callback");
138         return ERR_OSACCOUNT_SERVICE_INTERFACE_TO_AM_ACCOUNT_START_ERROR;
139     }
140     ACCOUNT_LOGI("End, succeed %{public}d", localId);
141     return code;
142 }
143 
SendToAMSAccountDeactivate(OsAccountInfo & osAccountInfo)144 ErrCode OsAccountInterface::SendToAMSAccountDeactivate(OsAccountInfo &osAccountInfo)
145 {
146     int32_t localId = osAccountInfo.GetLocalId();
147     ACCOUNT_LOGI("Deactivate OS account %{public}d", localId);
148     sptr<OsAccountUserCallback> deactivateUserCallback = new (std::nothrow) OsAccountUserCallback();
149     if (deactivateUserCallback == nullptr) {
150         ACCOUNT_LOGE("Alloc memory for deactivate user callback failed!");
151         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
152             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR, "malloc for OsAccountUserCallback failed!");
153         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
154     }
155 
156     StartTraceAdapter("AbilityManagerAdapter LogoutUser");
157     ErrCode code = AbilityManagerAdapter::GetInstance()->LogoutUser(localId, deactivateUserCallback);
158     if (code != ERR_OK) {
159         ACCOUNT_LOGE("Failed to AbilityManagerAdapter logout errcode is %{public}d", code);
160         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP, code,
161             "AbilityManager failed to logout user");
162         FinishTraceAdapter();
163         return code;
164     }
165     std::unique_lock<std::mutex> lock(deactivateUserCallback->mutex_);
166     deactivateUserCallback->onLogoutCondition_.wait(lock, [deactivateUserCallback] {
167         return deactivateUserCallback->isCalled_;
168     });
169     FinishTraceAdapter();
170     if (deactivateUserCallback->resultCode_ != ERR_OK) {
171         ACCOUNT_LOGE("Failed to logout user in call back");
172         ReportOsAccountOperationFail(localId, Constants::OPERATION_STOP,
173             deactivateUserCallback->resultCode_, "AbilityManager failed to logout user in callback");
174         return deactivateUserCallback->resultCode_;
175     }
176     ACCOUNT_LOGI("Deactivate End, succeed %{public}d", localId);
177     return code;
178 }
179 
180 #ifdef HAS_THEME_SERVICE_PART
InitThemeResource(int32_t localId)181 void OsAccountInterface::InitThemeResource(int32_t localId)
182 {
183     StartTraceAdapter("ThemeManager InitResource");
184     bool ret = ThemeManager::ThemeManagerClient::GetInstance().InitResource(localId);
185     if (!ret) {
186         ACCOUNT_LOGE("Init theme failed, localId=%{public}d.", localId);
187         REPORT_OS_ACCOUNT_FAIL(localId, Constants::OPERATION_CREATE, -1, "Failed to init theme resource");
188         FinishTraceAdapter();
189         return;
190     }
191     ACCOUNT_LOGI("Init theme successful.");
192     FinishTraceAdapter();
193     return;
194 }
195 #endif
196 
SendToBMSAccountCreate(OsAccountInfo & osAccountInfo,const std::vector<std::string> & disallowedHapList)197 ErrCode OsAccountInterface::SendToBMSAccountCreate(
198     OsAccountInfo &osAccountInfo, const std::vector<std::string> &disallowedHapList)
199 {
200     ErrCode errCode = ERR_OK;
201     int32_t retryTimes = 0;
202     while (retryTimes < MAX_RETRY_TIMES) {
203         errCode = BundleManagerAdapter::GetInstance()->CreateNewUser(osAccountInfo.GetLocalId(), disallowedHapList);
204         if ((errCode != Constants::E_IPC_ERROR) && (errCode != Constants::E_IPC_SA_DIED)) {
205             break;
206         }
207         ACCOUNT_LOGE("Fail to SendToBMSAccountCreate, errCode %{public}d.", errCode);
208         retryTimes++;
209         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
210     }
211     return errCode;
212 }
213 
SendToBMSAccountDelete(OsAccountInfo & osAccountInfo)214 ErrCode OsAccountInterface::SendToBMSAccountDelete(OsAccountInfo &osAccountInfo)
215 {
216     return BundleManagerAdapter::GetInstance()->RemoveUser(osAccountInfo.GetLocalId());
217 }
218 
219 #ifdef HAS_USER_IDM_PART
SendToIDMAccountDelete(OsAccountInfo & osAccountInfo)220 ErrCode OsAccountInterface::SendToIDMAccountDelete(OsAccountInfo &osAccountInfo)
221 {
222     std::shared_ptr<OsAccountDeleteUserIdmCallback> callback = std::make_shared<OsAccountDeleteUserIdmCallback>();
223     if (callback == nullptr) {
224         ACCOUNT_LOGE("Get idm callback ptr failed! insufficient memory!");
225         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
226             ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR,
227             "Failed to malloc for OsAccountDeleteUserIdmCallback");
228         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
229     }
230     StartTraceAdapter("UserIDMClient EnforceDelUser");
231     int32_t ret = UserIam::UserAuth::UserIdmClient::GetInstance().EraseUser(osAccountInfo.GetLocalId(), callback);
232     if ((ret != UserIam::UserAuth::ResultCode::SUCCESS) &&
233         (ret != UserIam::UserAuth::ResultCode::NOT_ENROLLED)) {
234         ACCOUNT_LOGE("Idm enforce delete user failed! error %{public}d", ret);
235         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, ret,
236             "Failed to call EraseUser");
237         FinishTraceAdapter();
238         return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
239     }
240 
241     // wait callback
242     {
243         std::unique_lock<std::mutex> lck(callback->mutex_);
244         if (!callback->isCalled_) {
245             callback->onResultCondition_.wait_for(lck, std::chrono::seconds(Constants::TIME_WAIT_TIME_OUT));
246         }
247         if (!callback->isCalled_) {
248             ACCOUNT_LOGE("Idm did not call back! timeout!");
249             ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE, -1,
250                 "UserIDM erase user timeout");
251             FinishTraceAdapter();
252             return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
253         }
254         if ((callback->resultCode_ != UserIam::UserAuth::ResultCode::SUCCESS) &&
255             (callback->resultCode_ != UserIam::UserAuth::ResultCode::NOT_ENROLLED)) {
256             ACCOUNT_LOGE("Idm enforce delete user failed! Callback error %{public}d", callback->resultCode_);
257             ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
258                 callback->resultCode_, "Failed to erase user credential");
259             FinishTraceAdapter();
260             return ERR_OSACCOUNT_SERVICE_IAM_ERASE_USER_FAILED;
261         }
262     }
263 
264     ACCOUNT_LOGI("Send to idm account delete and get callback succeed!");
265     FinishTraceAdapter();
266     return ERR_OK;
267 }
268 #endif // HAS_USER_IDM_PART
269 
SendToCESAccountCreate(OsAccountInfo & osAccountInfo)270 void OsAccountInterface::SendToCESAccountCreate(OsAccountInfo &osAccountInfo)
271 {
272     int osAccountID = osAccountInfo.GetLocalId();
273 #ifdef HAS_CES_PART
274     StartTraceAdapter("PublishCommonEvent account create");
275     OHOS::AAFwk::Want want;
276     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_ADDED);
277     OHOS::EventFwk::CommonEventData data;
278     data.SetCode(osAccountID);
279     data.SetWant(want);
280     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
281         ACCOUNT_LOGE("PublishCommonEvent for create account %{public}d failed!", osAccountID);
282         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_CREATE, -1, "PublishCommonEvent failed!");
283     } else {
284         ACCOUNT_LOGI("PublishCommonEvent for create account %{public}d succeed!", osAccountID);
285     }
286     FinishTraceAdapter();
287 #else // HAS_CES_PART
288     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d create!", osAccountID);
289 #endif // HAS_CES_PART
290 }
291 
SendToCESAccountDelete(OsAccountInfo & osAccountInfo)292 void OsAccountInterface::SendToCESAccountDelete(OsAccountInfo &osAccountInfo)
293 {
294     int osAccountID = osAccountInfo.GetLocalId();
295 #ifdef HAS_CES_PART
296     StartTraceAdapter("PublishCommonEvent account delete");
297     OHOS::AAFwk::Want want;
298     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED);
299     OHOS::EventFwk::CommonEventData data;
300     data.SetCode(osAccountID);
301     data.SetWant(want);
302     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
303         ACCOUNT_LOGE("PublishCommonEvent for delete account %{public}d failed!", osAccountID);
304         ReportOsAccountOperationFail(osAccountID, Constants::OPERATION_REMOVE, -1, "Failed to publish common event");
305     } else {
306         ACCOUNT_LOGI("PublishCommonEvent for delete account %{public}d succeed!", osAccountID);
307     }
308     FinishTraceAdapter();
309 #else // HAS_CES_PART
310     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d delete!", osAccountID);
311 #endif // HAS_CES_PART
312 }
313 
PublishCommonEvent(const OsAccountInfo & osAccountInfo,const std::string & commonEvent,const std::string & operation)314 void OsAccountInterface::PublishCommonEvent(
315     const OsAccountInfo &osAccountInfo, const std::string &commonEvent, const std::string &operation)
316 {
317     int osAccountID = osAccountInfo.GetLocalId();
318 #ifdef HAS_CES_PART
319     StartTraceAdapter("PublishCommonEvent account");
320     OHOS::AAFwk::Want want;
321     want.SetAction(commonEvent);
322     OHOS::EventFwk::CommonEventData data;
323     data.SetCode(osAccountID);
324     data.SetWant(want);
325     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
326         ACCOUNT_LOGE("PublishCommonEvent %{public}d failed!", osAccountID);
327         ReportOsAccountOperationFail(osAccountID, operation, -1, "PublishCommonEvent failed!");
328     } else {
329         ACCOUNT_LOGI("PublishCommonEvent %{public}d succeed!", osAccountID);
330     }
331     FinishTraceAdapter();
332 #else  // HAS_CES_PART
333     ACCOUNT_LOGI("No common event part, do not publish for account %{public}d!", osAccountID);
334 #endif // HAS_CES_PART
335 }
336 
SendToCESAccountSwitched(int newId,int oldId)337 void OsAccountInterface::SendToCESAccountSwitched(int newId, int oldId)
338 {
339 #ifdef HAS_CES_PART
340     StartTraceAdapter("PublishCommonEvent account switched");
341     OHOS::AAFwk::Want want;
342     want.SetAction(OHOS::EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
343     want.SetParam("oldId", std::to_string(oldId));
344     OHOS::EventFwk::CommonEventData data;
345     data.SetCode(newId);
346     data.SetWant(want);
347     if (!OHOS::EventFwk::CommonEventManager::PublishCommonEvent(data)) {
348         ACCOUNT_LOGE("PublishCommonEvent failed, account switched:%{public}d->%{public}d", oldId, newId);
349         ReportOsAccountOperationFail(newId, Constants::OPERATION_SWITCH, -1, "PublishCommonEvent switched failed!");
350     } else {
351         ACCOUNT_LOGI("PublishCommonEvent successful, account switched:%{public}d->%{public}d", oldId, newId);
352     }
353     FinishTraceAdapter();
354 #else // HAS_CES_PART
355     ACCOUNT_LOGI("No common event part, do not publish for account switched:%{public}d->%{public}d", oldId, newId);
356 #endif // HAS_CES_PART
357 }
358 
SendToStorageAccountCreate(OsAccountInfo & osAccountInfo)359 ErrCode OsAccountInterface::SendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
360 {
361     ErrCode errCode = ERR_OK;
362     int32_t retryTimes = 0;
363     while (retryTimes < MAX_RETRY_TIMES) {
364         errCode = InnerSendToStorageAccountCreate(osAccountInfo);
365         if (errCode != Constants::E_IPC_ERROR && errCode != Constants::E_IPC_SA_DIED) {
366             break;
367         }
368         ACCOUNT_LOGE("Fail to SendToStorageAccountCreate,id=%{public}d, errCode %{public}d.",
369             osAccountInfo.GetLocalId(), errCode);
370         retryTimes++;
371         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
372     }
373     return errCode;
374 }
375 
376 #ifdef HAS_STORAGE_PART
PrepareAddUser(const sptr<StorageManager::IStorageManager> & proxy,int32_t userId)377 static ErrCode PrepareAddUser(const sptr<StorageManager::IStorageManager> &proxy, int32_t userId)
378 {
379     ErrCode err = proxy->PrepareAddUser(userId, CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
380     if (err == 0) {
381         return ERR_OK;
382     }
383     ReportOsAccountOperationFail(userId, Constants::OPERATION_CREATE, err, "StorageManager failed to add user");
384     if (err == -EEXIST) {
385         return ERR_OK;
386     }
387     return err;
388 }
389 #endif
390 
InnerSendToStorageAccountCreate(OsAccountInfo & osAccountInfo)391 ErrCode OsAccountInterface::InnerSendToStorageAccountCreate(OsAccountInfo &osAccountInfo)
392 {
393 #ifdef HAS_STORAGE_PART
394     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
395     int32_t localId = osAccountInfo.GetLocalId();
396     if (!systemAbilityManager) {
397         ACCOUNT_LOGE("Failed to get system ability mgr.");
398         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
399             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
400             "GetSystemAbilityManager for storage failed!");
401         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
402     }
403     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
404     if (!remote) {
405         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
406         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE,
407             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
408             "CheckSystemAbility for storage failed!");
409         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
410     }
411     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
412     if (!proxy) {
413         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
414         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
415     }
416     StartTraceAdapter("StorageManager PrepareAddUser");
417 
418     ErrCode err = PrepareAddUser(proxy, localId);
419     if (err == ERR_OK) {
420         FinishTraceAdapter();
421         return ERR_OK;
422     }
423 
424     ACCOUNT_LOGI("PrepareAddUser Failed, start check and clean accounts.");
425     auto &osAccountManager = IInnerOsAccountManager::GetInstance();
426     if (osAccountManager.CleanGarbageOsAccounts(localId) <= 0) {
427         FinishTraceAdapter();
428         return err;
429     }
430     ACCOUNT_LOGI("Clean garbage account data, Retry Storage PrepareAddUser.");
431     err = PrepareAddUser(proxy, localId);
432     FinishTraceAdapter();
433     return err;
434 #else
435     return ERR_OK;
436 #endif
437 }
438 
SendToStorageAccountRemove(OsAccountInfo & osAccountInfo)439 ErrCode OsAccountInterface::SendToStorageAccountRemove(OsAccountInfo &osAccountInfo)
440 {
441     ACCOUNT_LOGI("Start");
442 #ifdef HAS_STORAGE_PART
443     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
444     if (!systemAbilityManager) {
445         ACCOUNT_LOGE("Failed to get system ability mgr.");
446         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
447             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
448             "Failed to get SystemAbilityManager");
449         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
450     }
451     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
452     if (!remote) {
453         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
454         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
455             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
456             "Failed to get StorageManager service");
457         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
458     }
459     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
460     if (!proxy) {
461         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
462         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
463     }
464 
465     StartTraceAdapter("StorageManager RemoveUser");
466     int err = proxy->RemoveUser(osAccountInfo.GetLocalId(),
467         CRYPTO_FLAG_EL1 | CRYPTO_FLAG_EL2);
468     if (err != 0) {
469         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_REMOVE,
470             err, "StorageManager failed to remove user");
471         ACCOUNT_LOGE("Storage RemoveUser failed, ret %{public}d", err);
472         FinishTraceAdapter();
473         return err;
474     }
475 
476     ACCOUNT_LOGI("End, Storage RemoveUser ret %{public}d.", err);
477     FinishTraceAdapter();
478 #endif
479     return ERR_OK;
480 }
481 
482 #ifdef HAS_STORAGE_PART
GetStorageProxy(sptr<StorageManager::IStorageManager> & proxy)483 static ErrCode GetStorageProxy(sptr<StorageManager::IStorageManager> &proxy)
484 {
485     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
486     if (!systemAbilityManager) {
487         ACCOUNT_LOGE("Failed to get system ability mgr.");
488         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
489     }
490     auto remote = systemAbilityManager->CheckSystemAbility(STORAGE_MANAGER_MANAGER_ID);
491     if (!remote) {
492         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
493         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
494     }
495     proxy = iface_cast<StorageManager::IStorageManager>(remote);
496     return ERR_OK;
497 }
498 
UnlockUser(const int localId)499 int32_t OsAccountInterface::UnlockUser(const int localId)
500 {
501     int32_t retryTimes = 0;
502     int32_t errCode = 0;
503     while (retryTimes < MAX_RETRY_TIMES) {
504         sptr<StorageManager::IStorageManager> proxy = nullptr;
505         if (GetStorageProxy(proxy) != ERR_OK) {
506             ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy, retry!");
507             errCode = ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
508             retryTimes++;
509             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
510             continue;
511         }
512         std::vector<uint8_t> emptyData;
513         errCode = proxy->ActiveUserKey(localId, emptyData, emptyData);
514         ACCOUNT_LOGI("ActiveUserKey end, ret %{public}d.", errCode);
515         if (errCode != ErrNo::E_ACTIVE_EL2_FAILED) {
516             errCode = proxy->PrepareStartUser(localId);
517             ACCOUNT_LOGI("PrepareStartUser end, errCode %{public}d.", errCode);
518             if (errCode != 0) {
519                 ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
520                     errCode, "StorageManager failed to start user");
521             }
522         }
523         if ((errCode == Constants::E_IPC_ERROR) || (errCode == Constants::E_IPC_SA_DIED)) {
524             ACCOUNT_LOGE("Failed to PrepareStartUser, id:%{public}d, errCode:%{public}d, retry!", localId, errCode);
525             retryTimes++;
526             std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
527             continue;
528         } else {
529             break;
530         }
531     }
532     return errCode;
533 }
534 #endif
535 
SendToStorageAccountStart(OsAccountInfo & osAccountInfo)536 ErrCode OsAccountInterface::SendToStorageAccountStart(OsAccountInfo &osAccountInfo)
537 {
538     ACCOUNT_LOGI("Start");
539     bool isUserUnlocked = false;
540 #ifdef HAS_STORAGE_PART
541     int localId = osAccountInfo.GetLocalId();
542     StartTraceAdapter("StorageManager PrepareStartUser");
543     int32_t err = UnlockUser(localId);
544     if (err == ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER) {
545         ReportOsAccountOperationFail(localId, Constants::OPERATION_ACTIVATE,
546             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER, "Failed to get StorageManager service");
547         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
548         return err;
549     }
550     if (err == ERR_OK) {
551         isUserUnlocked = true;
552     }
553     ACCOUNT_LOGI("End, Storage PrepareStartUser ret %{public}d.", err);
554     FinishTraceAdapter();
555 #else
556     isUserUnlocked = true;
557 #endif
558     if (!osAccountInfo.GetIsVerified() && isUserUnlocked) {
559         ACCOUNT_LOGI("OS account:%{public}d is unlocked.", osAccountInfo.GetLocalId());
560         osAccountInfo.SetIsVerified(true);
561         bool hasCredential = osAccountInfo.GetCredentialId() > 0;
562         if (!hasCredential) {
563             ACCOUNT_LOGI("OS account:%{public}d is loggen in.", osAccountInfo.GetLocalId());
564             osAccountInfo.SetIsLoggedIn(true);
565             osAccountInfo.SetLastLoginTime(std::chrono::duration_cast<std::chrono::seconds>(
566                 std::chrono::system_clock::now().time_since_epoch()).count());
567         }
568     }
569     ACCOUNT_LOGI("End, succeed!");
570     return ERR_OK;
571 }
572 
SendToStorageAccountStop(OsAccountInfo & osAccountInfo)573 ErrCode OsAccountInterface::SendToStorageAccountStop(OsAccountInfo &osAccountInfo)
574 {
575     ACCOUNT_LOGI("Stop storage, account id = %{public}d", osAccountInfo.GetLocalId());
576 #ifdef HAS_STORAGE_PART
577     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
578     if (!systemAbilityManager) {
579         ACCOUNT_LOGE("Failed to get system ability mgr.");
580         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
581             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
582             "GetSystemAbilityManager for storage failed!");
583         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
584     }
585     auto remote = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
586     if (!remote) {
587         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID service.");
588         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
589             ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER,
590             "GetSystemAbility for storage failed!");
591         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
592     }
593     auto proxy = iface_cast<StorageManager::IStorageManager>(remote);
594     if (!proxy) {
595         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
596         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
597     }
598     osAccountInfo.SetIsVerified(false);
599     StartTraceAdapter("StorageManager StopUser");
600     int localId = osAccountInfo.GetLocalId();
601     int err = proxy->StopUser(localId);
602     if (err != 0) {
603         ACCOUNT_LOGE("StorageManager failed to stop user, err: %{public}d", err);
604         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
605             err, "StorageManager failed to stop user");
606         FinishTraceAdapter();
607         return ERR_OSACCOUNT_SERVICE_STORAGE_STOP_USER_FAILED;
608     }
609     err = proxy->InactiveUserKey(localId);
610     if (err != 0) {
611         ACCOUNT_LOGE("StorageManager failed to inactivate user key, err: %{public}d", err);
612         ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_STOP,
613             err, "StorageManager failed to inactivate user key");
614         FinishTraceAdapter();
615         return ERR_OSACCOUNT_SERVICE_STORAGE_STOP_USER_FAILED;
616     }
617     FinishTraceAdapter();
618 #else
619     osAccountInfo.SetIsVerified(false);
620 #endif
621     return ERR_OK;
622 }
623 
SendToStorageAccountCreateComplete(int32_t localId)624 ErrCode OsAccountInterface::SendToStorageAccountCreateComplete(int32_t localId)
625 {
626     ErrCode errCode = ERR_OK;
627     int32_t retryTimes = 0;
628     while (retryTimes < MAX_RETRY_TIMES) {
629         errCode = InnerSendToStorageAccountCreateComplete(localId);
630         if (errCode == ERR_OK) {
631             break;
632         }
633         ACCOUNT_LOGE("Fail to complete account, localId=%{public}d, errCode=%{public}d.", localId, errCode);
634         retryTimes++;
635         std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_FOR_EXCEPTION));
636     }
637     return errCode;
638 }
639 
InnerSendToStorageAccountCreateComplete(int32_t localId)640 ErrCode OsAccountInterface::InnerSendToStorageAccountCreateComplete(int32_t localId)
641 {
642 #ifdef HAS_STORAGE_PART
643     sptr<StorageManager::IStorageManager> proxy = nullptr;
644     if (GetStorageProxy(proxy) != ERR_OK) {
645         ACCOUNT_LOGE("Failed to get STORAGE_MANAGER_MANAGER_ID proxy.");
646         return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;
647     }
648     StartTraceAdapter("StorageManager CompleteAddUser");
649     int errCode = proxy->CompleteAddUser(localId);
650     if (errCode != 0) {
651         ACCOUNT_LOGE("Failed to CompleteAddUser, localId=%{public}d, errCode=%{public}d", localId, errCode);
652         ReportOsAccountOperationFail(localId, Constants::OPERATION_CREATE, errCode,
653             "StorageManager failed to complete add user");
654         return errCode;
655     }
656     FinishTraceAdapter();
657 #endif
658     return ERR_OK;
659 }
660 
CheckAllAppDied(int32_t accountId)661 ErrCode OsAccountInterface::CheckAllAppDied(int32_t accountId)
662 {
663     int32_t dealTimes = DEAL_TIMES;
664     while (dealTimes > 0) {
665         bool isAllDied = AbilityManagerAdapter::GetInstance()->IsAllAppDied(accountId);
666         if (isAllDied) {
667             return ERR_OK;
668         }
669         ACCOUNT_LOGE("IsAllAppDied check failed");
670         usleep(GET_MSG_FREQ);
671         dealTimes--;
672     }
673     return ERR_ACCOUNT_COMMON_OPERATION_TIMEOUT;
674 }
675 }  // namespace AccountSA
676 }  // namespace OHOS
677