精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

OpenHarmony 源碼解析之賬號子系統

系統
在標準系統上,賬號子系統主要提供分布式帳號登錄狀態管理能力,支持在端側對接廠商云帳號應用,提供云帳號登錄狀態查詢和更新的管理能力。

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

1 簡介

在標準系統上,賬號子系統主要提供分布式帳號登錄狀態管理能力,支持在端側對接廠商云帳號應用,提供云帳號登錄狀態查詢和更新的管理能力

1.1 OpenHarmony架構圖

OpenHarmony 源碼解析之賬號子系統-鴻蒙HarmonyOS技術社區

1.2 賬號子系統架構圖

OpenHarmony 源碼解析之賬號子系統-鴻蒙HarmonyOS技術社區

1.3 賬號子系統目錄結構

  1. /base/account/os_account 
  2. ├── frameworks                           
  3. │   ├── appaccount                                          # 應用賬號kit代碼 
  4. │   ├── ohosaccount                                         # 云賬號kit代碼 
  5. │   ├── common                                              # 共通基礎代碼 
  6. │   │   ├── account_error                                   # 錯誤碼 
  7. │   │   ├── database                                        # 數據庫基礎代碼 
  8. │   │   ├── log                                             # 打印日志代碼 
  9. │   │   └── perf_stat                                       # 性能統計 
  10. ├── interfaces                           
  11. │   ├── innerkits                        
  12. │   │   ├── appaccount                                      # 應用賬號內部接口 
  13. │   │   ├── ohosaccount                                     # 云賬號內部接口 
  14. │   └── kits                             
  15. │       └── napi                         
  16. │           ├── appaccount                                  # 應用賬號對外接口 
  17. │           └── distributedaccount                          # 分布式賬號對外接口 
  18. ├── sa_profile                                              # 帳號SA配置文件定義目錄 
  19. └── services                             
  20.     └── accountmgr                                          # 帳號管理服務         

2 賬號管理服務的啟動

2.1 rc啟動服務

  1. #base\account\os_account\services\accountmgr\accountmgr.rc 
  2. on post-fs-data 
  3.     start accountmgr 
  4.  
  5. service accountmgr /system/bin/sa_main /system/profile/accountmgr.xml 
  6.     class z_core 
  7.     user system 
  8.     group system shell 
  9.     seclabel u:r:accountmgr:s0 
  10.     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks 

 2.1.1 rc文件結構解析

rc文件是以模塊為單位的,模塊分為3種類型:on、service、import

  • import: 導入其它的rc文件
  • on: 執行chown、mkdir、write、export、symlink等簡單的shell指令,如:
  1. on post-fs-data 
  2.     start accountmgr 

 post-fs-data將一個section里的所有命令加入到一個執行隊列,在未來的某個時候會順序執行隊列里的命令

  • service: 執行可執行程序,如:
  1. service accountmgr /system/bin/sa_main /system/profile/accountmgr.xml 
  2.     class z_core 
  3.     user system 
  4.     group system shell 
  5.     seclabel u:r:accountmgr:s0 
  6.     writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks /dev/blkio/foreground/tasks 

 accountmgr為可執行程序名

/system/bin/sa_main /system/profile/accountmgr.xml為可執行文件的路徑

class、user、group、seclabel、writepid這些關鍵字所對應的行是用來描述service一些特點,不同的service有著不同的特點

service什么時候被執行?

在某個on模塊的指令里會存在“class_start”,例如:

  1. class_start core 
  2. class_start main 
  3. on nonencrypted 
  4. class_start late_start 

 當執行到這里是service模塊就會被調用

2.2 AccountMgrService的啟動流程

OpenHarmony 源碼解析之賬號子系統-鴻蒙HarmonyOS技術社區

