diff --git a/services/abilitymgr/include/ability_manager_service.h b/services/abilitymgr/include/ability_manager_service.h index 082b0d62aa03dc9b3b98db1df5d8dbf88a37f4cf..d024f1ed151b44e3d63c19df26805a21c0ca8368 100644 --- a/services/abilitymgr/include/ability_manager_service.h +++ b/services/abilitymgr/include/ability_manager_service.h @@ -708,6 +708,8 @@ public: virtual int StopUser(int userId, const sptr &callback) override; + void ClearUserData(int32_t userId); + virtual int RegisterSnapshotHandler(const sptr& handler) override; virtual int32_t GetMissionSnapshot(const std::string& deviceId, int32_t missionId, diff --git a/services/abilitymgr/include/app_scheduler.h b/services/abilitymgr/include/app_scheduler.h index 35a30294edeb2baa2082a5635da2726c0b4af31c..701efe2c0278efd1e4f437da676cdb479db4ab8f 100644 --- a/services/abilitymgr/include/app_scheduler.h +++ b/services/abilitymgr/include/app_scheduler.h @@ -162,6 +162,14 @@ public: */ void KillProcessByAbilityToken(const sptr &token); + /** + * KillProcessesByUserId, call KillProcessesByUserId() through proxy object, + * kill the process by user id. + * + * @param userId, the user id. + */ + void KillProcessesByUserId(int32_t userId); + /** * convert ability state to app ability state. * diff --git a/services/abilitymgr/include/task_data_persistence_mgr.h b/services/abilitymgr/include/task_data_persistence_mgr.h index 9316c412cf725f15fd227941c63479ae7bedbe1b..db3c2e1e004b6f359ca5e6208e2b54088ba74863 100644 --- a/services/abilitymgr/include/task_data_persistence_mgr.h +++ b/services/abilitymgr/include/task_data_persistence_mgr.h @@ -59,11 +59,19 @@ public: */ bool DeleteMissionInfo(int missionId); + /** + * @brief Remove user directory. + * @param userId Indicates this user id. + * @return Returns true if the directory is successfully removed; returns false otherwise. + */ + bool RemoveUserDir(int32_t userId); + private: std::unordered_map> missionDataStorageMgr_; std::shared_ptr currentMissionDataStorage_; std::shared_ptr eventLoop_; std::shared_ptr handler_; + int32_t currentUserId_ = -1; }; } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/include/user_controller.h b/services/abilitymgr/include/user_controller.h index 7fa117bcc560cba5fbca021d559377c34ab2c110..44741bb2779a77da5012a8c5c396d27c7910c3b6 100644 --- a/services/abilitymgr/include/user_controller.h +++ b/services/abilitymgr/include/user_controller.h @@ -94,6 +94,8 @@ private: void UserBootDone(std::shared_ptr &item); void BroacastUserBackground(int32_t userId); void BroacastUserForeground(int32_t userId); + void BroacastUserStopping(int32_t userId); + void BroacastUserStopped(int32_t userId); void SendSystemUserStart(int32_t userId); void SendSystemUserCurrent(int32_t oldUserId, int32_t newUserId); diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index 1ea285e799a68a35a605c0b69b8f19e66ea71741..cc926436332f5496a84481d0d47b4ab5deca8e9f 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -2791,6 +2791,15 @@ int AbilityManagerService::StopUser(int userId, const sptr &c return 0; } +void AbilityManagerService::ClearUserData(int32_t userId) +{ + HILOG_DEBUG("%{public}s", __func__); + missionListManagers_.erase(userId); + connectManagers_.erase(userId); + dataAbilityManagers_.erase(userId); + pendingWantManagers_.erase(userId); +} + int AbilityManagerService::RegisterSnapshotHandler(const sptr& handler) { HILOG_INFO("snapshot: AbilityManagerService register snapshot handler success."); diff --git a/services/abilitymgr/src/app_scheduler.cpp b/services/abilitymgr/src/app_scheduler.cpp index 5a09640484de47ec15a6a7082ebe42c08181b436..966831ccf52f292d4dc4ce881434f1cb5229d61b 100644 --- a/services/abilitymgr/src/app_scheduler.cpp +++ b/services/abilitymgr/src/app_scheduler.cpp @@ -136,6 +136,13 @@ void AppScheduler::KillProcessByAbilityToken(const sptr &token) appMgrClient_->KillProcessByAbilityToken(token); } +void AppScheduler::KillProcessesByUserId(int32_t userId) +{ + HILOG_DEBUG("Kill process by user id."); + CHECK_POINTER(appMgrClient_); + appMgrClient_->KillProcessesByUserId(userId); +} + AppAbilityState AppScheduler::ConvertToAppAbilityState(const int32_t state) { AppExecFwk::AbilityState abilityState = static_cast(state); diff --git a/services/abilitymgr/src/task_data_persistence_mgr.cpp b/services/abilitymgr/src/task_data_persistence_mgr.cpp index 440e91df768381ee0920275bad36987825c7053c..47fac5416c4ac4ceef4bd1984274ba5e4f08e828 100644 --- a/services/abilitymgr/src/task_data_persistence_mgr.cpp +++ b/services/abilitymgr/src/task_data_persistence_mgr.cpp @@ -15,6 +15,7 @@ #include "task_data_persistence_mgr.h" #include "ability_util.h" +#include "file_util.h" #include "hilog_wrapper.h" namespace OHOS { @@ -49,6 +50,7 @@ bool TaskDataPersistenceMgr::Init(int userId) } else { currentMissionDataStorage_ = missionDataStorageMgr_[userId]; } + currentUserId_ = userId; CHECK_POINTER_RETURN_BOOL(currentMissionDataStorage_); HILOG_INFO("Init success."); @@ -88,5 +90,20 @@ bool TaskDataPersistenceMgr::DeleteMissionInfo(int missionId) currentMissionDataStorage_, missionId); return handler_->PostTask(DeleteMissionInfoFunc, DELETE_MISSION_INFO); } + +bool TaskDataPersistenceMgr::RemoveUserDir(int32_t userId) +{ + if (currentUserId_ == userId) { + HILOG_ERROR("can not removed current user dir"); + return false; + } + std::string userDir = TASK_DATA_FILE_BASE_PATH + "/" + std::to_string(userId); + bool ret = OHOS::HiviewDFX::FileUtil::ForceRemoveDirectory(userDir); + if (!ret) { + HILOG_ERROR("remove user dir %{public}s failed.", userDir.c_str()); + return false; + } + return true; +} } // namespace AAFwk } // namespace OHOS diff --git a/services/abilitymgr/src/user_controller.cpp b/services/abilitymgr/src/user_controller.cpp index 8fe353d91b251839d0455880c760b8c42684525a..74b49f2e9d1ea3c016666563987f61c35f35c93b 100644 --- a/services/abilitymgr/src/user_controller.cpp +++ b/services/abilitymgr/src/user_controller.cpp @@ -19,6 +19,7 @@ #include "hilog_wrapper.h" #include "ipc_skeleton.h" #include "os_account_manager.h" +#include "task_data_persistence_mgr.h" namespace OHOS { namespace AAFwk { @@ -155,7 +156,46 @@ int32_t UserController::StartUser(int32_t userId, bool isForeground) int32_t UserController::StopUser(int32_t userId) { - return -1; + if (userId < 0 || userId == USER_ID_DEFAULT) { + HILOG_ERROR("userId is invalid:%{public}d", userId); + return -1; + } + + if (IsCurrentUser(userId)) { + HILOG_WARN("user is already current:%{public}d", userId); + return 0; + } + + if (!IsExistOsAccount(userId)) { + HILOG_ERROR("not exist such account:%{public}d", userId); + return -1; + } + + BroacastUserStopping(userId); + + auto appScheduler = DelayedSingleton::GetInstance(); + if (!appScheduler) { + HILOG_ERROR("appScheduler is null"); + return -1; + } + appScheduler->KillProcessesByUserId(userId); + + auto taskDataPersistenceMgr = DelayedSingleton::GetInstance(); + if (!taskDataPersistenceMgr) { + HILOG_ERROR("taskDataPersistenceMgr is null"); + return -1; + } + taskDataPersistenceMgr->RemoveUserDir(userId); + + auto abilityManagerService = DelayedSingleton::GetInstance(); + if (!abilityManagerService) { + HILOG_ERROR("abilityManagerService is null"); + return -1; + } + abilityManagerService->ClearUserData(userId); + + BroacastUserStopped(userId); + return 0; } int32_t UserController::GetCurrentUserId() @@ -265,6 +305,16 @@ void UserController::BroacastUserForeground(int32_t userId) // todo: broadcast event user switch to fg. } +void UserController::BroacastUserStopping(int32_t userId) +{ + // todo +} + +void UserController::BroacastUserStopped(int32_t userId) +{ + // todo +} + void UserController::SendSystemUserStart(int32_t userId) { auto handler = eventHandler_; diff --git a/services/abilitymgr/test/mock/include/mock_app_manager_client.h b/services/abilitymgr/test/mock/include/mock_app_manager_client.h index 3a1d2a59b454c37897ac27bdb3a79197d74dc861..85b3cf0d6157b68438ce926760455529f6f061a8 100644 --- a/services/abilitymgr/test/mock/include/mock_app_manager_client.h +++ b/services/abilitymgr/test/mock/include/mock_app_manager_client.h @@ -40,6 +40,7 @@ public: AppMgrResultCode(const sptr &token, const sptr &preToken, const int32_t visibility, const int32_t perceptibility, const int32_t connectionState)); MOCK_METHOD1(KillProcessByAbilityToken, AppMgrResultCode(const sptr &token)); + MOCK_METHOD1(KillProcessesByUserId, AppMgrResultCode(int32_t userId)); MOCK_METHOD4(CompelVerifyPermission, int(const std::string &permission, int pid, int uid, std::string &message)); }; } // namespace AppExecFwk diff --git a/services/abilitymgr/test/mock/libs/appexecfwk_core/include/appmgr/app_mgr_client.h b/services/abilitymgr/test/mock/libs/appexecfwk_core/include/appmgr/app_mgr_client.h index 71ac01703ba89faaeee7ef57c8f448a9f34eac84..406ea62d0dff0990b4e88b55e94cc47eb88d5607 100644 --- a/services/abilitymgr/test/mock/libs/appexecfwk_core/include/appmgr/app_mgr_client.h +++ b/services/abilitymgr/test/mock/libs/appexecfwk_core/include/appmgr/app_mgr_client.h @@ -107,6 +107,15 @@ public: */ virtual AppMgrResultCode KillProcessByAbilityToken(const sptr &token); + /** + * KillProcessesByUserId, call KillProcessesByUserId() through proxy object, + * kill the processes by user id. + * + * @param userId, the user id. + * @return Returns RESULT_OK on success, others on failure. + */ + virtual AppMgrResultCode KillProcessesByUserId(int32_t userId); + /** * KillApplication, call KillApplication() through proxy object, kill the application. * diff --git a/services/abilitymgr/test/mock/libs/appexecfwk_core/src/appmgr/app_mgr_client.cpp b/services/abilitymgr/test/mock/libs/appexecfwk_core/src/appmgr/app_mgr_client.cpp index 657293e5a8926d6b1e98daadee50a5772a2e026a..529ed601caca862f448159ac250a7d12ad6fd93a 100644 --- a/services/abilitymgr/test/mock/libs/appexecfwk_core/src/appmgr/app_mgr_client.cpp +++ b/services/abilitymgr/test/mock/libs/appexecfwk_core/src/appmgr/app_mgr_client.cpp @@ -72,6 +72,11 @@ AppMgrResultCode AppMgrClient::KillProcessByAbilityToken(const sptr &token) HILOG_INFO("Test AppScheduler::KillProcessByAbilityToken()"); } +void AppScheduler::KillProcessesByUserId(int32_t userId) +{ + HILOG_INFO("Test AppScheduler::KillProcessesByUserId()"); +} + AppAbilityState AppScheduler::ConvertToAppAbilityState(const int32_t state) { AppExecFwk::AbilityState abilityState = static_cast(state); diff --git a/services/test/mock/include/mock_app_mgr_client.h b/services/test/mock/include/mock_app_mgr_client.h index b005e7f5dac5031a20b4b29dc4887ea8812f00b2..2145d8e7409e3c4a302fdb0a696ceac88daa5d4f 100644 --- a/services/test/mock/include/mock_app_mgr_client.h +++ b/services/test/mock/include/mock_app_mgr_client.h @@ -31,6 +31,7 @@ public: MOCK_METHOD2(UpdateAbilityState, AppMgrResultCode(const sptr &token, const AbilityState state)); MOCK_METHOD1(KillApplication, AppMgrResultCode(const std::string &)); MOCK_METHOD1(KillProcessByAbilityToken, AppMgrResultCode(const sptr &token)); + MOCK_METHOD1(KillProcessesByUserId, AppMgrResultCode(int32_t userId)); MOCK_METHOD4(CompelVerifyPermission, int(const std::string &permission, int pid, int uid, std::string &message)); MOCK_METHOD1(AbilityAttachTimeOut, void(const sptr &token));