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 d1b45596bad024345fbd5d991c57b8f3aa0c1475..f37cd92dfdffcc48b5be4c04b6ccec7301692132 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 cea47b58b666c23ec238416fe7896ac8a9e221d2..500d39e5670a12137cb09463dafda557253c8281 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 e2e7135ffd3294656e10a7a4fa9c068c91a8710d..8edb285424fdab803a519401b6c04b7b5a559d1a 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 20ca8dd81e2f52732192133e9c4ba494df0d84ee..a9d308c16277ca43563361555e99bc7c46cdb27c 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 d55ec512f85ba94183ad69066b79050214d905e1..5e40df422e8a8b10b36d4dc59a4b2c3f0db5e193 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