2.2.1 AccountMgrService通過OnStart調用Init

  • AccountMgrService繼承自SystemAbility,當應用啟動時首先應用程序框架會調用AccountMgrService的生命周期函數OnStart();
  • OnStart()首先判斷服務運行狀態是否已經開啟,如果沒有開啟,則調用Init()進行初始化操作
  • 初始化操作完成并返回true給OnStart()后,服務運行狀態則更新為開啟狀態
  1. //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp 
  2. void AccountMgrService::OnStart() 
  3.     //判斷服務運行狀態是否已經開啟 
  4.     if (state_ == ServiceRunningState::STATE_RUNNING) { 
  5.         ACCOUNT_LOGI("AccountMgrService has already started."); 
  6.         return
  7.     } 
  8.  
  9.     PerfStat::GetInstance().SetInstanceStartTime(GetTickCount()); 
  10.     ACCOUNT_LOGI("start is triggered"); 
  11.     //如果服務運行狀態沒有開啟,則調用Init()進行初始化操作 
  12.     if (!Init()) { 
  13.         ACCOUNT_LOGE("failed to init AccountMgrService"); 
  14.         return
  15.     } 
  16.     //初始化操作完成并返回true給OnStart()后,服務運行狀態則更新為開啟狀態 
  17.     state_ = ServiceRunningState::STATE_RUNNING; 
  18.     ACCOUNT_LOGI("AccountMgrService::OnStart start service success."); 

 2.2.2 AccountMgrService的Init()實現

  • Init()被調用后,依然要先判斷服務運行狀態是否已經開啟
  • 隨后,檢查DEVICE_OWNER_DIR是否存在,如果不存在就強制創建
  • 如果服務還沒有被注冊,則調用Publish()來注冊服務,Publish()執行成功后,標記服務已經被注冊
  • 創建OhosAccountManager對象,并調用它的OnInitialize方法
  1. //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp 
  2. bool AccountMgrService::Init() 
  3.     //判斷服務運行狀態是否已經開啟 
  4.     if (state_ == ServiceRunningState::STATE_RUNNING) { 
  5.         ACCOUNT_LOGW("Service is already running!"); 
  6.         return false
  7.     } 
  8.  
  9.     //檢查DEVICE_OWNER_DIR是否存在,如果不存在就強制創建 
  10.     if (!OHOS::FileExists(DEVICE_OWNER_DIR)) { 
  11.         ACCOUNT_LOGI("Device owner dir not exist, create!"); 
  12.         if (!OHOS::ForceCreateDirectory(DEVICE_OWNER_DIR)) { 
  13.             ACCOUNT_LOGW("Create device owner dir failure!"); 
  14.         } 
  15.     } 
  16.  
  17.     bool ret = false
  18.     //如果服務還沒有被注冊,則調用Publish()來注冊服務,Publish()執行成功后,標記服務已經被注冊 
  19.     if (!registerToService_) { 
  20.         ret = Publish(&DelayedRefSingleton<AccountMgrService>::GetInstance()); 
  21.         if (!ret) { 
  22.             HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed"
  23.                 HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ERR_ACCOUNT_MGR_ADD_TO_SA_ERROR); 
  24.             ACCOUNT_LOGE("AccountMgrService::Init Publish failed!"); 
  25.             return false
  26.         } 
  27.         registerToService_ = true
  28.     } 
  29.  
  30.     PerfStat::GetInstance().SetInstanceInitTime(GetTickCount()); 
  31.  
  32.     //創建OhosAccountManager對象 
  33.     ohosAccountMgr_ = std::make_shared<OhosAccountManager>(); 
  34.      
  35.     //調用OhosAccountManager的OnInitialize方法 
  36.     ret = ohosAccountMgr_->OnInitialize(); 
  37.     if (!ret) { 
  38.         ACCOUNT_LOGE("Ohos account manager initialize failed"); 
  39.         HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStartFailed"
  40.             HiviewDFX::HiSysEvent::EventType::FAULT, "ERROR_TYPE", ret); 
  41.         return ret; 
  42.     } 
  43.     dumpHelper_ = std::make_unique<AccountDumpHelper>(ohosAccountMgr_); 
  44.     IAccountContext::SetInstance(this); 
  45.     ACCOUNT_LOGI("init end success"); 
  46.     return true

2.2.3 OhosAccountManager的初始化

  • OhosAccountManager::OnInitialize首先調用BuildEventsMapper()進行事件映射,查看BuildEventsMapper()實現可發現,寫死的事件有賬號登入、登出、注銷和Token失效,并與對應的方法綁定
  • 組織賬號配置文件路徑,作為參數創建OhosAccountDataDeal對象,并調用它的Init方法,查看Init()實現可發現,Init()讀取賬號配置文件并保存到jsonData_中
  • 調用AccountInfoFromJson()獲取賬號信息并保存到currentAccount_中
  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. bool OhosAccountManager::OnInitialize() 
  3.     accountState_ = std::make_unique<AccountStateMachine>(); 
  4.      
  5.     //事件映射 
  6.     BuildEventsMapper(); 
  7.  
  8.     //組織賬號配置文件路徑 
  9.     std::int32_t userId = GetUserId(); 
  10.     std::string filePath; 
  11.     filePath.append(ACCOUNT_CFG_DIR_ROOT_PATH).append(std::to_string(userId)).append(ACCOUNT_CFG_FILE_NAME); 
  12.      
  13.     //創建OhosAccountDataDeal對象 
  14.     dataDealer_ = std::make_unique<OhosAccountDataDeal>(filePath); 
  15.  
  16.     std::int32_t tryTimes = 0; 
  17.     while (tryTimes < MAX_RETRY_TIMES) { 
  18.         tryTimes++; 
  19.          
  20.         //調用ohos_account_data_deal的Init方法 
  21.         ErrCode errCode = dataDealer_->Init(); 
  22.         if (errCode == ERR_OK) { 
  23.             break; 
  24.         } 
  25.  
  26.         // when json file corrupted, have it another try 
  27.         if ((tryTimes == MAX_RETRY_TIMES) || (errCode != ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION)) { 
  28.             ACCOUNT_LOGE("parse json file failed: %{public}d, tryTime: %{public}d", errCode, tryTimes); 
  29.             eventMap_.clear(); 
  30.             eventFuncMap_.clear(); 
  31.             return false
  32.         } 
  33.     } 
  34.  
  35.     // get account info from config file 
  36.     dataDealer_->AccountInfoFromJson(currentAccount_); 
  37.     accountState_->SetAccountState(currentAccount_.ohosAccountStatus_); 
  38.     return true

