1 /*
2 * Copyright (c) 2021-2022 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 "ui_mgr_service.h"
17
18 #include <atomic>
19
20 #include "if_system_ability_manager.h"
21 #include "ipc_skeleton.h"
22 #include "string_ex.h"
23 #include "system_ability_definition.h"
24 #include "ui_service_mgr_errors.h"
25 #include "xcollie/watchdog.h"
26
27 #include "ui_service_hilog.h"
28 namespace OHOS {
29 namespace Ace {
30 namespace {
31 constexpr int32_t UI_MGR_SERVICE_SA_ID = 7001;
32 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
33 const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(DelayedSingleton<UIMgrService>::GetInstance().get());
34 } // namespace
35
36 // UiservicePluginDialog UIMgrService::dialogPlugin_;
37
UIMgrService()38 UIMgrService::UIMgrService()
39 : SystemAbility(UI_MGR_SERVICE_SA_ID, true), eventLoop_(nullptr), handler_(nullptr),
40 state_(UIServiceRunningState::STATE_NOT_START)
41 {}
42
~UIMgrService()43 UIMgrService::~UIMgrService()
44 {
45 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
46 callbackMap_.clear();
47 }
48
Dump(int32_t fd,const std::vector<std::u16string> & args)49 int32_t UIMgrService::Dump(int32_t fd, const std::vector<std::u16string>& args)
50 {
51 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
52 dprintf(fd, "total callbacks: %u\n", callbackMap_.size());
53 if (!callbackMap_.empty()) {
54 dprintf(fd, "callback keys: \n");
55 }
56 for (const auto& callback : callbackMap_) {
57 dprintf(fd, " %s\n", callback.first.c_str());
58 }
59 return UI_SERVICE_NO_ERROR;
60 }
61
OnStart()62 void UIMgrService::OnStart()
63 {
64 if (state_ == UIServiceRunningState::STATE_RUNNING) {
65 return;
66 }
67 if (!Init()) {
68 return;
69 }
70 state_ = UIServiceRunningState::STATE_RUNNING;
71 eventLoop_->Run();
72
73 /* Publish service maybe failed, so we need call this function at the last,
74 * so it can't affect the TDD test program */
75 bool ret = Publish(DelayedSingleton<UIMgrService>::GetInstance().get());
76 if (!ret) {
77 return;
78 }
79 LOGI("Ace UImanager service OnStart");
80 }
81
Init()82 bool UIMgrService::Init()
83 {
84 eventLoop_ = AppExecFwk::EventRunner::Create("UIMgrService");
85 if (eventLoop_ == nullptr) {
86 return false;
87 }
88
89 handler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
90 if (handler_ == nullptr) {
91 return false;
92 }
93
94 int32_t ret = HiviewDFX::Watchdog::GetInstance().AddThread("UIMgrService", handler_, WATCHDOG_TIMEVAL);
95 if (ret != 0) {
96 LOGW("Add watchdog thread failed");
97 }
98
99 LOGI("Ace UIservice init success");
100 return true;
101 }
102
OnStop()103 void UIMgrService::OnStop()
104 {
105 eventLoop_->Stop();
106 eventLoop_.reset();
107 handler_.reset();
108 state_ = UIServiceRunningState::STATE_NOT_START;
109 LOGI("Ace UImanager service stop");
110 }
111
QueryServiceState() const112 UIServiceRunningState UIMgrService::QueryServiceState() const
113 {
114 return state_;
115 }
116
RegisterCallBack(const AAFwk::Want & want,const sptr<IUIService> & uiService)117 int32_t UIMgrService::RegisterCallBack(const AAFwk::Want& want, const sptr<IUIService>& uiService)
118 {
119 if (uiService == nullptr) {
120 return UI_SERVICE_IS_NULL;
121 }
122 if (handler_ == nullptr) {
123 return UI_SERVICE_HANDLER_IS_NULL;
124 }
125 std::function<void()> registerFunc = std::bind(&UIMgrService::HandleRegister, shared_from_this(), want, uiService);
126 bool ret = handler_->PostTask(registerFunc);
127 if (!ret) {
128 return UI_SERVICE_POST_TASK_FAILED;
129 }
130 LOGI("UIServices register CallBack success");
131 return NO_ERROR;
132 }
133
UnregisterCallBack(const AAFwk::Want & want)134 int32_t UIMgrService::UnregisterCallBack(const AAFwk::Want& want)
135 {
136 if (handler_ == nullptr) {
137 return UI_SERVICE_HANDLER_IS_NULL;
138 }
139 std::function<void()> unregisterFunc = std::bind(&UIMgrService::HandleUnregister, shared_from_this(), want);
140 bool ret = handler_->PostTask(unregisterFunc);
141 if (!ret) {
142 return UI_SERVICE_POST_TASK_FAILED;
143 }
144 LOGI("UIServices unregister CallBack success");
145 return NO_ERROR;
146 }
147
Push(const AAFwk::Want & want,const std::string & name,const std::string & jsonPath,const std::string & data,const std::string & extraData)148 int32_t UIMgrService::Push(const AAFwk::Want& want, const std::string& name, const std::string& jsonPath,
149 const std::string& data, const std::string& extraData)
150 {
151 std::map<std::string, sptr<IUIService>> callbackMap;
152 {
153 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
154 callbackMap = std::map<std::string, sptr<IUIService>>(callbackMap_);
155 }
156 for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
157 sptr<IUIService> uiService = iter->second;
158 if (uiService == nullptr) {
159 return UI_SERVICE_IS_NULL;
160 }
161 uiService->OnPushCallBack(want, name, jsonPath, data, extraData);
162 }
163 return NO_ERROR;
164 }
165
Request(const AAFwk::Want & want,const std::string & name,const std::string & data)166 int32_t UIMgrService::Request(const AAFwk::Want& want, const std::string& name, const std::string& data)
167 {
168 std::map<std::string, sptr<IUIService>> callbackMap;
169 {
170 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
171 callbackMap = std::map<std::string, sptr<IUIService>>(callbackMap_);
172 }
173 for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
174 sptr<IUIService> uiService = iter->second;
175 if (uiService == nullptr) {
176 return UI_SERVICE_IS_NULL;
177 }
178 uiService->OnRequestCallBack(want, name, data);
179 }
180 return NO_ERROR;
181 }
182
ReturnRequest(const AAFwk::Want & want,const std::string & source,const std::string & data,const std::string & extraData)183 int32_t UIMgrService::ReturnRequest(
184 const AAFwk::Want& want, const std::string& source, const std::string& data, const std::string& extraData)
185 {
186 std::map<std::string, sptr<IUIService>> callbackMap;
187 {
188 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
189 callbackMap = std::map<std::string, sptr<IUIService>>(callbackMap_);
190 }
191 for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
192 sptr<IUIService> uiService = iter->second;
193 if (uiService == nullptr) {
194 return UI_SERVICE_IS_NULL;
195 }
196 uiService->OnReturnRequest(want, source, data, extraData);
197 }
198 return NO_ERROR;
199 }
200
HandleRegister(const AAFwk::Want & want,const sptr<IUIService> & uiService)201 int32_t UIMgrService::HandleRegister(const AAFwk::Want& want, const sptr<IUIService>& uiService)
202 {
203 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
204 std::string keyStr = GetCallBackKeyStr(want);
205 bool exist = CheckCallBackFromMap(keyStr);
206 if (exist) {
207 callbackMap_.erase(keyStr);
208 }
209 callbackMap_.emplace(keyStr, uiService);
210 return NO_ERROR;
211 }
212
HandleUnregister(const AAFwk::Want & want)213 int32_t UIMgrService::HandleUnregister(const AAFwk::Want& want)
214 {
215 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
216 std::string keyStr = GetCallBackKeyStr(want);
217 bool exist = CheckCallBackFromMap(keyStr);
218 if (!exist) {
219 return NO_CALLBACK_FOR_KEY;
220 }
221 callbackMap_.erase(keyStr);
222 return NO_ERROR;
223 }
224
GetCallBackKeyStr(const AAFwk::Want & want)225 std::string UIMgrService::GetCallBackKeyStr(const AAFwk::Want& want)
226 {
227 AppExecFwk::ElementName element = want.GetElement();
228 std::string bundleName = element.GetBundleName();
229 std::string keyStr = bundleName;
230 return keyStr;
231 }
232
CheckCallBackFromMap(const std::string & key)233 bool UIMgrService::CheckCallBackFromMap(const std::string& key)
234 {
235 std::lock_guard<std::recursive_mutex> lock(uiMutex_);
236 auto it = callbackMap_.find(key);
237 if (it == callbackMap_.end()) {
238 return false;
239 }
240 return true;
241 }
242 } // namespace Ace
243 } // namespace OHOS
244