• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_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         HILOG_INFO("Dataobs Manager Service has already started.");
53         return;
54     }
55     if (!Init()) {
56         HILOG_ERROR("failed to init service.");
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         HILOG_ERROR("Init Publish failed!");
64         return;
65     }
66 
67     HILOG_INFO("Dataobs Manager Service start success.");
68 }
69 
Init()70 bool DataObsMgrService::Init()
71 {
72     handler_ = TaskHandlerWrap::GetFfrtHandler();
73     return true;
74 }
75 
OnStop()76 void DataObsMgrService::OnStop()
77 {
78     HILOG_INFO("stop service");
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         HILOG_ERROR("dataObserver is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
92         return DATA_OBSERVER_IS_NULL;
93     }
94 
95     if (dataObsMgrInner_ == nullptr) {
96         HILOG_ERROR("dataObsMgrInner_ is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
97         return DATAOBS_SERVICE_INNER_IS_NULL;
98     }
99 
100     int status;
101     if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
102         status = dataObsMgrInnerPref_->HandleRegisterObserver(uri, dataObserver);
103     } else {
104         status = dataObsMgrInner_->HandleRegisterObserver(uri, dataObserver);
105     }
106 
107     if (status != NO_ERROR) {
108         HILOG_ERROR("Observer register failed: %{public}d, uri:%{public}s", status,
109             CommonUtils::Anonymous(uri.ToString()).c_str());
110         return status;
111     }
112     return NO_ERROR;
113 }
114 
UnregisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)115 int DataObsMgrService::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
116 {
117     if (dataObserver == nullptr) {
118         HILOG_ERROR("dataObserver is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
119         return DATA_OBSERVER_IS_NULL;
120     }
121 
122     if (dataObsMgrInner_ == nullptr) {
123         HILOG_ERROR("dataObsMgrInner_ is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
124         return DATAOBS_SERVICE_INNER_IS_NULL;
125     }
126 
127     int status;
128     if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
129         status = dataObsMgrInnerPref_->HandleUnregisterObserver(uri, dataObserver);
130     } else {
131         status = dataObsMgrInner_->HandleUnregisterObserver(uri, dataObserver);
132     }
133 
134     if (status != NO_ERROR) {
135         HILOG_ERROR("Observer unregister failed: %{public}d, uri:%{public}s", status,
136             CommonUtils::Anonymous(uri.ToString()).c_str());
137         return status;
138     }
139     return NO_ERROR;
140 }
141 
NotifyChange(const Uri & uri)142 int DataObsMgrService::NotifyChange(const Uri &uri)
143 {
144     if (handler_ == nullptr) {
145         HILOG_ERROR("handler is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
146         return DATAOBS_SERVICE_HANDLER_IS_NULL;
147     }
148 
149     if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr || dataObsMgrInnerPref_ == nullptr) {
150         HILOG_ERROR("dataObsMgr is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
151         return DATAOBS_SERVICE_INNER_IS_NULL;
152     }
153 
154     {
155         std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
156         if (taskCount_ >= TASK_COUNT_MAX) {
157             HILOG_ERROR("The number of task has reached the upper limit, uri:%{public}s",
158                 CommonUtils::Anonymous(uri.ToString()).c_str());
159             return DATAOBS_SERVICE_TASK_LIMMIT;
160         }
161         ++taskCount_;
162     }
163 
164     ChangeInfo changeInfo = { ChangeInfo::ChangeType::OTHER, { uri } };
165     handler_->SubmitTask([this, uri, changeInfo]() {
166         if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
167             dataObsMgrInnerPref_->HandleNotifyChange(uri);
168         } else {
169             dataObsMgrInner_->HandleNotifyChange(uri);
170             dataObsMgrInnerExt_->HandleNotifyChange(changeInfo);
171         }
172         std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
173         --taskCount_;
174     });
175 
176     return NO_ERROR;
177 }
178 
RegisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,bool isDescendants)179 Status DataObsMgrService::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
180     bool isDescendants)
181 {
182     if (dataObserver == nullptr) {
183         HILOG_ERROR("dataObserver is nullptr, uri:%{public}s, isDescendants:%{public}d",
184             CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
185         return DATA_OBSERVER_IS_NULL;
186     }
187 
188     if (dataObsMgrInnerExt_ == nullptr) {
189         HILOG_ERROR("dataObsMgrInner_ is nullptr, uri:%{public}s, isDescendants:%{public}d",
190             CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
191         return DATAOBS_SERVICE_INNER_IS_NULL;
192     }
193 
194     auto innerUri = uri;
195     return dataObsMgrInnerExt_->HandleRegisterObserver(innerUri, dataObserver, isDescendants);
196 }
197 
UnregisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)198 Status DataObsMgrService::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
199 {
200     if (dataObserver == nullptr) {
201         HILOG_ERROR("dataObserver is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
202         return DATA_OBSERVER_IS_NULL;
203     }
204 
205     if (dataObsMgrInnerExt_ == nullptr) {
206         HILOG_ERROR("dataObsMgrInner_ is nullptr, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
207         return DATAOBS_SERVICE_INNER_IS_NULL;
208     }
209 
210     auto innerUri = uri;
211     return dataObsMgrInnerExt_->HandleUnregisterObserver(innerUri, dataObserver);
212 }
213 
UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)214 Status DataObsMgrService::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)
215 {
216     if (dataObserver == nullptr) {
217         HILOG_ERROR("dataObserver is nullptr");
218         return DATA_OBSERVER_IS_NULL;
219     }
220 
221     if (dataObsMgrInnerExt_ == nullptr) {
222         HILOG_ERROR("dataObsMgrInner_ is nullptr");
223         return DATAOBS_SERVICE_INNER_IS_NULL;
224     }
225 
226     return dataObsMgrInnerExt_->HandleUnregisterObserver(dataObserver);
227 }
228 
DeepCopyChangeInfo(const ChangeInfo & src,ChangeInfo & dst) const229 Status DataObsMgrService::DeepCopyChangeInfo(const ChangeInfo &src, ChangeInfo &dst) const
230 {
231     dst = src;
232     if (dst.size_ == 0) {
233         return SUCCESS;
234     }
235     dst.data_ = new (std::nothrow) uint8_t[dst.size_];
236     if (dst.data_ == nullptr) {
237         return DATAOBS_SERVICE_INNER_IS_NULL;
238     }
239 
240     errno_t ret = memcpy_s(dst.data_, dst.size_, src.data_, src.size_);
241     if (ret != EOK) {
242         delete [] static_cast<uint8_t *>(dst.data_);
243         dst.data_ = nullptr;
244         return DATAOBS_SERVICE_INNER_IS_NULL;
245     }
246     return SUCCESS;
247 }
248 
NotifyChangeExt(const ChangeInfo & changeInfo)249 Status DataObsMgrService::NotifyChangeExt(const ChangeInfo &changeInfo)
250 {
251     if (handler_ == nullptr) {
252         HILOG_ERROR("handler is nullptr");
253         return DATAOBS_SERVICE_HANDLER_IS_NULL;
254     }
255 
256     if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr) {
257         HILOG_ERROR("dataObsMgrInner_:%{public}d or dataObsMgrInnerExt_ is nullptr", dataObsMgrInner_ == nullptr);
258         return DATAOBS_SERVICE_INNER_IS_NULL;
259     }
260     ChangeInfo changes;
261     Status result = DeepCopyChangeInfo(changeInfo, changes);
262     if (result != SUCCESS) {
263         HILOG_ERROR("copy data failed, changeType:%{public}ud, num of uris:%{public}zu, data is "
264                     "nullptr:%{public}d, size:%{public}ud",
265                     changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
266         return result;
267     }
268 
269     {
270         std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
271         if (taskCount_ >= TASK_COUNT_MAX) {
272             HILOG_ERROR("The number of task has reached the upper limit, changeType:%{public}ud, num of "
273                         "uris:%{public}zu, data is nullptr:%{public}d, size:%{public}ud",
274                 changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
275             return DATAOBS_SERVICE_TASK_LIMMIT;
276         }
277         ++taskCount_;
278     }
279 
280     handler_->SubmitTask([this, changes]() {
281         dataObsMgrInnerExt_->HandleNotifyChange(changes);
282         for (auto &uri : changes.uris_) {
283             dataObsMgrInner_->HandleNotifyChange(uri);
284         }
285         delete [] static_cast<uint8_t *>(changes.data_);
286         std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
287         --taskCount_;
288     });
289     return SUCCESS;
290 }
291 
Dump(int fd,const std::vector<std::u16string> & args)292 int DataObsMgrService::Dump(int fd, const std::vector<std::u16string>& args)
293 {
294     std::string result;
295     Dump(args, result);
296     int ret = dprintf(fd, "%s\n", result.c_str());
297     if (ret < 0) {
298         HILOG_ERROR("%{public}s, dprintf error.", __func__);
299         return DATAOBS_HIDUMP_ERROR;
300     }
301     return SUCCESS;
302 }
303 
Dump(const std::vector<std::u16string> & args,std::string & result) const304 void DataObsMgrService::Dump(const std::vector<std::u16string>& args, std::string& result) const
305 {
306     auto size = args.size();
307     if (size == 0) {
308         ShowHelp(result);
309         return;
310     }
311 
312     std::string optionKey = Str16ToStr8(args[0]);
313     if (optionKey != "-h") {
314         result.append("error: unkown option.\n");
315     }
316     ShowHelp(result);
317 }
318 
ShowHelp(std::string & result) const319 void DataObsMgrService::ShowHelp(std::string& result) const
320 {
321     result.append("Usage:\n")
322         .append("-h                          ")
323         .append("help text for the tool\n");
324 }
325 }  // namespace AAFwk
326 }  // namespace OHOS
327