2.2.4 OhosAccountManager::BuildEventsMapper()

  • OhosAccountManager::BuildEventsMapper()將賬號登入、登出、注銷和Token失效四個事件與相應的處理函數綁定
  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. void OhosAccountManager::BuildEventsMapper() 
  3.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGIN, 
  4.         ACCOUNT_BIND_SUCCESS_EVT)); 
  5.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOUT, 
  6.         ACCOUNT_MANUAL_UNBOUND_EVT)); 
  7.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, 
  8.         ACCOUNT_TOKEN_EXPIRED_EVT)); 
  9.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOFF, 
  10.         ACCOUNT_MANUAL_LOGOFF_EVT)); 
  11.  
  12.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGIN, &OhosAccountManager::LoginOhosAccount)); 
  13.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOUT, &OhosAccountManager::LogoutOhosAccount)); 
  14.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOFF, &OhosAccountManager::LogoffOhosAccount)); 
  15.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, 
  16.         &OhosAccountManager::HandleOhosAccountTokenInvalidEvent)); 

 2.2.5 ohos_account_data_deal的Init()實現

  • OhosAccountDataDeal::Init()首先檢查賬號配置文件存不存在,如果不存在則創建,如果存在則讀取賬號配置文件內容并保存到jsonData_中
  1. //base\account\os_account\services\accountmgr\src\ohos_account_data_deal.cpp 
  2. ErrCode OhosAccountDataDeal::Init() 
  3.     if (!FileExists(configFile_)) { 
  4.         ACCOUNT_LOGI("file %{public}s not exist, create!", configFile_.c_str()); 
  5.         BuildJsonFileFromScratch(); 
  6.     } 
  7.  
  8.     std::ifstream fin(configFile_); 
  9.     if (!fin) { 
  10.         ACCOUNT_LOGE("Failed to open file %{public}s", configFile_.c_str()); 
  11.         return ERR_ACCOUNT_DATADEAL_INPUT_FILE_ERROR; 
  12.     } 
  13.  
  14.     // NOT-allow exceptions when parse json file 
  15.     nlohmann::json jsonData = json::parse(fin, nullptr, false); 
  16.     if (!jsonData.is_structured()) { 
  17.         ACCOUNT_LOGE("Invalid json file, remove"); 
  18.         fin.close(); 
  19.         if (RemoveFile(configFile_)) { 
  20.             ACCOUNT_LOGE("Remove invalid json file failed"); 
  21.         } 
  22.         return ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION; 
  23.     } 
  24.  
  25.     // jsonData_ keeps well-structured json key-values 
  26.     jsonData_ = jsonData; 
  27.     initOk_ = true
  28.     fin.close(); 
  29.     return ERR_OK; 

3 分布式賬號模塊接口說明

分布式帳號模塊的功能主要包括獲取、查詢和更新分布式賬號信息,僅支持系統應用

在分布式賬號模塊的初始化中,可發現以下函數的注冊:

  1. //base\account\os_account\interfaces\kits\napi\distributedaccount\src\napi_distributed_account.cpp 
  2. napi_value NapiDistributedAccount::Init(napi_env env, napi_value exports) 
  3.     ACCOUNT_LOGI("enter"); 
  4.     napi_property_descriptor descriptor[] = { 
  5.         DECLARE_NAPI_FUNCTION("getDistributedAccountAbility", GetDistributedAccountAbility), 
  6.     }; 
  7.     napi_define_properties(env, exports, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor); 
  8.  
  9.     napi_property_descriptor properties[] = { 
  10.         DECLARE_NAPI_FUNCTION("queryOsAccountDistributedInfo", QueryOhosAccountInfo), 
  11.         DECLARE_NAPI_FUNCTION("updateOsAccountDistributedInfo", UpdateOsAccountDistributedInfo), 
  12.     }; 
  13.     napi_value cons = nullptr; 
  14.     napi_define_class(env, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), DISTRIBUTED_ACCOUNT_CLASS_NAME.size(), 
  15.         JsConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &cons); 
  16.     napi_create_reference(env, cons, 1, &constructorRef_); 
  17.     napi_set_named_property(env, exports, DISTRIBUTED_ACCOUNT_CLASS_NAME.c_str(), cons); 
  18.  
  19.     return exports; 

4 分布式賬號模塊接口調用流程

這里以queryOsAccountDistributedInfo為例,來分析調用流程:

OpenHarmony 源碼解析之賬號子系統-鴻蒙HarmonyOS技術社區

 

 

OpenHarmony 源碼解析之賬號子系統-鴻蒙HarmonyOS技術社區

