From 8edc24a10cd6c083832ffbf2ae898fed429f7cab Mon Sep 17 00:00:00 2001 From: qibao Date: Sat, 6 Sep 2025 11:16:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=A2=E9=98=85=E4=B8=8E?= =?UTF-8?q?=E5=8F=96=E6=B6=88=E8=AE=A2=E9=98=85=E5=AD=98=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E9=81=97=E7=95=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue:#ICWOPA Reason 订阅与取消订阅存在一些遗留问题 Description 订阅/取消订阅proxyData时在锁中getCallingTokenId,ipc的getValidInstance耗时长,分析可否优化使用方式 订阅ProxyData后,客户端退出时未自动取消订阅 recover时若客户端未注册任何监听,也会向服务端发请求 Tests ninja all tests Signed-off-by: qibao --- .../data_share/data_share_service_impl.cpp | 11 ++++--- .../proxy_data_subscriber_manager.cpp | 33 ++++++++++++++----- .../proxy_data_subscriber_manager.h | 10 +++--- .../service/test/data_proxy_handle_test.cpp | 30 +++++++++++++++++ .../datasharesubscriber_fuzzer.cpp | 8 +++-- 5 files changed, 73 insertions(+), 19 deletions(-) diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index d1b45596b..f37cd92df 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -797,6 +797,7 @@ int32_t DataShareServiceImpl::OnAppExit(pid_t uid, pid_t pid, uint32_t tokenId, uid, pid, tokenId, bundleName.c_str()); RdbSubscriberManager::GetInstance().Delete(tokenId, pid); PublishedDataSubscriberManager::GetInstance().Delete(tokenId, pid); + ProxyDataSubscriberManager::GetInstance().Delete(tokenId, pid); return E_OK; } @@ -1114,14 +1115,14 @@ std::vector DataShareServiceImpl::SubscribeProxyData(const std: ZLOGE("get callerBundleInfo failed"); return results; } + auto callingPid = IPCSkeleton::GetCallingPid(); for (const auto &uri : uris) { DataShareProxyData proxyData; DataProxyErrorCode ret = static_cast(PublishedProxyData::Query(uri, callerBundleInfo, proxyData)); if (ret == SUCCESS) { ret = ProxyDataSubscriberManager::GetInstance().Add( - ProxyDataKey(uri, callerBundleInfo.bundleName), observer, callerBundleInfo.bundleName, - callerBundleInfo.appIdentifier, callerBundleInfo.userId); + ProxyDataKey(uri, callerBundleInfo.bundleName), observer, callerBundleInfo, callingPid); } results.emplace_back(uri, ret); } @@ -1133,10 +1134,12 @@ std::vector DataShareServiceImpl::UnsubscribeProxyData(const st { std::string bundleName; GetCallerBundleName(bundleName); - int32_t userId = AccountDelegate::GetInstance()->GetUserByToken(IPCSkeleton::GetCallingTokenID()); + auto callerTokenId = IPCSkeleton::GetCallingTokenID(); + int32_t userId = AccountDelegate::GetInstance()->GetUserByToken(callerTokenId); std::vector result = {}; for (const auto &uri : uris) { - auto ret = ProxyDataSubscriberManager::GetInstance().Delete(ProxyDataKey(uri, bundleName), userId); + auto key = ProxyDataKey(uri, bundleName); + auto ret = ProxyDataSubscriberManager::GetInstance().Delete(key, userId, callerTokenId); result.emplace_back(uri, ret); } return result; diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.cpp b/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.cpp index cea47b58b..500d39e56 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.cpp +++ b/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.cpp @@ -32,23 +32,22 @@ ProxyDataSubscriberManager &ProxyDataSubscriberManager::GetInstance() } DataProxyErrorCode ProxyDataSubscriberManager::Add(const ProxyDataKey &key, const sptr &observer, - const std::string &bundleName, const std::string &callerAppIdentifier, const int32_t &userId) + const BundleInfo &callerBundleInfo, uint32_t callerPid) { - auto callerTokenId = IPCSkeleton::GetCallingTokenID(); ProxyDataCache_.Compute( - key, [&observer, callerTokenId, bundleName, callerAppIdentifier, userId](const ProxyDataKey &key, + key, [&observer, &callerBundleInfo, callerPid](const ProxyDataKey &key, std::vector &value) { ZLOGI("add proxy data subscriber, uri %{public}s", URIUtils::Anonymous(key.uri).c_str()); - value.emplace_back(observer, callerTokenId, bundleName, callerAppIdentifier, userId); + value.emplace_back(observer, callerBundleInfo, callerPid); return true; }); return SUCCESS; } -DataProxyErrorCode ProxyDataSubscriberManager::Delete(const ProxyDataKey &key, const int32_t &userId) +DataProxyErrorCode ProxyDataSubscriberManager::Delete(const ProxyDataKey &key, const int32_t &userId, + const uint32_t callerTokenId) { - auto callerTokenId = IPCSkeleton::GetCallingTokenID(); auto result = ProxyDataCache_.ComputeIfPresent(key, [&userId, callerTokenId](const auto &key, std::vector &value) { @@ -66,6 +65,22 @@ DataProxyErrorCode ProxyDataSubscriberManager::Delete(const ProxyDataKey &key, c return result ? SUCCESS : URI_NOT_EXIST; } +void ProxyDataSubscriberManager::Delete(uint32_t callerTokenId, uint32_t callerPid) +{ + ProxyDataCache_.EraseIf([&callerTokenId, &callerPid](const auto &key, std::vector &value) { + for (auto it = value.begin(); it != value.end();) { + if (it->callerTokenId == callerTokenId && it->callerPid == callerPid) { + ZLOGI("erase start, uri is %{public}s, tokenId is 0x%{public}x, pid is %{public}d", + URIUtils::Anonymous(key.uri).c_str(), callerTokenId, callerPid); + it = value.erase(it); + } else { + it++; + } + } + return value.empty(); + }); +} + bool ProxyDataSubscriberManager::CheckAllowList(const std::vector &allowList, const std::string &callerAppIdentifier) { @@ -157,9 +172,9 @@ bool ProxyDataKey::operator!=(const ProxyDataKey &rhs) const } ProxyDataSubscriberManager::ObserverNode::ObserverNode(const sptr &observer, - const uint32_t &callerTokenId, const std::string &bundleName, - const std::string &callerAppIdentifier, const int32_t &userId) : observer(observer), - callerTokenId(callerTokenId), bundleName(bundleName), callerAppIdentifier(callerAppIdentifier), userId(userId) + const BundleInfo &callerBundleInfo, uint32_t callerPid) : observer(observer), + callerTokenId(callerBundleInfo.tokenId), callerPid(callerPid), bundleName(callerBundleInfo.bundleName), + callerAppIdentifier(callerBundleInfo.appIdentifier), userId(callerBundleInfo.userId) { } } // namespace OHOS::DataShare diff --git a/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.h b/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.h index e2e7135ff..8edb28542 100644 --- a/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.h +++ b/services/distributeddataservice/service/data_share/subscriber_managers/proxy_data_subscriber_manager.h @@ -19,6 +19,7 @@ #include "concurrent_map.h" #include "data_proxy_observer.h" #include "dataproxy_handle_common.h" +#include "bundle_mgr_proxy.h" namespace OHOS::DataShare { struct ProxyDataKey { @@ -37,18 +38,19 @@ class ProxyDataSubscriberManager { public: static ProxyDataSubscriberManager &GetInstance(); DataProxyErrorCode Add(const ProxyDataKey &key, const sptr &observer, - const std::string &bundleName, const std::string &callerAppIdentifier, const int32_t &userId); - DataProxyErrorCode Delete(const ProxyDataKey &key, const int32_t &userId); + const BundleInfo &callerBundleInfo, uint32_t callerPid); + DataProxyErrorCode Delete(const ProxyDataKey &key, const int32_t &userId, const uint32_t callerTokenId); + void Delete(uint32_t callerTokenId, uint32_t callerPid); void Emit(const std::vector &keys, const std::map> &datas, const int32_t &userId); void Clear(); private: struct ObserverNode { - ObserverNode(const sptr &observer, const uint32_t &callerTokenId, - const std::string &bundleName, const std::string &callerAppIdentifier, const int32_t &userId = 0); + ObserverNode(const sptr &observer, const BundleInfo &callerBundleInfo, uint32_t callerPid); sptr observer; uint32_t callerTokenId; + uint32_t callerPid; std::string bundleName; std::string callerAppIdentifier; int32_t userId = 0; diff --git a/services/distributeddataservice/service/test/data_proxy_handle_test.cpp b/services/distributeddataservice/service/test/data_proxy_handle_test.cpp index 20ca8dd81..a9d308c16 100644 --- a/services/distributeddataservice/service/test/data_proxy_handle_test.cpp +++ b/services/distributeddataservice/service/test/data_proxy_handle_test.cpp @@ -27,6 +27,9 @@ #include "proxy_data_manager.h" #include "system_ability_definition.h" #include "token_setproc.h" +#include "bundle_mgr_proxy.h" +#include "proxy_data_subscriber_manager.h" +#include "data_share_obs_proxy.h" using namespace testing::ext; using namespace OHOS::DataShare; @@ -491,4 +494,31 @@ HWTEST_F(DataShareProxyHandleTest, GetProxyData002, TestSize.Level1) SetSelfTokenID(tokenId); ZLOGI("DataShareProxyHandleTest GetProxyData002 end"); } + +/** +* @tc.name: Delete001 +* @tc.desc: test delete subscriber for app exit function +* @tc.type: FUNC +* @tc.require: +*/ +HWTEST_F(DataShareProxyHandleTest, Delete001, TestSize.Level1) +{ + ZLOGI("DataShareProxyHandleTest Delete001 start"); + BundleInfo callerBundleInfo; + callerBundleInfo.bundleName = "testBundle"; + callerBundleInfo.appIdentifier = "123456789"; + callerBundleInfo.appIndex = 0; + callerBundleInfo.userId = USER_TEST; + callerBundleInfo.tokenId = 12345678; + ProxyDataKey key(TEST_URI1, BUNDLE_NAME); + sptr observer; + auto ret = ProxyDataSubscriberManager::GetInstance().Add(key, observer, callerBundleInfo.bundleName, + callerBundleInfo.appIdentifier, callerBundleInfo.userId); + EXPECT_EQ(ret, OHOS::DataShare::SUCCESS); + + uint32_t notSubscribedTokenId = 12121212; + ProxyDataSubscriberManager::GetInstance().Delete(notSubscribedTokenId); + ProxyDataSubscriberManager::GetInstance().Delete(callerBundleInfo.tokenId); + ZLOGI("DataShareProxyHandleTest Delete001 end"); +} } // namespace OHOS::Test \ No newline at end of file diff --git a/services/distributeddataservice/service/test/fuzztest/datasharesubscriber_fuzzer/datasharesubscriber_fuzzer.cpp b/services/distributeddataservice/service/test/fuzztest/datasharesubscriber_fuzzer/datasharesubscriber_fuzzer.cpp index d55ec512f..5e40df422 100644 --- a/services/distributeddataservice/service/test/fuzztest/datasharesubscriber_fuzzer/datasharesubscriber_fuzzer.cpp +++ b/services/distributeddataservice/service/test/fuzztest/datasharesubscriber_fuzzer/datasharesubscriber_fuzzer.cpp @@ -38,7 +38,9 @@ void AddFuzz(FuzzedDataProvider &provider) std::string callerAppIdentifier = provider.ConsumeRandomLengthString(); int32_t userId = provider.ConsumeIntegral(); auto& manager = ProxyDataSubscriberManager::GetInstance(); - manager.Add(key, observer, bundleName, callerAppIdentifier, userId); + BundleInfo callerBundleInfo {bundleName, callerAppIdentifier, userId, 0, IPCSkeleton::GetCallingTokenID()}; + auto callingPid = IPCSkeleton::GetCallingPid(); + manager.Add(key, observer, callerBundleInfo, callingPid); } void CheckAllowListFuzz(FuzzedDataProvider &provider) @@ -77,10 +79,12 @@ void ObserverNodeFuzz(FuzzedDataProvider &provider) { sptr observer; uint32_t tokenId = provider.ConsumeIntegral(); + auto callingPid = IPCSkeleton::GetCallingPid(); std::string name = provider.ConsumeRandomLengthString(); std::string caller = provider.ConsumeRandomLengthString(); int32_t userId = provider.ConsumeIntegral(); - ProxyDataSubscriberManager::ObserverNode observerNode(observer, tokenId, name, caller, userId); + const BundleInfo &callerBundleInfo {name, caller, userId, 0, tokenId}; + ProxyDataSubscriberManager::ObserverNode observerNode(observer, callerBundleInfo, callingPid); } } // namespace OHOS -- Gitee