diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h index 911ac9825811b7941ad1d583d23b14415dd80432..8a0f63a122c4708dd58802353e7104a2d94f2960 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_client.h @@ -441,6 +441,14 @@ public: */ virtual AppMgrResultCode RegisterConfigurationObserver(const sptr &observer); + /** + * Register configuration observer with userId. + * + * @param observer Configuration observer. When configuration changed, observer will be called. + * @return Returns RESULT_OK on success, others on failure. + */ + virtual AppMgrResultCode RegisterConfigurationObserver(const sptr &observer, int userId); + /** * Unregister configuration observer. * diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h index 2c19e0b08a2690a3baa045ccd983cc6fb7332b62..668a4c0675d3ffc5a8ca59d0fd0250c95d7bf3d7 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_interface.h @@ -488,6 +488,14 @@ public: */ virtual int32_t RegisterConfigurationObserver(const sptr &observer) = 0; + /** + * Register configuration observer with userId. + * + * @param observer Configuration observer. When configuration changed, observer will be called. + * @return Returns RESULT_OK on success, others on failure. + */ + virtual int32_t RegisterConfigurationObserver(const sptr &observer, int32_t userId) = 0; + /** * Unregister configuration observer. * diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h index 84c34ddefb1499624d78d907706212e91cea72a8..20fce4da930f55e32e428534ede36cc2be23b6ac 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_ipc_interface_code.h @@ -136,6 +136,7 @@ enum class AppMgrInterfaceCode { PRELOAD_MODULE_FINISHED = 111, QUERY_RUNNING_SHARED_BUNDLES = 112, EXIT_MASTER_PROCESS_ROLE = 113, + REGISTER_CONFIGURATION_OBSERVER_WITH_USRID = 114, }; } // AppExecFwk } // OHOS diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h index 2e071da60237dcb519aa3d04e5ae95e163183397..29eb1ec27ac6a331b57586292ae1acadd5264e67 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_mgr_proxy.h @@ -448,6 +448,9 @@ public: virtual int32_t RegisterConfigurationObserver(const sptr &observer) override; + virtual int32_t RegisterConfigurationObserver(const sptr &observer, + int32_t userId) override; + virtual int32_t UnregisterConfigurationObserver(const sptr &observer) override; /** diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp index af1eabdb77dc080ca2cb3ab6a5739dd8b4bad18d..9699160b979729f401bb74cf2942597a18488c7d 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_client.cpp @@ -908,6 +908,20 @@ AppMgrResultCode AppMgrClient::RegisterConfigurationObserver(const sptr &observer, + int32_t userId) +{ + sptr service = iface_cast(mgrHolder_->GetRemoteObject()); + if (service != nullptr) { + int32_t result = service->RegisterConfigurationObserver(observer, userId); + if (result == ERR_OK) { + return AppMgrResultCode::RESULT_OK; + } + return AppMgrResultCode::ERROR_SERVICE_NOT_READY; + } + return AppMgrResultCode::ERROR_SERVICE_NOT_CONNECTED; +} + AppMgrResultCode AppMgrClient::UnregisterConfigurationObserver(const sptr &observer) { sptr service = iface_cast(mgrHolder_->GetRemoteObject()); diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp index ee5d9a12e9a952ed9ede3e9147f6b3fadb6fcd22..6eb6692bf432e7190d3f2fa6cfaa963fdfe6f924 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_mgr_proxy.cpp @@ -1103,6 +1103,38 @@ int32_t AppMgrProxy::RegisterConfigurationObserver(const sptr& observer, int32_t userId) +{ + if (!observer) { + TAG_LOGE(AAFwkTag::APPMGR, "observer null"); + return ERR_INVALID_VALUE; + } + TAG_LOGD(AAFwkTag::APPMGR, "RegisterConfigurationObserver start"); + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInt32(userId)) { + TAG_LOGE(AAFwkTag::APPMGR, " invilid userId"); + return ERR_INVALID_DATA; + } + + if (!WriteInterfaceToken(data)) { + return ERR_FLATTEN_OBJECT; + } + + if (!data.WriteRemoteObject(observer->AsObject())) { + TAG_LOGE(AAFwkTag::APPMGR, "observer write failed."); + return ERR_FLATTEN_OBJECT; + } + + auto error = SendRequest(AppMgrInterfaceCode::REGISTER_CONFIGURATION_OBSERVER_WITH_USRID, data, reply, option); + if (error != NO_ERROR) { + TAG_LOGE(AAFwkTag::APPMGR, "Send request error: %{public}d", error); + return error; + } + return reply.ReadInt32(); +} + int32_t AppMgrProxy::UnregisterConfigurationObserver(const sptr &observer) { TAG_LOGD(AAFwkTag::APPMGR, "UnregisterConfigurationObserver start"); diff --git a/services/appmgr/include/app_mgr_service.h b/services/appmgr/include/app_mgr_service.h index 65c785c843ba7323f9ff8380cf658ca08e9d11b0..a836bfed63f23f899a4d66cde121b882c43e137a 100644 --- a/services/appmgr/include/app_mgr_service.h +++ b/services/appmgr/include/app_mgr_service.h @@ -470,6 +470,16 @@ public: */ virtual int32_t RegisterConfigurationObserver(const sptr &observer) override; + /** + * @brief register a configuration observer bound to userId which will receive notifies when updated. + * @param observer the configuration observer to receive notify. + * @param userId the userId registered before + * + * @return Returns ERR_OK on success, others on failure. + */ + virtual int32_t RegisterConfigurationObserver(const sptr &observer, + int32_t userId) override; + /** * @brief unregister a configuration observer registered before. * @param observer the configuration observer registered before. diff --git a/services/appmgr/include/app_mgr_service_inner.h b/services/appmgr/include/app_mgr_service_inner.h index 7f8bd2fa425a427b560ff35e5b46e2004648ad3f..beb4c37105a5c06fd74e2529cb0865aa71a156da 100644 --- a/services/appmgr/include/app_mgr_service_inner.h +++ b/services/appmgr/include/app_mgr_service_inner.h @@ -813,6 +813,8 @@ public: int32_t RegisterConfigurationObserver(const sptr& observer); + int32_t RegisterConfigurationObserver(const sptr& observer, int32_t userId); + int32_t UnregisterConfigurationObserver(const sptr& observer); /** diff --git a/services/appmgr/src/app_mgr_service.cpp b/services/appmgr/src/app_mgr_service.cpp index dd1cf4fe04dcc7880c1d59423fe42d0d32ea4e98..c85ea03f19f53f54bd6968f6ffd21156dc54959b 100644 --- a/services/appmgr/src/app_mgr_service.cpp +++ b/services/appmgr/src/app_mgr_service.cpp @@ -1157,6 +1157,15 @@ int32_t AppMgrService::RegisterConfigurationObserver(const sptrRegisterConfigurationObserver(observer); } +int32_t AppMgrService::RegisterConfigurationObserver(const sptr &observer, int32_t userId) +{ + if (!IsReady()) { + TAG_LOGE(AAFwkTag::APPMGR, "not ready"); + return ERR_INVALID_OPERATION; + } + return appMgrServiceInner_->RegisterConfigurationObserver(observer, userId); +} + int32_t AppMgrService::UnregisterConfigurationObserver(const sptr &observer) { if (!IsReady()) { diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index 7058992c0f96486b5b96d1cda33b90885fa50009..b1487278d67df4eea71412af7d3c4a018e1e8413 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -6028,6 +6028,32 @@ int32_t AppMgrServiceInner::RegisterConfigurationObserver(const sptr& observer, int32_t userId) +{ + TAG_LOGD(AAFwkTag::APPMGR, "called"); + if (!AAFwk::PermissionVerification::GetInstance()->IsSACall()) { + TAG_LOGE(AAFwkTag::APPMGR, "caller not SA"); + return ERR_INVALID_VALUE; + } + + if (observer == nullptr) { + TAG_LOGE(AAFwkTag::APPMGR, "observer null"); + return ERR_INVALID_VALUE; + } + std::lock_guard registerLock(configurationObserverLock_); + auto it = std::find_if(configurationObservers_.begin(), configurationObservers_.end(), + [&](const ConfigurationObserverWithUserId& item) { + return (item.observer && item.observer->AsObject() == observer->AsObject()); + }); + if (it != configurationObservers_.end()) { + TAG_LOGE(AAFwkTag::APPMGR, "observer exist"); + return ERR_INVALID_VALUE; + } + configurationObservers_.push_back( + ConfigurationObserverWithUserId { observer, userId }); + return NO_ERROR; +} + int32_t AppMgrServiceInner::UnregisterConfigurationObserver(const sptr& observer) { TAG_LOGI(AAFwkTag::APPMGR, "call"); diff --git a/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h b/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h index e6d5a1fe68774ee7fafd4f4ea083d6938218c746..b4f91142c70ef9ee26b63261159562a7d753fea0 100644 --- a/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h +++ b/test/mock/frameworks_kits_appkit_test/include/mock_app_mgr_service.h @@ -61,6 +61,7 @@ public: MOCK_METHOD1(GetConfiguration, int32_t(Configuration& config)); MOCK_METHOD2(UpdateConfiguration, int32_t(const Configuration& config, const int32_t userId)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); + MOCK_METHOD2(RegisterConfigurationObserver, int32_t(const sptr& observer, int32_t userId)); MOCK_METHOD1(UnregisterConfigurationObserver, int32_t(const sptr& observer)); MOCK_METHOD1(GetAppRunningStateByBundleName, bool(const std::string& bundleName)); MOCK_METHOD2(NotifyLoadRepairPatch, int32_t(const std::string& bundleName, diff --git a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h index 859875dbefab05aa0f44b806af6c35083c2ea56e..08087efaac0e58672cfd7483199ed7b702a76c12 100644 --- a/test/mock/services_appmgr_test/include/mock_app_mgr_service.h +++ b/test/mock/services_appmgr_test/include/mock_app_mgr_service.h @@ -79,6 +79,7 @@ public: MOCK_METHOD3(UpdateConfigurationByBundleName, int32_t(const Configuration& config, const std::string &name, int32_t appIndex)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); + MOCK_METHOD2(RegisterConfigurationObserver, int32_t(const sptr& observer, int32_t userId)); MOCK_METHOD1(UnregisterConfigurationObserver, int32_t(const sptr& observer)); MOCK_METHOD1(GetAppRunningStateByBundleName, bool(const std::string& bundleName)); MOCK_METHOD2(NotifyLoadRepairPatch, int32_t(const std::string& bundleName, diff --git a/test/unittest/ability_permission_util_second_test/mock/include/mock_app_mgr_service.h b/test/unittest/ability_permission_util_second_test/mock/include/mock_app_mgr_service.h index 988782453e3fa965048055c86eff74378736d01e..2993a87b5b11a268a47df47c03e4ee2793aed353 100644 --- a/test/unittest/ability_permission_util_second_test/mock/include/mock_app_mgr_service.h +++ b/test/unittest/ability_permission_util_second_test/mock/include/mock_app_mgr_service.h @@ -76,6 +76,7 @@ public: MOCK_METHOD3(UpdateConfigurationByBundleName, int32_t(const Configuration& config, const std::string &name, int32_t appIndex)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); + MOCK_METHOD2(RegisterConfigurationObserver, int32_t(const sptr& observer, int32_t userId)); MOCK_METHOD1(UnregisterConfigurationObserver, int32_t(const sptr& observer)); MOCK_METHOD1(GetAppRunningStateByBundleName, bool(const std::string& bundleName)); MOCK_METHOD2(NotifyLoadRepairPatch, int32_t(const std::string& bundleName, diff --git a/test/unittest/app_mgr_service_test/app_mgr_service_test.cpp b/test/unittest/app_mgr_service_test/app_mgr_service_test.cpp index 8d9b609212ce879d0e623604f2fb23b056c55cba..c9545015a7d68fa33d87dd8948fdbb855bfd0a11 100644 --- a/test/unittest/app_mgr_service_test/app_mgr_service_test.cpp +++ b/test/unittest/app_mgr_service_test/app_mgr_service_test.cpp @@ -992,6 +992,44 @@ HWTEST_F(AppMgrServiceTest, RegisterConfigurationObserver_002, TestSize.Level2) EXPECT_NE(res, ERR_INVALID_OPERATION); } +/* + * Feature: AppMgrService + * Function: RegisterConfigurationObserver + * SubFunction: NA + * FunctionPoints: AppMgrService RegisterConfigurationObserver + * EnvConditions: NA + * CaseDescription: Verify RegisterConfigurationObserver + */ +HWTEST_F(AppMgrServiceTest, RegisterConfigurationObserver_003, TestSize.Level2) +{ + auto appMgrService = std::make_shared(); + int32_t userId = 1; + sptr observer = nullptr; + appMgrService->SetInnerService(nullptr); + int32_t res = appMgrService->RegisterConfigurationObserver(observer, userId); + EXPECT_EQ(res, ERR_INVALID_OPERATION); +} + +/* + * Feature: AppMgrService + * Function: RegisterConfigurationObserver + * SubFunction: NA + * FunctionPoints: AppMgrService RegisterConfigurationObserver + * EnvConditions: NA + * CaseDescription: Verify RegisterConfigurationObserver + */ +HWTEST_F(AppMgrServiceTest, RegisterConfigurationObserver_004, TestSize.Level2) +{ + auto appMgrService = std::make_shared(); + int32_t userId = 1; + sptr observer = nullptr; + appMgrService->SetInnerService(std::make_shared()); + appMgrService->taskHandler_ = taskHandler_; + appMgrService->eventHandler_ = std::make_shared(taskHandler_, appMgrService->appMgrServiceInner_); + int32_t res = appMgrService->RegisterConfigurationObserver(observer, userId); + EXPECT_NE(res, ERR_INVALID_OPERATION); +} + /* * Feature: AppMgrService * Function: UnregisterConfigurationObserver diff --git a/test/unittest/multi_app_utils_test/include/mock_app_mgr_service.h b/test/unittest/multi_app_utils_test/include/mock_app_mgr_service.h index c11b4ec495427f42c5b56eb760d9947159ffd276..18b5c792e93fcebd47c4b804c30563c2af049019 100644 --- a/test/unittest/multi_app_utils_test/include/mock_app_mgr_service.h +++ b/test/unittest/multi_app_utils_test/include/mock_app_mgr_service.h @@ -76,6 +76,7 @@ public: MOCK_METHOD3(UpdateConfigurationByBundleName, int32_t(const Configuration& config, const std::string &name, int32_t appIndex)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); + MOCK_METHOD2(RegisterConfigurationObserver, int32_t(const sptr& observer, int32_t userId)); MOCK_METHOD1(UnregisterConfigurationObserver, int32_t(const sptr& observer)); MOCK_METHOD1(GetAppRunningStateByBundleName, bool(const std::string& bundleName)); MOCK_METHOD2(NotifyLoadRepairPatch, int32_t(const std::string& bundleName, diff --git a/test/unittest/multi_instance_utils_second_test/mock_iapp_mgr.h b/test/unittest/multi_instance_utils_second_test/mock_iapp_mgr.h index 127d92c641b880b1472a215f20ec8e67fab897b5..8cf53371726da388088c8ed1120eb88f75f7f41b 100644 --- a/test/unittest/multi_instance_utils_second_test/mock_iapp_mgr.h +++ b/test/unittest/multi_instance_utils_second_test/mock_iapp_mgr.h @@ -250,6 +250,11 @@ public: return 0; } + virtual int32_t RegisterConfigurationObserver(const sptr& observer, int32_t userId) + { + return 0; + } + virtual int32_t UnregisterConfigurationObserver(const sptr& observer) { return 0; diff --git a/test/unittest/ui_ability_lifecycle_manager_third_test/mock/include/mock_app_mgr_service.h b/test/unittest/ui_ability_lifecycle_manager_third_test/mock/include/mock_app_mgr_service.h index 25a36af0fa2abe8fa7c3f5ee5f687c96cf5e8994..aeac6bcdfac5adc7dbc64a9046e2afda21dec87b 100644 --- a/test/unittest/ui_ability_lifecycle_manager_third_test/mock/include/mock_app_mgr_service.h +++ b/test/unittest/ui_ability_lifecycle_manager_third_test/mock/include/mock_app_mgr_service.h @@ -76,6 +76,7 @@ public: MOCK_METHOD3(UpdateConfigurationByBundleName, int32_t(const Configuration& config, const std::string &name, int32_t appIndex)); MOCK_METHOD1(RegisterConfigurationObserver, int32_t(const sptr& observer)); + MOCK_METHOD2(RegisterConfigurationObserver, int32_t(const sptr& observer, int32_t userId)); MOCK_METHOD1(UnregisterConfigurationObserver, int32_t(const sptr& observer)); MOCK_METHOD1(GetAppRunningStateByBundleName, bool(const std::string& bundleName)); MOCK_METHOD2(NotifyLoadRepairPatch, int32_t(const std::string& bundleName,