NapiDistributedAccount::QueryOhosAccountInfo實際調用的是OhosAccountKits::GetInstance().QueryOhosAccountInfo()

  1. //base\account\os_account\interfaces\kits\napi\distributedaccount\src\napi_distributed_account.cpp 
  2. napi_value NapiDistributedAccount::QueryOhosAccountInfo(napi_env env, napi_callback_info cbInfo) 
  3.     ...... 
  4.     napi_create_async_work( 
  5.         env, nullptr, resource, 
  6.         [](napi_env env, void *data) { 
  7.             DistributedAccountAsyncContext *asyncContext = (DistributedAccountAsyncContext*)data; 
  8.             std::pair<bool, OhosAccountInfo> accountInfo = OhosAccountKits::GetInstance().QueryOhosAccountInfo(); 
  9.        ...... 
  10.  
  11.     return result; 

 OhosAccountKitsImpl::QueryOhosAccountInfo()實際調用的是AccountProxy::QueryOhosAccountInfo()

  1. //base\account\os_account\interfaces\innerkits\ohosaccount\native\src\ohos_account_kits_impl.cpp 
  2. std::pair<bool, OhosAccountInfo> OhosAccountKitsImpl::QueryOhosAccountInfo() 
  3.     auto accountProxy = GetService(); 
  4.     if (accountProxy == nullptr) { 
  5.         ACCOUNT_LOGE("Get proxy failed"); 
  6.         return std::make_pair(false, OhosAccountInfo()); 
  7.     } 
  8.  
  9.     //調用AccountProxy::QueryOhosAccountInfo() 
  10.     return accountProxy->QueryOhosAccountInfo(); 

 AccountProxy::QueryOhosAccountInfo()調用SendRequest()發送QUERY_OHOS_ACCOUNT_INFO請求

  1. //base\account\os_account\frameworks\ohosaccount\native\src\account_proxy.cpp 
  2. std::pair<bool, OhosAccountInfo> AccountProxy::QueryOhosAccountInfo(void) 
  3.     ... 
  4.          
  5.     //調用SendRequest()發送QUERY_OHOS_ACCOUNT_INFO請求 
  6.     auto ret = Remote()->SendRequest(QUERY_OHOS_ACCOUNT_INFO, data, reply, option); 
  7.     if (ret != ERR_NONE) { 
  8.         ACCOUNT_LOGE("SendRequest failed %d", ret); 
  9.         return std::make_pair(false, OhosAccountInfo()); 
  10.     } 
  11.      
  12.     ... 
  13.      
  14.     return std::make_pair(true, OhosAccountInfo(Str16ToStr8(name), Str16ToStr8(uid), status)); 

 我們看看它的對端AccountStub::OnRemoteRequest是如何處理發送端的請求并返回什么樣的結果的:

從stubFuncMap_匹配請求碼,然后獲取stubFuncMap_的第二項來處理請求

  1. //base\account\os_account\services\accountmgr\src\account_stub.cpp 
  2. std::int32_t AccountStub::OnRemoteRequest(std::uint32_t code, MessageParcel &data, 
  3.                                           MessageParcel &reply, MessageOption &option
  4.     ... 
  5.  
  6.     //從stubFuncMap_匹配請求碼 
  7.     const auto &itFunc = stubFuncMap_.find(code); 
  8.     if (itFunc != stubFuncMap_.end()) { 
  9.         return (this->*(itFunc->second))(data, reply); 
  10.     } 
  11.  
  12.     ACCOUNT_LOGW("remote request unhandled: %{public}d", code); 
  13.     return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 

 我們來看看stubFuncMap_長啥樣:

很容易看出,QUERY_OHOS_ACCOUNT_INFO請求碼對應的是AccountStub::CmdQueryOhosAccountInfo()

  1. //base\account\os_account\services\accountmgr\src\account_stub.cpp 
  2. const std::map<std::uint32_t, AccountStubFunc> AccountStub::stubFuncMap_ { 
  3.     std::make_pair(UPDATE_OHOS_ACCOUNT_INFO, &AccountStub::CmdUpdateOhosAccountInfo), 
  4.     std::make_pair(QUERY_OHOS_ACCOUNT_INFO, &AccountStub::CmdQueryOhosAccountInfo), 
  5.     std::make_pair(QUERY_OHOS_ACCOUNT_QUIT_TIPS, &AccountStub::CmdQueryOhosQuitTips), 
  6.     std::make_pair(QUERY_DEVICE_ACCOUNT_ID, &AccountStub::CmdQueryDeviceAccountId), 
  7.     std::make_pair(QUERY_DEVICE_ACCOUNT_ID_FROM_UID, &AccountStub::CmdQueryDeviceAccountIdFromUid), 
  8. }; 

 我們看看AccountStub::CmdQueryOhosAccountInfo()的實現:

  • CmdQueryOhosAccountInfo()中首先檢查調用的進程是不是root或者system,從這可以看出,Account的相關接口只有系統用戶才能使用
  • 接著檢查是否有PERMISSION_MANAGE_USERS權限
  • 然后獲取AccountInfo的其實是QueryOhosAccountInfo(),它的實現是在AccountMgrService里面
  1. //base\account\os_account\services\accountmgr\src\account_stub.cpp 
  2. std::int32_t AccountStub::CmdQueryOhosAccountInfo(MessageParcel &data, MessageParcel &reply) 
  3.     //檢查調用的進程是不是root或者system 
  4.     //檢查是否有PERMISSION_MANAGE_USERS權限 
  5.     if (!IsRootOrSystemAccount() && !HasAccountRequestPermission(PERMISSION_MANAGE_USERS)) { 
  6.         ACCOUNT_LOGE("Check permission failed"); 
  7.         return ERR_ACCOUNT_ZIDL_CHECK_PERMISSION_ERROR; 
  8.     } 
  9.  
  10.     //調用AccountMgrService::QueryOhosAccountInfo 
  11.     std::pair<bool, OhosAccountInfo> info = QueryOhosAccountInfo(); 
  12.     if (!info.first) { 
  13.         ACCOUNT_LOGE("Query ohos account info failed"); 
  14.         return ERR_ACCOUNT_ZIDL_ACCOUNT_STUB_ERROR; 
  15.     } 
  16.  
  17.     ... 
  18.     return ERR_OK; 

 在AccountMgrService::QueryOhosAccountInfo()里調用OhosAccountManager的GetAccountInfo()

  1. //base\account\os_account\services\accountmgr\src\account_mgr_service.cpp 
  2. std::pair<bool, OhosAccountInfo> AccountMgrService::QueryOhosAccountInfo(void) 
  3.     //調用OhosAccountManager::GetAccountInfo 
  4.     AccountInfo accountInfo = ohosAccountMgr_->GetAccountInfo(); 
  5.     if (accountInfo.ohosAccountUid_.empty()) { 
  6.         ACCOUNT_LOGE("invalid id"); 
  7.         accountInfo.clear(); 
  8.     } 
  9.     ... 
  10.          
  11.     return std::make_pair(true, OhosAccountInfo(name, id, status)); 
  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. AccountInfo OhosAccountManager::GetAccountInfo() 
  3.     std::lock_guard<std::mutex> mutexLock(mgrMutex_); 
  4.     return currentAccount_; 
  5.  
  6. AccountInfo currentAccount_; 

這里只是返回currentAccount_變量,它是一個AccountInfo,在前面的賬號管理服務啟動的時候,我們知道currentAccount_是在初始化過程中通過讀取賬號配置文件到jsonData_中得到的

5 賬號登入、登出、注銷以及Token失效

前面提到,OhosAccountManager::OnInitialize會首先調用BuildEventsMapper()進行事件映射

  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. void OhosAccountManager::BuildEventsMapper() 
  3.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGIN, 
  4.         ACCOUNT_BIND_SUCCESS_EVT)); 
  5.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOUT, 
  6.         ACCOUNT_MANUAL_UNBOUND_EVT)); 
  7.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, 
  8.         ACCOUNT_TOKEN_EXPIRED_EVT)); 
  9.     eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(OHOS_ACCOUNT_EVENT_LOGOFF, 
  10.         ACCOUNT_MANUAL_LOGOFF_EVT)); 
  11.  
  12.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGIN, &OhosAccountManager::LoginOhosAccount)); 
  13.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOUT, &OhosAccountManager::LogoutOhosAccount)); 
  14.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_LOGOFF, &OhosAccountManager::LogoffOhosAccount)); 
  15.     eventFuncMap_.insert(std::make_pair(OHOS_ACCOUNT_EVENT_TOKEN_INVALID, 
  16.         &OhosAccountManager::HandleOhosAccountTokenInvalidEvent)); 

 可以看到,監聽的事件處理回調有登入、登出、注銷以及Token失效四種類型,下面以LoginOhosAccount為例看看它們具體做了什么:

  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. bool OhosAccountManager::LoginOhosAccount(const std::string &name, const std::string &uid, const std::string &eventStr) 
  3.     std::lock_guard<std::mutex> mutexLock(mgrMutex_); 
  4.     bool ret = HandleEvent(eventStr); // update account status 
  5.     if (!ret) { 
  6.         ACCOUNT_LOGE("LoginOhosAccount: HandleEvent %{public}s failed", eventStr.c_str()); 
  7.         return false
  8.     } 
  9.  
  10.     AccountInfo accountInfo(name, uid, currentAccount_.ohosAccountStatus_); 
  11.     accountInfo.bindTime_ = std::time(nullptr); 
  12.     accountInfo.userId_ = GetUserId(); 
  13.     ret = SetAccount(accountInfo); // set account info 
  14.     if (!ret) { 
  15.         ACCOUNT_LOGE("LoginOhosAccount: SetAccount failed"); 
  16.         return false
  17.     } 
  18.     ACCOUNT_LOGI("LoginOhosAccount success"); 
  19.     return true
  20. ... 

 從上面可以看出,登錄、登出、注銷及Token失效操作步驟基本一致,首先對收到的事件進行處理,然后將賬號信息更新到緩存和配置文件中

