• 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 
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