• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 #include "dataobs_mgr_inner.h"
16 
17 #include "data_ability_observer_stub.h"
18 #include "data_share_permission.h"
19 #include "dataobs_mgr_errors.h"
20 #include "datashare_errno.h"
21 #include "hilog_tag_wrapper.h"
22 #include "common_utils.h"
23 #include <string>
24 namespace OHOS {
25 namespace AAFwk {
26 
DataObsMgrInner()27 DataObsMgrInner::DataObsMgrInner() {}
28 
~DataObsMgrInner()29 DataObsMgrInner::~DataObsMgrInner() {}
30 
HandleRegisterObserver(const Uri & uri,struct ObserverNode observerNode)31 int DataObsMgrInner::HandleRegisterObserver(const Uri &uri, struct ObserverNode observerNode)
32 {
33     std::lock_guard<ffrt::mutex> lock(innerMutex_);
34 
35     auto [obsPair, flag] = observers_.try_emplace(uri.ToString(), std::list<struct ObserverNode>());
36     if (!flag && obsPair->second.size() >= OBS_ALL_NUM_MAX) {
37         TAG_LOGE(AAFwkTag::DBOBSMGR,
38             "subscribers num:%{public}s maxed",
39             CommonUtils::Anonymous(uri.ToString()).c_str());
40         return DATAOBS_SERVICE_OBS_LIMMIT;
41     }
42 
43     uint32_t tokenCount = 0;
44     for (auto obs = obsPair->second.begin(); obs != obsPair->second.end(); obs++) {
45         if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) {
46             TAG_LOGE(AAFwkTag::DBOBSMGR, "obs registered:%{public}s",
47                 CommonUtils::Anonymous(uri.ToString()).c_str());
48             return OBS_EXIST;
49         }
50         if ((*obs).tokenId_ == observerNode.tokenId_) {
51             tokenCount++;
52             if (tokenCount > OBS_NUM_MAX) {
53                 TAG_LOGE(AAFwkTag::DBOBSMGR, "subscribers num:%{public}s maxed, token:%{public}d",
54                     CommonUtils::Anonymous(uri.ToString()).c_str(), observerNode.tokenId_);
55                 return DATAOBS_SERVICE_OBS_LIMMIT;
56             }
57         }
58     }
59 
60     obsPair->second.push_back(observerNode);
61 
62     AddObsDeathRecipient(observerNode.observer_);
63 
64     return NO_ERROR;
65 }
66 
HandleUnregisterObserver(const Uri & uri,struct ObserverNode observerNode)67 int DataObsMgrInner::HandleUnregisterObserver(const Uri &uri, struct ObserverNode observerNode)
68 {
69     std::lock_guard<ffrt::mutex> lock(innerMutex_);
70 
71     auto obsPair = observers_.find(uri.ToString());
72     if (obsPair == observers_.end()) {
73         TAG_LOGW(
74             AAFwkTag::DBOBSMGR, "uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
75         return NO_OBS_FOR_URI;
76     }
77 
78     TAG_LOGD(AAFwkTag::DBOBSMGR, "obs num:%{public}zu:%{public}s", obsPair->second.size(),
79         CommonUtils::Anonymous(uri.ToString()).c_str());
80     auto obs = obsPair->second.begin();
81     for (; obs != obsPair->second.end(); obs++) {
82         if ((*obs).observer_->AsObject() == observerNode.observer_->AsObject()) {
83             break;
84         }
85     }
86     if (obs == obsPair->second.end()) {
87         TAG_LOGW(
88             AAFwkTag::DBOBSMGR, "uri no obs:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
89         return NO_OBS_FOR_URI;
90     }
91     obsPair->second.remove(*obs);
92     if (obsPair->second.empty()) {
93         observers_.erase(obsPair);
94     }
95 
96     if (!HaveRegistered(observerNode.observer_)) {
97         RemoveObsDeathRecipient(observerNode.observer_->AsObject());
98     }
99 
100     return NO_ERROR;
101 }
102 
HandleNotifyChange(const Uri & uri,int32_t userId)103 int DataObsMgrInner::HandleNotifyChange(const Uri &uri, int32_t userId)
104 {
105     std::string uriStr = uri.ToString();
106     std::list<struct ObserverNode> obsList;
107     std::lock_guard<ffrt::mutex> lock(innerMutex_);
108     {
109         auto obsPair = observers_.find(uriStr);
110         if (obsPair == observers_.end()) {
111             TAG_LOGD(AAFwkTag::DBOBSMGR, "uri no obs:%{public}s",
112                 CommonUtils::Anonymous(uriStr).c_str());
113             return NO_OBS_FOR_URI;
114         }
115         obsList = obsPair->second;
116     }
117 
118     for (auto &obs : obsList) {
119         if (obs.observer_ == nullptr) {
120             continue;
121         }
122         if (obs.userId_ != 0 && userId != 0 && obs.userId_ != userId) {
123             TAG_LOGW(AAFwkTag::DBOBSMGR, "Not allow across user notify, %{public}d to %{public}d, %{public}s",
124                 userId, obs.userId_, CommonUtils::Anonymous(uriStr).c_str());
125             continue;
126         }
127         uint32_t token = obs.isExtension_ ? obs.firstCallerTokenID_ : obs.tokenId_;
128         std::string permission = obs.permission_;
129         if (!permission.empty() && !DataShare::DataSharePermission::VerifyPermission(token,
130             permission)) {
131             TAG_LOGE(AAFwkTag::DBOBSMGR, "HandleNotifyChange permission denied, token %{public}d permission "
132                 "%{public}s uri %{public}s", token, permission.c_str(), CommonUtils::Anonymous(uriStr).c_str());
133             // just hisysevent now
134             std::string msg = __FUNCTION__;
135             DataShare::DataSharePermission::ReportExtensionFault(DataShare::E_DATASHARE_PERMISSION_DENIED, token,
136                 uriStr, msg);
137         }
138         obs.observer_->OnChange();
139     }
140 
141     TAG_LOGD(AAFwkTag::DBOBSMGR, "uri end:%{public}s,obs num:%{public}zu",
142         CommonUtils::Anonymous(uri.ToString()).c_str(), obsList.size());
143     return NO_ERROR;
144 }
145 
AddObsDeathRecipient(sptr<IDataAbilityObserver> dataObserver)146 void DataObsMgrInner::AddObsDeathRecipient(sptr<IDataAbilityObserver> dataObserver)
147 {
148     if ((dataObserver == nullptr) || dataObserver->AsObject() == nullptr) {
149         return;
150     }
151 
152     auto it = obsRecipient_.find(dataObserver->AsObject());
153     if (it != obsRecipient_.end()) {
154         TAG_LOGW(AAFwkTag::DBOBSMGR, "called");
155         return;
156     } else {
157         std::weak_ptr<DataObsMgrInner> thisWeakPtr(shared_from_this());
158         sptr<IRemoteObject::DeathRecipient> deathRecipient =
159             new DataObsCallbackRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
160                 auto dataObsMgrInner = thisWeakPtr.lock();
161                 if (dataObsMgrInner) {
162                     dataObsMgrInner->OnCallBackDied(remote);
163                 }
164             });
165         if (!dataObserver->AsObject()->AddDeathRecipient(deathRecipient)) {
166             TAG_LOGE(AAFwkTag::DBOBSMGR, "failed");
167         }
168         obsRecipient_.emplace(dataObserver->AsObject(), deathRecipient);
169     }
170 }
171 
RemoveObsDeathRecipient(sptr<IRemoteObject> dataObserver)172 void DataObsMgrInner::RemoveObsDeathRecipient(sptr<IRemoteObject> dataObserver)
173 {
174     if (dataObserver == nullptr) {
175         return;
176     }
177 
178     auto it = obsRecipient_.find(dataObserver);
179     if (it != obsRecipient_.end()) {
180         it->first->RemoveDeathRecipient(it->second);
181         obsRecipient_.erase(it);
182         return;
183     }
184 }
185 
OnCallBackDied(const wptr<IRemoteObject> & remote)186 void DataObsMgrInner::OnCallBackDied(const wptr<IRemoteObject> &remote)
187 {
188     auto dataObserver = remote.promote();
189     if (dataObserver == nullptr) {
190         return;
191     }
192     std::lock_guard<ffrt::mutex> lock(innerMutex_);
193 
194     if (dataObserver == nullptr) {
195         TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver");
196         return;
197     }
198 
199     RemoveObs(dataObserver);
200 }
201 
202 // remove dataObserver of all users
RemoveObs(sptr<IRemoteObject> dataObserver)203 void DataObsMgrInner::RemoveObs(sptr<IRemoteObject> dataObserver)
204 {
205     for (auto iter = observers_.begin(); iter != observers_.end();) {
206         auto &obsList = iter->second;
207         for (auto it = obsList.begin(); it != obsList.end(); it++) {
208             if ((*it).observer_->AsObject() == dataObserver) {
209                 TAG_LOGD(AAFwkTag::DBOBSMGR, "erase");
210                 obsList.erase(it);
211                 break;
212             }
213         }
214         if (obsList.size() == 0) {
215             iter = observers_.erase(iter);
216         } else {
217             iter++;
218         }
219     }
220     RemoveObsDeathRecipient(dataObserver);
221 }
222 
HaveRegistered(sptr<IDataAbilityObserver> dataObserver)223 bool DataObsMgrInner::HaveRegistered(sptr<IDataAbilityObserver> dataObserver)
224 {
225     for (auto &[key, value] : observers_) {
226         for (struct ObserverNode& node: value) {
227             if (node.observer_ == dataObserver) {
228                 return true;
229             }
230         }
231     }
232     return false;
233 }
234 }  // namespace AAFwk
235 }  // namespace OHOS
236