因此,這里我們只需要看看HandleEvent()做了什么處理:

這里首先根據eventStr找到對應的事件類型,然后將事件更新到賬號狀態機

  1. //base\account\os_account\services\accountmgr\src\ohos_account_manager.cpp 
  2. bool OhosAccountManager::HandleEvent(const std::string &eventStr) 
  3.     //根據eventStr找到對應的事件類型 
  4.     auto iter = eventMap_.find(eventStr); 
  5.     if (iter == eventMap_.end()) { 
  6.         ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str()); 
  7.         return false
  8.     } 
  9.  
  10.     int event = iter->second
  11.     //將事件更新到賬號狀態機 
  12.     bool ret = accountState_->StateChangeProcess(event); 
  13.     if (!ret) { 
  14.         ACCOUNT_LOGE("Handle event %{public}d failed", event); 
  15.         return false
  16.     } 
  17.     std::int32_t newState = accountState_->GetAccountState(); 
  18.     if (newState != currentAccount_.ohosAccountStatus_) { 
  19.         HiviewDFX::HiSysEvent::Write(HiviewDFX::HiSysEvent::Domain::ACCOUNT, "AccountServiceStateMachineEvent"
  20.             HiviewDFX::HiSysEvent::EventType::FAULT, "DEVICE_MODE", currentAccount_.userId_, 
  21.             "OPERATION_TYPE", event, "OLD_STATE", currentAccount_.ohosAccountStatus_, "NEW_STATE", newState); 
  22.         currentAccount_.ohosAccountStatus_ = newState; 
  23.     } 
  24.     return true
  1. //base\account\os_account\services\accountmgr\src\account_state_machine.cpp 
  2. bool AccountStateMachine::StateChangeProcess(int evt) 
  3.     // for performance record 
  4.     std::string stateRecordStr; 
  5.     int64_t processTicks = GetTickCount(); 
  6.     stateRecordStr.append("state from[").append(std::to_string(currentState_)).append("] to ["); 
  7.  
  8.     // get all the current state event action 
  9.     auto stateIter = stateMachineMap_.find(currentState_); 
  10.     if (stateIter == stateMachineMap_.end()) { 
  11.         ACCOUNT_LOGE("current state %d is not in state machine map.", currentState_); 
  12.         return false
  13.     } 
  14.  
  15.     // get the current event action 
  16.     auto eventIter = stateIter->second.find(evt); 
  17.     if (eventIter == stateIter->second.end()) { 
  18.         ACCOUNT_LOGE("event %d is not in state machine map.", evt); 
  19.         return false
  20.     } 
  21.  
  22.     // maybe action is null 
  23.     if (eventIter->second == nullptr) { 
  24.         ACCOUNT_LOGI("event %d has no action.", evt); 
  25.         return true
  26.     } 
  27.  
  28.     int nextState = eventIter->second->GetNextState(); 
  29.     if (currentState_ != nextState) { 
  30.         ACCOUNT_LOGI("account state change, (oldstate, newstate) = (%d, %d)", currentState_, nextState); 
  31.         currentState_ = nextState; 
  32.     } 
  33.  
  34.     // Record state change performance 
  35.     processTicks = GetTickCount() - processTicks; 
  36.     stateRecordStr.append(std::to_string(nextState)).append("], event[").append(std::to_string(evt)).append("] Cost"); 
  37.     PerfStat::GetInstance().SetAccountStateChangeTime(stateRecordStr, processTicks); 
  38.  
  39.     return true

