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
16 #include "dataobs_mgr_service.h"
17
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <unistd.h>
22 #include "string_ex.h"
23
24 #include "dataobs_mgr_errors.h"
25 #include "hilog_tag_wrapper.h"
26 #include "if_system_ability_manager.h"
27 #include "ipc_skeleton.h"
28 #include "system_ability_definition.h"
29 #include "common_utils.h"
30 #include "securec.h"
31
32 namespace OHOS {
33 namespace AAFwk {
34 const bool REGISTER_RESULT =
35 SystemAbility::MakeAndRegisterAbility(DelayedSingleton<DataObsMgrService>::GetInstance().get());
36
DataObsMgrService()37 DataObsMgrService::DataObsMgrService()
38 : SystemAbility(DATAOBS_MGR_SERVICE_SA_ID, true),
39 state_(DataObsServiceRunningState::STATE_NOT_START)
40 {
41 dataObsMgrInner_ = std::make_shared<DataObsMgrInner>();
42 dataObsMgrInnerExt_ = std::make_shared<DataObsMgrInnerExt>();
43 dataObsMgrInnerPref_ = std::make_shared<DataObsMgrInnerPref>();
44 }
45
~DataObsMgrService()46 DataObsMgrService::~DataObsMgrService()
47 {}
48
OnStart()49 void DataObsMgrService::OnStart()
50 {
51 if (state_ == DataObsServiceRunningState::STATE_RUNNING) {
52 TAG_LOGI(AAFwkTag::DBOBSMGR, "dms started");
53 return;
54 }
55 if (!Init()) {
56 TAG_LOGE(AAFwkTag::DBOBSMGR, "init failed");
57 return;
58 }
59 state_ = DataObsServiceRunningState::STATE_RUNNING;
60 /* Publish service maybe failed, so we need call this function at the last,
61 * so it can't affect the TDD test program */
62 if (!Publish(DelayedSingleton<DataObsMgrService>::GetInstance().get())) {
63 TAG_LOGE(AAFwkTag::DBOBSMGR, "publish init failed");
64 return;
65 }
66
67 TAG_LOGI(AAFwkTag::DBOBSMGR, "dms called");
68 }
69
Init()70 bool DataObsMgrService::Init()
71 {
72 handler_ = TaskHandlerWrap::GetFfrtHandler();
73 return true;
74 }
75
OnStop()76 void DataObsMgrService::OnStop()
77 {
78 TAG_LOGI(AAFwkTag::DBOBSMGR, "stop");
79 handler_.reset();
80 state_ = DataObsServiceRunningState::STATE_NOT_START;
81 }
82
QueryServiceState() const83 DataObsServiceRunningState DataObsMgrService::QueryServiceState() const
84 {
85 return state_;
86 }
87
RegisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)88 int DataObsMgrService::RegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
89 {
90 if (dataObserver == nullptr) {
91 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
92 CommonUtils::Anonymous(uri.ToString()).c_str());
93 return DATA_OBSERVER_IS_NULL;
94 }
95
96 if (dataObsMgrInner_ == nullptr) {
97 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
98 CommonUtils::Anonymous(uri.ToString()).c_str());
99 return DATAOBS_SERVICE_INNER_IS_NULL;
100 }
101
102 int status;
103 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
104 status = dataObsMgrInnerPref_->HandleRegisterObserver(uri, dataObserver);
105 } else {
106 status = dataObsMgrInner_->HandleRegisterObserver(uri, dataObserver);
107 }
108
109 if (status != NO_ERROR) {
110 TAG_LOGE(AAFwkTag::DBOBSMGR, "register failed:%{public}d, uri:%{public}s", status,
111 CommonUtils::Anonymous(uri.ToString()).c_str());
112 return status;
113 }
114 return NO_ERROR;
115 }
116
UnregisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)117 int DataObsMgrService::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
118 {
119 if (dataObserver == nullptr) {
120 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
121 CommonUtils::Anonymous(uri.ToString()).c_str());
122 return DATA_OBSERVER_IS_NULL;
123 }
124
125 if (dataObsMgrInner_ == nullptr) {
126 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
127 CommonUtils::Anonymous(uri.ToString()).c_str());
128 return DATAOBS_SERVICE_INNER_IS_NULL;
129 }
130
131 int status;
132 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
133 status = dataObsMgrInnerPref_->HandleUnregisterObserver(uri, dataObserver);
134 } else {
135 status = dataObsMgrInner_->HandleUnregisterObserver(uri, dataObserver);
136 }
137
138 if (status != NO_ERROR) {
139 TAG_LOGE(AAFwkTag::DBOBSMGR, "unregister failed:%{public}d, uri:%{public}s", status,
140 CommonUtils::Anonymous(uri.ToString()).c_str());
141 return status;
142 }
143 return NO_ERROR;
144 }
145
NotifyChange(const Uri & uri)146 int DataObsMgrService::NotifyChange(const Uri &uri)
147 {
148 if (handler_ == nullptr) {
149 TAG_LOGE(
150 AAFwkTag::DBOBSMGR, "null handler, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
151 return DATAOBS_SERVICE_HANDLER_IS_NULL;
152 }
153
154 if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr || dataObsMgrInnerPref_ == nullptr) {
155 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgr, uri:%{public}s",
156 CommonUtils::Anonymous(uri.ToString()).c_str());
157 return DATAOBS_SERVICE_INNER_IS_NULL;
158 }
159
160 {
161 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
162 if (taskCount_ >= TASK_COUNT_MAX) {
163 TAG_LOGE(AAFwkTag::DBOBSMGR, "task num reached limit, uri:%{public}s",
164 CommonUtils::Anonymous(uri.ToString()).c_str());
165 return DATAOBS_SERVICE_TASK_LIMMIT;
166 }
167 ++taskCount_;
168 }
169
170 ChangeInfo changeInfo = { ChangeInfo::ChangeType::OTHER, { uri } };
171 handler_->SubmitTask([this, uri, changeInfo]() {
172 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
173 dataObsMgrInnerPref_->HandleNotifyChange(uri);
174 } else {
175 dataObsMgrInner_->HandleNotifyChange(uri);
176 dataObsMgrInnerExt_->HandleNotifyChange(changeInfo);
177 }
178 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
179 --taskCount_;
180 });
181
182 return NO_ERROR;
183 }
184
RegisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,bool isDescendants)185 Status DataObsMgrService::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
186 bool isDescendants)
187 {
188 if (dataObserver == nullptr) {
189 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s, isDescendants:%{public}d",
190 CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
191 return DATA_OBSERVER_IS_NULL;
192 }
193
194 if (dataObsMgrInnerExt_ == nullptr) {
195 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s, isDescendants:%{public}d",
196 CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
197 return DATAOBS_SERVICE_INNER_IS_NULL;
198 }
199
200 auto innerUri = uri;
201 return dataObsMgrInnerExt_->HandleRegisterObserver(innerUri, dataObserver, isDescendants);
202 }
203
UnregisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)204 Status DataObsMgrService::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
205 {
206 if (dataObserver == nullptr) {
207 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
208 CommonUtils::Anonymous(uri.ToString()).c_str());
209 return DATA_OBSERVER_IS_NULL;
210 }
211
212 if (dataObsMgrInnerExt_ == nullptr) {
213 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
214 CommonUtils::Anonymous(uri.ToString()).c_str());
215 return DATAOBS_SERVICE_INNER_IS_NULL;
216 }
217
218 auto innerUri = uri;
219 return dataObsMgrInnerExt_->HandleUnregisterObserver(innerUri, dataObserver);
220 }
221
UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)222 Status DataObsMgrService::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)
223 {
224 if (dataObserver == nullptr) {
225 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver");
226 return DATA_OBSERVER_IS_NULL;
227 }
228
229 if (dataObsMgrInnerExt_ == nullptr) {
230 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner");
231 return DATAOBS_SERVICE_INNER_IS_NULL;
232 }
233
234 return dataObsMgrInnerExt_->HandleUnregisterObserver(dataObserver);
235 }
236
DeepCopyChangeInfo(const ChangeInfo & src,ChangeInfo & dst) const237 Status DataObsMgrService::DeepCopyChangeInfo(const ChangeInfo &src, ChangeInfo &dst) const
238 {
239 dst = src;
240 if (dst.size_ == 0) {
241 return SUCCESS;
242 }
243 dst.data_ = new (std::nothrow) uint8_t[dst.size_];
244 if (dst.data_ == nullptr) {
245 return DATAOBS_SERVICE_INNER_IS_NULL;
246 }
247
248 errno_t ret = memcpy_s(dst.data_, dst.size_, src.data_, src.size_);
249 if (ret != EOK) {
250 delete [] static_cast<uint8_t *>(dst.data_);
251 dst.data_ = nullptr;
252 return DATAOBS_SERVICE_INNER_IS_NULL;
253 }
254 return SUCCESS;
255 }
256
NotifyChangeExt(const ChangeInfo & changeInfo)257 Status DataObsMgrService::NotifyChangeExt(const ChangeInfo &changeInfo)
258 {
259 if (handler_ == nullptr) {
260 TAG_LOGE(AAFwkTag::DBOBSMGR, "null handler");
261 return DATAOBS_SERVICE_HANDLER_IS_NULL;
262 }
263
264 if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr) {
265 TAG_LOGE(AAFwkTag::DBOBSMGR, "dataObsMgrInner_:%{public}d or null dataObsMgrInnerExt",
266 dataObsMgrInner_ == nullptr);
267 return DATAOBS_SERVICE_INNER_IS_NULL;
268 }
269 ChangeInfo changes;
270 Status result = DeepCopyChangeInfo(changeInfo, changes);
271 if (result != SUCCESS) {
272 TAG_LOGE(AAFwkTag::DBOBSMGR,
273 "copy data failed, changeType:%{public}ud,uris num:%{public}zu, "
274 "null data:%{public}d, size:%{public}ud",
275 changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
276 return result;
277 }
278
279 {
280 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
281 if (taskCount_ >= TASK_COUNT_MAX) {
282 TAG_LOGE(AAFwkTag::DBOBSMGR,
283 "task num maxed, changeType:%{public}ud,"
284 "uris num:%{public}zu, null data:%{public}d, size:%{public}ud",
285 changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
286 return DATAOBS_SERVICE_TASK_LIMMIT;
287 }
288 ++taskCount_;
289 }
290
291 handler_->SubmitTask([this, changes]() {
292 dataObsMgrInnerExt_->HandleNotifyChange(changes);
293 for (auto &uri : changes.uris_) {
294 dataObsMgrInner_->HandleNotifyChange(uri);
295 }
296 delete [] static_cast<uint8_t *>(changes.data_);
297 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
298 --taskCount_;
299 });
300 return SUCCESS;
301 }
302
Dump(int fd,const std::vector<std::u16string> & args)303 int DataObsMgrService::Dump(int fd, const std::vector<std::u16string>& args)
304 {
305 std::string result;
306 Dump(args, result);
307 int ret = dprintf(fd, "%s\n", result.c_str());
308 if (ret < 0) {
309 TAG_LOGE(AAFwkTag::DBOBSMGR, "dprintf error");
310 return DATAOBS_HIDUMP_ERROR;
311 }
312 return SUCCESS;
313 }
314
Dump(const std::vector<std::u16string> & args,std::string & result) const315 void DataObsMgrService::Dump(const std::vector<std::u16string>& args, std::string& result) const
316 {
317 auto size = args.size();
318 if (size == 0) {
319 ShowHelp(result);
320 return;
321 }
322
323 std::string optionKey = Str16ToStr8(args[0]);
324 if (optionKey != "-h") {
325 result.append("error: unkown option.\n");
326 }
327 ShowHelp(result);
328 }
329
ShowHelp(std::string & result) const330 void DataObsMgrService::ShowHelp(std::string& result) const
331 {
332 result.append("Usage:\n")
333 .append("-h ")
334 .append("help text for the tool\n");
335 }
336 } // namespace AAFwk
337 } // namespace OHOS
338