• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define LOG_TAG "ProxyDataSubscriberManager"
17 
18 #include "proxy_data_subscriber_manager.h"
19 
20 #include "dataproxy_handle_common.h"
21 #include "ipc_skeleton.h"
22 #include "log_print.h"
23 #include "proxy_data_manager.h"
24 #include "utils.h"
25 #include "utils/anonymous.h"
26 
27 namespace OHOS::DataShare {
GetInstance()28 ProxyDataSubscriberManager &ProxyDataSubscriberManager::GetInstance()
29 {
30     static ProxyDataSubscriberManager manager;
31     return manager;
32 }
33 
Add(const ProxyDataKey & key,const sptr<IProxyDataObserver> & observer,const std::string & bundleName,const std::string & callerAppIdentifier,const int32_t & userId)34 DataProxyErrorCode ProxyDataSubscriberManager::Add(const ProxyDataKey &key, const sptr<IProxyDataObserver> &observer,
35     const std::string &bundleName, const std::string &callerAppIdentifier, const int32_t &userId)
36 {
37     auto callerTokenId = IPCSkeleton::GetCallingTokenID();
38     ProxyDataCache_.Compute(
39         key, [&observer, callerTokenId, bundleName, callerAppIdentifier, userId](const ProxyDataKey &key,
40         std::vector<ObserverNode> &value) {
41             ZLOGI("add proxy data subscriber, uri %{public}s",
42                 URIUtils::Anonymous(key.uri).c_str());
43             value.emplace_back(observer, callerTokenId, bundleName, callerAppIdentifier, userId);
44             return true;
45         });
46     return SUCCESS;
47 }
48 
Delete(const ProxyDataKey & key,const int32_t & userId)49 DataProxyErrorCode ProxyDataSubscriberManager::Delete(const ProxyDataKey &key, const int32_t &userId)
50 {
51     auto callerTokenId = IPCSkeleton::GetCallingTokenID();
52     auto result =
53         ProxyDataCache_.ComputeIfPresent(key, [&userId, callerTokenId](const auto &key,
54             std::vector<ObserverNode> &value) {
55             for (auto it = value.begin(); it != value.end();) {
56                 if (it->callerTokenId == callerTokenId && it->userId == userId) {
57                     ZLOGI("delete proxy data subscriber, uri %{public}s",
58                         URIUtils::Anonymous(key.uri).c_str());
59                     it = value.erase(it);
60                 } else {
61                     it++;
62                 }
63             }
64             return !value.empty();
65         });
66     return result ? SUCCESS : URI_NOT_EXIST;
67 }
68 
CheckAllowList(const std::vector<std::string> & allowList,const std::string & callerAppIdentifier)69 bool ProxyDataSubscriberManager::CheckAllowList(const std::vector<std::string> &allowList,
70     const std::string &callerAppIdentifier)
71 {
72     for (const auto &item : allowList) {
73         if (callerAppIdentifier == item || item == ALLOW_ALL) {
74             return true;
75         }
76     }
77     return false;
78 }
79 
80 // if arg observer is not null, notify that observer only; otherwise notify all observers
Emit(const std::vector<ProxyDataKey> & keys,const std::map<DataShareObserver::ChangeType,std::vector<DataShareProxyData>> & datas,const int32_t & userId)81 void ProxyDataSubscriberManager::Emit(const std::vector<ProxyDataKey> &keys,
82     const std::map<DataShareObserver::ChangeType, std::vector<DataShareProxyData>> &datas, const int32_t &userId)
83 {
84     std::map<sptr<IProxyDataObserver>, std::vector<DataProxyChangeInfo>> callbacks;
85     for (auto typeIt = datas.begin(); typeIt != datas.end(); ++typeIt) {
86         auto type = typeIt->first;
87         for (const auto &data : typeIt->second) {
88             std::string bundleName;
89             URIUtils::GetBundleNameFromProxyURI(data.uri_, bundleName);
90             auto it = ProxyDataCache_.Find(ProxyDataKey(data.uri_, bundleName));
91             if (!it.first) {
92                 continue;
93             }
94             auto &observers = it.second;
95             std::for_each(observers.begin(), observers.end(),
96                 [&callbacks, data, userId, bundleName, &type, this](const auto &obs) {
97                 if ((CheckAllowList(data.allowList_, obs.callerAppIdentifier) ||
98                     bundleName == obs.bundleName) && obs.userId == userId) {
99                     callbacks[obs.observer].emplace_back(type, data.uri_, data.value_);
100                 } else {
101                     ZLOGE("no permission to receive notification");
102                 }
103             });
104         }
105     }
106     for (auto &[callback, changeInfo] : callbacks) {
107         if (callback != nullptr) {
108             callback->OnChangeFromProxyData(changeInfo);
109         }
110     }
111 }
112 
Clear()113 void ProxyDataSubscriberManager::Clear()
114 {
115     ProxyDataCache_.Clear();
116 }
117 
ProxyDataKey(const std::string & uri,const std::string & bundle)118 ProxyDataKey::ProxyDataKey(const std::string &uri, const std::string &bundle)
119     : uri(uri), bundleName(bundle)
120 {
121     /* private published data can use key as simple uri */
122     /* etc: datashareproxy://{bundleName}/meeting can use meeting replaced */
123     /* if key is normal uri, bundleName is from uri */
124     if (URIUtils::IsDataProxyURI(uri)) {
125         URIUtils::GetBundleNameFromProxyURI(uri, bundleName);
126     }
127 }
128 
operator <(const ProxyDataKey & rhs) const129 bool ProxyDataKey::operator<(const ProxyDataKey &rhs) const
130 {
131     return uri < rhs.uri;
132 }
133 
operator >(const ProxyDataKey & rhs) const134 bool ProxyDataKey::operator>(const ProxyDataKey &rhs) const
135 {
136     return rhs < *this;
137 }
138 
operator <=(const ProxyDataKey & rhs) const139 bool ProxyDataKey::operator<=(const ProxyDataKey &rhs) const
140 {
141     return !(rhs < *this);
142 }
143 
operator >=(const ProxyDataKey & rhs) const144 bool ProxyDataKey::operator>=(const ProxyDataKey &rhs) const
145 {
146     return !(*this < rhs);
147 }
148 
operator ==(const ProxyDataKey & rhs) const149 bool ProxyDataKey::operator==(const ProxyDataKey &rhs) const
150 {
151     return uri == rhs.uri && bundleName == rhs.bundleName;
152 }
153 
operator !=(const ProxyDataKey & rhs) const154 bool ProxyDataKey::operator!=(const ProxyDataKey &rhs) const
155 {
156     return !(rhs == *this);
157 }
158 
ObserverNode(const sptr<IProxyDataObserver> & observer,const uint32_t & callerTokenId,const std::string & bundleName,const std::string & callerAppIdentifier,const int32_t & userId)159 ProxyDataSubscriberManager::ObserverNode::ObserverNode(const sptr<IProxyDataObserver> &observer,
160     const uint32_t &callerTokenId, const std::string &bundleName,
161     const std::string &callerAppIdentifier, const int32_t &userId) : observer(observer),
162     callerTokenId(callerTokenId), bundleName(bundleName), callerAppIdentifier(callerAppIdentifier), userId(userId)
163 {
164 }
165 } // namespace OHOS::DataShare
166