可以看到,在狀態機里面只是簡單完成狀態的切換

6 總結

通過本文的學習可了解到賬號子系統源碼架構的各個組成部分的實現以及流程(包括框架代碼、內部接口、外部接口、系統服務等),結合上文內容,可進一步對賬號子系統其它組件進行深入的學習。

下一步,

(1) 著重理解賬號子系統框架代碼,為開發的可重用性和擴充性做準備;

(2) 著重理解賬號管理服務模塊,看看賬號管理服務是如何為各功能模塊的業務請求提供應答的;

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-11-08 15:04:47

鴻蒙HarmonyOS應用

2022-02-17 20:57:07

OpenHarmon操作系統鴻蒙

2021-09-18 14:40:37

鴻蒙HarmonyOS應用

2021-12-17 16:42:09

鴻蒙HarmonyOS應用

2023-04-12 15:31:11

系統服務管理鴻蒙

2022-01-10 15:30:11

鴻蒙HarmonyOS應用

2022-05-10 11:17:27

電話子系統數據服務模塊

2021-11-18 10:28:03

鴻蒙HarmonyOS應用

2022-05-24 15:46:51

Wi-FiSTA模式

2021-09-13 15:15:18

鴻蒙HarmonyOS應用

2023-04-06 09:14:11

多模輸入子系統鴻蒙

2022-01-13 10:11:59

鴻蒙HarmonyOS應用

2023-06-28 15:00:02

開源鴻蒙輸入系統架構

2021-09-17 14:38:58

鴻蒙HarmonyOS應用

2022-01-20 14:33:29

openharmonwayland協議鴻蒙

2022-02-14 14:47:11

SystemUIOpenHarmon鴻蒙

2022-03-18 16:07:04

Graphic子系統鴻蒙

2022-05-17 10:42:36

reboot源碼解析

2022-06-13 14:18:39

電源管理子系統耗電量服務

2021-09-16 15:08:08

鴻蒙HarmonyOS應用
點贊
收藏

51CTO技術棧公眾號

