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 "ability_connect_callback_stub.h"
25 #include "ability_manager_interface.h"
26 #include "ability_manager_proxy.h"
27 #include "dataobs_mgr_errors.h"
28 #include "hilog_tag_wrapper.h"
29 #include "if_system_ability_manager.h"
30 #include "in_process_call_wrapper.h"
31 #include "ipc_skeleton.h"
32 #include "iservice_registry.h"
33 #include "system_ability_definition.h"
34 #include "common_utils.h"
35 #include "securec.h"
36 #ifdef SCENE_BOARD_ENABLE
37 #include "window_manager_lite.h"
38 #else
39 #include "window_manager.h"
40 #endif
41
42 namespace OHOS {
43 namespace AAFwk {
44 static constexpr const char *DIALOG_APP = "com.ohos.pasteboarddialog";
45 static constexpr const char *PROGRESS_ABILITY = "PasteboardProgressAbility";
46 static constexpr const char *PROMPT_TEXT = "PromptText_PasteBoard_Local";
47
48 const bool REGISTER_RESULT =
49 SystemAbility::MakeAndRegisterAbility(DelayedSingleton<DataObsMgrService>::GetInstance().get());
50
DataObsMgrService()51 DataObsMgrService::DataObsMgrService()
52 : SystemAbility(DATAOBS_MGR_SERVICE_SA_ID, true),
53 state_(DataObsServiceRunningState::STATE_NOT_START)
54 {
55 dataObsMgrInner_ = std::make_shared<DataObsMgrInner>();
56 dataObsMgrInnerExt_ = std::make_shared<DataObsMgrInnerExt>();
57 dataObsMgrInnerPref_ = std::make_shared<DataObsMgrInnerPref>();
58 }
59
~DataObsMgrService()60 DataObsMgrService::~DataObsMgrService()
61 {}
62
OnStart()63 void DataObsMgrService::OnStart()
64 {
65 if (state_ == DataObsServiceRunningState::STATE_RUNNING) {
66 TAG_LOGI(AAFwkTag::DBOBSMGR, "dms started");
67 return;
68 }
69 if (!Init()) {
70 TAG_LOGE(AAFwkTag::DBOBSMGR, "init failed");
71 return;
72 }
73 state_ = DataObsServiceRunningState::STATE_RUNNING;
74 /* Publish service maybe failed, so we need call this function at the last,
75 * so it can't affect the TDD test program */
76 if (!Publish(DelayedSingleton<DataObsMgrService>::GetInstance().get())) {
77 TAG_LOGE(AAFwkTag::DBOBSMGR, "publish init failed");
78 return;
79 }
80
81 TAG_LOGI(AAFwkTag::DBOBSMGR, "dms called");
82 }
83
Init()84 bool DataObsMgrService::Init()
85 {
86 handler_ = TaskHandlerWrap::GetFfrtHandler();
87 return true;
88 }
89
OnStop()90 void DataObsMgrService::OnStop()
91 {
92 TAG_LOGI(AAFwkTag::DBOBSMGR, "stop");
93 handler_.reset();
94 state_ = DataObsServiceRunningState::STATE_NOT_START;
95 }
96
QueryServiceState() const97 DataObsServiceRunningState DataObsMgrService::QueryServiceState() const
98 {
99 return state_;
100 }
101
RegisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)102 int DataObsMgrService::RegisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
103 {
104 if (dataObserver == nullptr) {
105 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
106 CommonUtils::Anonymous(uri.ToString()).c_str());
107 return DATA_OBSERVER_IS_NULL;
108 }
109
110 if (dataObsMgrInner_ == nullptr) {
111 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
112 CommonUtils::Anonymous(uri.ToString()).c_str());
113 return DATAOBS_SERVICE_INNER_IS_NULL;
114 }
115
116 int status;
117 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
118 status = dataObsMgrInnerPref_->HandleRegisterObserver(uri, dataObserver);
119 } else {
120 status = dataObsMgrInner_->HandleRegisterObserver(uri, dataObserver);
121 }
122
123 if (status != NO_ERROR) {
124 TAG_LOGE(AAFwkTag::DBOBSMGR, "register failed:%{public}d, uri:%{public}s", status,
125 CommonUtils::Anonymous(uri.ToString()).c_str());
126 return status;
127 }
128 return NO_ERROR;
129 }
130
UnregisterObserver(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)131 int DataObsMgrService::UnregisterObserver(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
132 {
133 if (dataObserver == nullptr) {
134 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
135 CommonUtils::Anonymous(uri.ToString()).c_str());
136 return DATA_OBSERVER_IS_NULL;
137 }
138
139 if (dataObsMgrInner_ == nullptr) {
140 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
141 CommonUtils::Anonymous(uri.ToString()).c_str());
142 return DATAOBS_SERVICE_INNER_IS_NULL;
143 }
144
145 int status;
146 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
147 status = dataObsMgrInnerPref_->HandleUnregisterObserver(uri, dataObserver);
148 } else {
149 status = dataObsMgrInner_->HandleUnregisterObserver(uri, dataObserver);
150 }
151
152 if (status != NO_ERROR) {
153 TAG_LOGE(AAFwkTag::DBOBSMGR, "unregister failed:%{public}d, uri:%{public}s", status,
154 CommonUtils::Anonymous(uri.ToString()).c_str());
155 return status;
156 }
157 return NO_ERROR;
158 }
159
NotifyChange(const Uri & uri)160 int DataObsMgrService::NotifyChange(const Uri &uri)
161 {
162 if (handler_ == nullptr) {
163 TAG_LOGE(
164 AAFwkTag::DBOBSMGR, "null handler, uri:%{public}s", CommonUtils::Anonymous(uri.ToString()).c_str());
165 return DATAOBS_SERVICE_HANDLER_IS_NULL;
166 }
167
168 if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr || dataObsMgrInnerPref_ == nullptr) {
169 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgr, uri:%{public}s",
170 CommonUtils::Anonymous(uri.ToString()).c_str());
171 return DATAOBS_SERVICE_INNER_IS_NULL;
172 }
173
174 {
175 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
176 if (taskCount_ >= TASK_COUNT_MAX) {
177 TAG_LOGE(AAFwkTag::DBOBSMGR, "task num reached limit, uri:%{public}s",
178 CommonUtils::Anonymous(uri.ToString()).c_str());
179 return DATAOBS_SERVICE_TASK_LIMMIT;
180 }
181 ++taskCount_;
182 }
183
184 ChangeInfo changeInfo = { ChangeInfo::ChangeType::OTHER, { uri } };
185 handler_->SubmitTask([this, uri, changeInfo]() {
186 if (const_cast<Uri &>(uri).GetScheme() == SHARE_PREFERENCES) {
187 dataObsMgrInnerPref_->HandleNotifyChange(uri);
188 } else {
189 dataObsMgrInner_->HandleNotifyChange(uri);
190 dataObsMgrInnerExt_->HandleNotifyChange(changeInfo);
191 }
192 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
193 --taskCount_;
194 });
195
196 return NO_ERROR;
197 }
198
RegisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver,bool isDescendants)199 Status DataObsMgrService::RegisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver,
200 bool isDescendants)
201 {
202 if (dataObserver == nullptr) {
203 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s, isDescendants:%{public}d",
204 CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
205 return DATA_OBSERVER_IS_NULL;
206 }
207
208 if (dataObsMgrInnerExt_ == nullptr) {
209 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s, isDescendants:%{public}d",
210 CommonUtils::Anonymous(uri.ToString()).c_str(), isDescendants);
211 return DATAOBS_SERVICE_INNER_IS_NULL;
212 }
213
214 auto innerUri = uri;
215 return dataObsMgrInnerExt_->HandleRegisterObserver(innerUri, dataObserver, isDescendants);
216 }
217
UnregisterObserverExt(const Uri & uri,sptr<IDataAbilityObserver> dataObserver)218 Status DataObsMgrService::UnregisterObserverExt(const Uri &uri, sptr<IDataAbilityObserver> dataObserver)
219 {
220 if (dataObserver == nullptr) {
221 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver, uri:%{public}s",
222 CommonUtils::Anonymous(uri.ToString()).c_str());
223 return DATA_OBSERVER_IS_NULL;
224 }
225
226 if (dataObsMgrInnerExt_ == nullptr) {
227 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner, uri:%{public}s",
228 CommonUtils::Anonymous(uri.ToString()).c_str());
229 return DATAOBS_SERVICE_INNER_IS_NULL;
230 }
231
232 auto innerUri = uri;
233 return dataObsMgrInnerExt_->HandleUnregisterObserver(innerUri, dataObserver);
234 }
235
UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)236 Status DataObsMgrService::UnregisterObserverExt(sptr<IDataAbilityObserver> dataObserver)
237 {
238 if (dataObserver == nullptr) {
239 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObserver");
240 return DATA_OBSERVER_IS_NULL;
241 }
242
243 if (dataObsMgrInnerExt_ == nullptr) {
244 TAG_LOGE(AAFwkTag::DBOBSMGR, "null dataObsMgrInner");
245 return DATAOBS_SERVICE_INNER_IS_NULL;
246 }
247
248 return dataObsMgrInnerExt_->HandleUnregisterObserver(dataObserver);
249 }
250
DeepCopyChangeInfo(const ChangeInfo & src,ChangeInfo & dst) const251 Status DataObsMgrService::DeepCopyChangeInfo(const ChangeInfo &src, ChangeInfo &dst) const
252 {
253 dst = src;
254 if (dst.size_ == 0) {
255 return SUCCESS;
256 }
257 dst.data_ = new (std::nothrow) uint8_t[dst.size_];
258 if (dst.data_ == nullptr) {
259 return DATAOBS_SERVICE_INNER_IS_NULL;
260 }
261
262 errno_t ret = memcpy_s(dst.data_, dst.size_, src.data_, src.size_);
263 if (ret != EOK) {
264 delete [] static_cast<uint8_t *>(dst.data_);
265 dst.data_ = nullptr;
266 return DATAOBS_SERVICE_INNER_IS_NULL;
267 }
268 return SUCCESS;
269 }
270
NotifyChangeExt(const ChangeInfo & changeInfo)271 Status DataObsMgrService::NotifyChangeExt(const ChangeInfo &changeInfo)
272 {
273 if (handler_ == nullptr) {
274 TAG_LOGE(AAFwkTag::DBOBSMGR, "null handler");
275 return DATAOBS_SERVICE_HANDLER_IS_NULL;
276 }
277
278 if (dataObsMgrInner_ == nullptr || dataObsMgrInnerExt_ == nullptr) {
279 TAG_LOGE(AAFwkTag::DBOBSMGR, "dataObsMgrInner_:%{public}d or null dataObsMgrInnerExt",
280 dataObsMgrInner_ == nullptr);
281 return DATAOBS_SERVICE_INNER_IS_NULL;
282 }
283 ChangeInfo changes;
284 Status result = DeepCopyChangeInfo(changeInfo, changes);
285 if (result != SUCCESS) {
286 TAG_LOGE(AAFwkTag::DBOBSMGR,
287 "copy data failed, changeType:%{public}ud,uris num:%{public}zu, "
288 "null data:%{public}d, size:%{public}ud",
289 changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
290 return result;
291 }
292
293 {
294 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
295 if (taskCount_ >= TASK_COUNT_MAX) {
296 TAG_LOGE(AAFwkTag::DBOBSMGR,
297 "task num maxed, changeType:%{public}ud,"
298 "uris num:%{public}zu, null data:%{public}d, size:%{public}ud",
299 changeInfo.changeType_, changeInfo.uris_.size(), changeInfo.data_ == nullptr, changeInfo.size_);
300 return DATAOBS_SERVICE_TASK_LIMMIT;
301 }
302 ++taskCount_;
303 }
304
305 handler_->SubmitTask([this, changes]() {
306 dataObsMgrInnerExt_->HandleNotifyChange(changes);
307 for (auto &uri : changes.uris_) {
308 dataObsMgrInner_->HandleNotifyChange(uri);
309 }
310 delete [] static_cast<uint8_t *>(changes.data_);
311 std::lock_guard<ffrt::mutex> lck(taskCountMutex_);
312 --taskCount_;
313 });
314 return SUCCESS;
315 }
316
GetFocusedAppInfo(int32_t & windowId,sptr<IRemoteObject> & abilityToken) const317 void DataObsMgrService::GetFocusedAppInfo(int32_t &windowId, sptr<IRemoteObject> &abilityToken) const
318 {
319 Rosen::FocusChangeInfo info;
320 #ifdef SCENE_BOARD_ENABLE
321 Rosen::WindowManagerLite::GetInstance().GetFocusWindowInfo(info);
322 #else
323 Rosen::WindowManager::GetInstance().GetFocusWindowInfo(info);
324 #endif
325 windowId = info.windowId_;
326 abilityToken = info.abilityToken_;
327 }
328
GetAbilityManagerService() const329 sptr<IRemoteObject> DataObsMgrService::GetAbilityManagerService() const
330 {
331 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
332 if (systemAbilityManager == nullptr) {
333 TAG_LOGE(AAFwkTag::DBOBSMGR, "Failed to get ability manager.");
334 return nullptr;
335 }
336 sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(ABILITY_MGR_SERVICE_ID);
337 if (!remoteObject) {
338 TAG_LOGE(AAFwkTag::DBOBSMGR, "Failed to get ability manager service.");
339 return nullptr;
340 }
341 return remoteObject;
342 }
343
NotifyProcessObserver(const std::string & key,const sptr<IRemoteObject> & observer)344 Status DataObsMgrService::NotifyProcessObserver(const std::string &key, const sptr<IRemoteObject> &observer)
345 {
346 auto remote = GetAbilityManagerService();
347 if (remote == nullptr) {
348 TAG_LOGE(AAFwkTag::DBOBSMGR, "Get ability manager failed.");
349 return DATAOBS_PROXY_INNER_ERR;
350 }
351 auto abilityManager = iface_cast<IAbilityManager>(remote);
352
353 int32_t windowId;
354 sptr<IRemoteObject> callerToken;
355 GetFocusedAppInfo(windowId, callerToken);
356
357 Want want;
358 want.SetElementName(DIALOG_APP, PROGRESS_ABILITY);
359 want.SetAction(PROGRESS_ABILITY);
360 want.SetParam("promptText", std::string(PROMPT_TEXT));
361 want.SetParam("remoteDeviceName", std::string());
362 want.SetParam("progressKey", key);
363 want.SetParam("isRemote", false);
364 want.SetParam("windowId", windowId);
365 want.SetParam("ipcCallback", observer);
366 if (callerToken != nullptr) {
367 want.SetParam("tokenKey", callerToken);
368 } else {
369 TAG_LOGW(AAFwkTag::DBOBSMGR, "CallerToken is nullptr.");
370 }
371
372 int32_t status = IN_PROCESS_CALL(abilityManager->StartAbility(want));
373 if (status != SUCCESS) {
374 TAG_LOGE(AAFwkTag::DBOBSMGR, "ShowProgress fail, status:%{public}d", status);
375 return DATAOBS_PROXY_INNER_ERR;
376 }
377 return SUCCESS;
378 }
379
Dump(int fd,const std::vector<std::u16string> & args)380 int DataObsMgrService::Dump(int fd, const std::vector<std::u16string>& args)
381 {
382 std::string result;
383 Dump(args, result);
384 int ret = dprintf(fd, "%s\n", result.c_str());
385 if (ret < 0) {
386 TAG_LOGE(AAFwkTag::DBOBSMGR, "dprintf error");
387 return DATAOBS_HIDUMP_ERROR;
388 }
389 return SUCCESS;
390 }
391
Dump(const std::vector<std::u16string> & args,std::string & result) const392 void DataObsMgrService::Dump(const std::vector<std::u16string>& args, std::string& result) const
393 {
394 auto size = args.size();
395 if (size == 0) {
396 ShowHelp(result);
397 return;
398 }
399
400 std::string optionKey = Str16ToStr8(args[0]);
401 if (optionKey != "-h") {
402 result.append("error: unkown option.\n");
403 }
404 ShowHelp(result);
405 }
406
ShowHelp(std::string & result) const407 void DataObsMgrService::ShowHelp(std::string& result) const
408 {
409 result.append("Usage:\n")
410 .append("-h ")
411 .append("help text for the tool\n");
412 }
413 } // namespace AAFwk
414 } // namespace OHOS
415