久久成人免费日本黄色| 国产亚洲精aa在线看| 91免费国产视频网站| 国产精品18久久久久久麻辣| 中文字幕美女视频| 136福利精品导航| 一本色道久久综合亚洲aⅴ蜜桃| 日本视频一区二区不卡| 国产精品伦理一区| 伊人影院久久| 伊人久久免费视频| 91人妻一区二区| 日韩在线影院| 亚洲精品久久久久久国产精华液| 精品日韩电影| 国产精品久久久久久免费| 亚洲精品婷婷| 日韩最新av在线| 黄色污在线观看| 99久热在线精品视频观看| 红桃视频成人在线观看| 自拍偷拍99| 色视频在线观看| 国精产品一区一区三区mba视频| 性色av一区二区三区免费| 香蕉久久久久久久| 日韩在线你懂的| 欧美一卡二卡在线观看| 国产精品wwwww| 欧美人与动牲性行为| 国产视频一区二区在线观看| 91成人免费看| 一本色道久久综合亚洲| 麻豆9191精品国产| 97精品国产97久久久久久| 影音先锋男人在线| 五月综合久久| 亚洲国产欧美在线成人app| 视频免费1区二区三区 | 91视频精品在这里| 91久久爱成人| 亚洲一区二区三区网站| 久久久久中文| 欧美在线视频一区二区| 日本三级网站在线观看| 午夜国产欧美理论在线播放| 日韩一区二区av| 69xxx免费| av中字幕久久| 亚洲天堂影视av| 国产男女猛烈无遮挡a片漫画| 一区二区三区国产好| 91精品蜜臀在线一区尤物| 国产又黄又猛又粗又爽的视频| 欧美a级在线观看| 欧美日韩精品中文字幕| 国产特级淫片高清视频| 麻豆蜜桃在线观看| 欧美日韩国产影院| 久久精品免费一区二区| 深夜福利视频一区二区| 欧美视频一二三| 99999精品视频| 亚洲自拍偷拍图| 天堂中文在线资源| 国产乱理伦片在线观看夜一区| 国产精品专区第二| 一级爱爱免费视频| 久久国内精品视频| 91深夜福利视频| 性做久久久久久久久久| 丁香婷婷综合激情五月色| 国产伦精品一区二区三区免费视频| 成人爽a毛片一区二区| 成人黄色一级视频| 欧美韩国日本精品一区二区三区| 欧美孕妇性xxxⅹ精品hd| 久久精子c满五个校花| 先锋影音欧美| av在线免费播放| 亚洲成人动漫一区| 日韩av在线综合| 久久精品国产福利| 日韩小视频在线观看专区| 熟妇高潮一区二区| 狠狠色狠狠色综合婷婷tag| 综合国产在线观看| 麻豆成人在线视频| 国产精品久久久久久久免费软件| 国产成人精品久久| 国产精品羞羞答答在线| k8久久久一区二区三区| 欧美性天天影院| 国产精品久久久久久福利| 亚洲精品视频免费观看| 国产一区二区三区精彩视频 | 欧美美女搞黄| 国产精品美女久久久久久 | av成人天堂| 国产精国产精品| 国产肥老妇视频| 久久综合色天天久久综合图片| 亚洲成人在线视频网站| 色婷婷在线播放| 欧美综合视频在线观看| 日本少妇一级片| 国产99久久久国产精品成人免费 | 精品无人区太爽高潮在线播放| 亚洲黄色av片| 思热99re视热频这里只精品| 久久精品国亚洲| 日韩精品视频免费看| 免费看黄色91| 精品伊人久久大线蕉色首页| 毛片在线视频| 色婷婷久久一区二区三区麻豆| 国产精欧美一区二区三区白种人| 女人抽搐喷水高潮国产精品| 日韩在线视频观看正片免费网站| 国产精品第一页在线观看| 极品少妇一区二区三区精品视频| 蜜桃久久影院| 啪啪免费视频一区| 欧美日韩一区二区三区四区五区| 艳妇乳肉豪妇荡乳xxx| 国产精品传媒精东影业在线 | av磁力番号网| 日韩性xxx| 亚洲精品美女久久久久| 深夜福利影院在线观看| 精品一区二区三区蜜桃| 奇米精品在线| 久久人体大尺度| 亚洲精品mp4| h片在线观看下载| 性欧美大战久久久久久久久| 91av视频免费观看| 精品日产免费二区日产免费二区| 97婷婷涩涩精品一区| 午夜精品久久久久久久爽| 国产精品午夜在线| 北条麻妃在线视频| 自拍偷拍一区| 欧美亚洲国产成人精品| 日批免费在线观看| 亚洲成人av在线电影| 亚洲一二三四五| 国内在线观看一区二区三区| 亚洲综合中文字幕在线| 91精选在线| 欧美一区二区视频观看视频| 欧美另类videoxo高潮| 黄网站免费久久| 精品一区二区成人免费视频| 亚洲一区二区小说| 久久中文字幕在线| 国产jzjzjz丝袜老师水多| 亚洲免费观看高清完整版在线| √天堂资源在线| 欧美一级二级三级区| 亚洲国产欧美日韩在线观看第一区| 久久国产精品久久久久久| av综合在线观看| 亚洲精品综合在线| 国产成人av免费观看| 午夜日韩激情| 国产乱子伦精品| 欧美办公室脚交xxxx| 亚洲欧美在线看| 天天天天天天天干| 中文字幕色av一区二区三区| 中文字幕在线观看视频www| 欧美午夜精品| 玛丽玛丽电影原版免费观看1977| 少妇一区视频| 久久久999精品视频| 精品美女www爽爽爽视频| 亚洲大型综合色站| 中文字幕 自拍| 国内精品第一页| 玩弄中年熟妇正在播放| 精品成人影院| 91在线免费观看网站| 超碰中文在线| 国产性猛交xxxx免费看久久| 国产精品热久久| 性久久久久久久久| 国产真人做爰视频免费| 毛片免费在线| 香蕉影视欧美成人| 林心如三级全黄裸体| 国产91丝袜在线观看| 免费在线观看毛片网站| 91精品电影| 久久综合伊人77777麻豆| 99精品视频在线免费播放 | 成都免费高清电影| 狠狠色丁香婷婷综合久久片| 浮妇高潮喷白浆视频| 999精品在线| 国产日本一区二区三区| 久久亚洲精品人成综合网| 久久久午夜视频| av在线播放av| 日韩欧美在线不卡| 少妇又紧又色又爽又刺激视频 | 全球最大av网站久久| 欧美日本在线视频中文字字幕| 人成在线免费视频| 色橹橹欧美在线观看视频高清| 亚洲午夜小视频| 国产91免费在线观看| 欧美艳星brazzers| 圆产精品久久久久久久久久久| 中文字幕一区在线观看视频| 鲁大师私人影院在线观看| 国产毛片精品国产一区二区三区| 欧美丰满熟妇xxxxx| 亚洲国产高清一区二区三区| 26uuu成人| 国产精品视频一区二区三区四蜜臂| wwwxx欧美| 成人自拍视频| 国产日韩av在线播放| 欧美日韩大片| 欧美在线一级视频| а√在线中文在线新版| 久久99国产综合精品女同| 日本a级在线| 伊人久久大香线蕉av一区二区| 无码h黄肉3d动漫在线观看| 欧美成人午夜电影| a级片免费视频| 91精品中文字幕一区二区三区| 中文字幕一级片| 欧美性视频一区二区三区| 四虎成人在线观看| 欧美性高潮在线| 国产精品老女人| 精品久久中文字幕| 国产成人无码一区二区三区在线| 亚洲一区二区视频在线观看| 麻豆精品一区二区三区视频| 亚洲日本一区二区| 1024手机在线视频| 亚洲精品ww久久久久久p站| 国产免费无码一区二区视频| 亚洲欧美电影院| 青娱乐免费在线视频| 亚洲综合久久久久| 日本免费一二三区| 日本乱理伦在线| 亚洲高清久久网| 四虎免费在线观看| 日韩av一区在线观看| 色婷婷av一区二区三| 亚洲精品av在线| 蜜桃视频在线观看视频| 亚洲天堂av在线免费| 成a人片在线观看www视频| 色偷偷av亚洲男人的天堂| 思思99re6国产在线播放| 久久中文字幕在线视频| 久草在线视频福利| 91大神福利视频在线| 男人皇宫亚洲男人2020| 国产精品va在线播放我和闺蜜| av成人免费| 亚洲自拍小视频免费观看| 亚洲一区二区免费在线观看| 国产精品青青草| 伊人精品一区| 亚洲精品视频一区二区三区| 日韩欧美精品一区| 国产精品无码电影在线观看| 国产女优一区| 国产小视频精品| 国产精品1区2区| 久久久久久久久免费看无码 | 女海盗2成人h版中文字幕| 日韩男女性生活视频| 久久精品资源| 国产伦精品一区二区三区四区免费 | 九色综合日本| 日韩精品诱惑一区?区三区| 热久久最新地址| 久久xxxx精品视频| 亚洲午夜精品一区| 99久久精品费精品国产一区二区| av手机在线播放| 亚洲国产欧美在线| 中文字幕av影视| 日韩精品一区在线| 黄色的视频在线免费观看| 九九精品在线观看| 日韩不卡免费高清视频| 97夜夜澡人人双人人人喊| 中文字幕av一区二区三区人| 亚洲小视频在线播放| 久久综合九色| 亚洲v在线观看| 国产精品国模大尺度视频| 久久久久久久极品| 717成人午夜免费福利电影| 爽爽视频在线观看| 欧美精品免费看| 国产精品人人爽| 国产一区二区三区成人欧美日韩在线观看 | 国产欧洲精品视频| 久久中文资源| 亚洲成人动漫在线| 日韩精品一二三区| 无码一区二区精品| 亚洲精品网站在线观看| 波多野结衣在线电影| 亚洲国产精品va在线看黑人| 国产在线高潮| 国产精品女主播| 天堂在线精品| 中文字幕日韩精品无码内射| 六月丁香综合在线视频| 毛片网站免费观看| 亚洲成a人v欧美综合天堂| 国产成人精品无码高潮| 中文字幕亚洲无线码在线一区| 涩涩涩视频在线观看| 国产伦精品一区二区三区四区视频 | 青青视频免费在线观看| 青青青伊人色综合久久| 亚洲第一香蕉网| 欧美日韩国产一区中文午夜| 日本wwwxxxx| 久久久久久久久久久成人| 日本在线成人| 蜜桃视频成人在线观看| 精久久久久久久久久久| 少妇太紧太爽又黄又硬又爽小说| 色偷偷久久一区二区三区| 四虎电影院在线观看| 91精品国产91久久久久久久久| 99a精品视频在线观看| 亚洲国产一二三精品无码| 国产乱码字幕精品高清av | 亚洲影院在线看| 欧美第一精品| 亚洲36d大奶网| 国产精品乱子久久久久| 91久久精品国产91性色69| 色噜噜狠狠狠综合曰曰曰88av| 国产精品伊人| 国产又爽又黄ai换脸| 国内国产精品久久| 欧美成欧美va| 久久九九精品视频| 国产一级精品aaaaa看| 亚洲日本视频| 国产精品久久无码| 欧美性猛交xxxx黑人| 黄色网址在线播放| 国产在线精品成人一区二区三区| 97在线精品| 亚洲欧美日韩中文字幕在线观看| 一区二区三区四区高清精品免费观看 | 国产精品12| 在线看片日韩| 美国黄色a级片| 欧美日韩免费不卡视频一区二区三区 | 久久综合久久99| 亚洲 小说区 图片区| 久久精品国产精品| 视频一区国产| 97超碰青青草| 国产精品污网站| 成人黄色免费视频| 992tv在线成人免费观看| 少妇精品久久久一区二区| 女人高潮一级片| 亚洲一二三四在线| 欧美 丝袜 自拍 制服 另类| 天堂av在线一区| 中文字幕第69页| 欧美成人video| 在线能看的av网址| 亚洲一卡二卡区| 粉嫩绯色av一区二区在线观看| 国产精品久久久久久久妇| 中文国产成人精品| 中文字幕一区二区三区四区久久| 两根大肉大捧一进一出好爽视频| 欧美国产激情一区二区三区蜜月| 99在线观看精品视频| 91精品国产91久久久久久久久 | 国产成人亚洲综合无码| 91蜜桃视频在线| 国产一区二区三区四区视频| 91精品国产高清久久久久久91 | 一级一级黄色片| 欧美情侣性视频| 欧美日韩色图| 无码人妻一区二区三区精品视频 |