• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_idl.h"
17 
18 #include "ipc_skeleton.h"
19 #include "tokenid_kit.h"
20 #include "ui_service_hilog.h"
21 #include "ui_service_mgr_errors.h"
22 #include "ui_service_mgr_xcollie.h"
23 #include "xcollie/watchdog.h"
24 
25 namespace OHOS {
26 namespace Ace {
27 namespace {
28 constexpr int32_t UI_MGR_SERVICE_SA_ID = 7001;
29 constexpr uint32_t WATCHDOG_TIMEVAL = 5000;
30 constexpr uint32_t UI_MGR_SERVICE_TIMEOUT = 5;
31 #ifdef UI_SERVICE_WITH_IDL
32 const bool REGISTER_RESULT =
33     SystemAbility::MakeAndRegisterAbility(DelayedSingleton<UIMgrServiceIdl>::GetInstance().get());
34 #endif
35 } // namespace
36 
UIMgrServiceIdl()37 UIMgrServiceIdl::UIMgrServiceIdl()
38     : SystemAbility(UI_MGR_SERVICE_SA_ID, true), eventLoop_(nullptr), handler_(nullptr),
39       state_(UIServiceRunningState::STATE_NOT_START)
40 {
41     LOGI("Ace UIServcieIdl is created");
42 }
43 
~UIMgrServiceIdl()44 UIMgrServiceIdl::~UIMgrServiceIdl()
45 {
46     LOGI("Ace UIServcieIdl is destroyed");
47     std::lock_guard<std::recursive_mutex> lock(uiMutex_);
48     callbackMap_.clear();
49 }
50 
Dump(int32_t fd,const std::vector<std::u16string> & args)51 int32_t UIMgrServiceIdl::Dump(int32_t fd, const std::vector<std::u16string>& args)
52 {
53     std::lock_guard<std::recursive_mutex> lock(uiMutex_);
54     dprintf(fd, "total callbacks: %u\n", callbackMap_.size());
55     if (!callbackMap_.empty()) {
56         dprintf(fd, "callback keys: \n");
57     }
58     for (const auto& callback : callbackMap_) {
59         dprintf(fd, "  %s\n", callback.first.c_str());
60     }
61     return UI_SERVICE_NO_ERROR;
62 }
63 
OnStart()64 void UIMgrServiceIdl::OnStart()
65 {
66     if (state_ == UIServiceRunningState::STATE_RUNNING) {
67         return;
68     }
69     if (!Init()) {
70         return;
71     }
72     state_ = UIServiceRunningState::STATE_RUNNING;
73     eventLoop_->Run();
74 
75     /* Publish service maybe failed, so we need call this function at the last,
76      * so it can't affect the TDD test program */
77     bool ret = Publish(DelayedSingleton<UIMgrServiceIdl>::GetInstance().get());
78     if (!ret) {
79         return;
80     }
81     LOGI("Ace UImanager service OnStart");
82 }
83 
Init()84 bool UIMgrServiceIdl::Init()
85 {
86     eventLoop_ = AppExecFwk::EventRunner::Create("UIMgrServiceIdl");
87     if (eventLoop_ == nullptr) {
88         return false;
89     }
90 
91     handler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
92     if (handler_ == nullptr) {
93         return false;
94     }
95 
96     int32_t ret = HiviewDFX::Watchdog::GetInstance().AddThread("UIMgrServiceIdl", handler_, WATCHDOG_TIMEVAL);
97     if (ret != 0) {
98         LOGW("Add watchdog thread failed");
99     }
100 
101     LOGI("Ace UIservice init success");
102     return true;
103 }
104 
OnStop()105 void UIMgrServiceIdl::OnStop()
106 {
107     eventLoop_->Stop();
108     eventLoop_.reset();
109     handler_.reset();
110     state_ = UIServiceRunningState::STATE_NOT_START;
111     LOGI("Ace UImanager service stop");
112 }
113 
QueryServiceState() const114 UIServiceRunningState UIMgrServiceIdl::QueryServiceState() const
115 {
116     return state_;
117 }
118 
RegisterCallBack(const AAFwk::Want & want,const sptr<IUIServiceNew> & uiService)119 int32_t UIMgrServiceIdl::RegisterCallBack(const AAFwk::Want& want, const sptr<IUIServiceNew>& uiService)
120 {
121     if (uiService == nullptr) {
122         return UI_SERVICE_IS_NULL;
123     }
124     if (handler_ == nullptr) {
125         return UI_SERVICE_HANDLER_IS_NULL;
126     }
127     std::function<void()> registerFunc =
128         std::bind(&UIMgrServiceIdl::HandleRegister, shared_from_this(), want, uiService);
129     bool ret = handler_->PostTask(registerFunc);
130     if (!ret) {
131         return UI_SERVICE_POST_TASK_FAILED;
132     }
133     LOGI("UIServices register CallBack success");
134     return NO_ERROR;
135 }
136 
UnregisterCallBack(const AAFwk::Want & want)137 int32_t UIMgrServiceIdl::UnregisterCallBack(const AAFwk::Want& want)
138 {
139     if (handler_ == nullptr) {
140         return UI_SERVICE_HANDLER_IS_NULL;
141     }
142     std::function<void()> unregisterFunc = std::bind(&UIMgrServiceIdl::HandleUnregister, shared_from_this(), want);
143     bool ret = handler_->PostTask(unregisterFunc);
144     if (!ret) {
145         return UI_SERVICE_POST_TASK_FAILED;
146     }
147     LOGI("UIServices unregister CallBack success");
148     return NO_ERROR;
149 }
150 
Push(const AAFwk::Want & want,const std::string & name,const std::string & jsonPath,const std::string & data,const std::string & extraData)151 int32_t UIMgrServiceIdl::Push(const AAFwk::Want& want, const std::string& name, const std::string& jsonPath,
152     const std::string& data, const std::string& extraData)
153 {
154     std::map<std::string, sptr<IUIServiceNew>> callbackMap;
155     {
156         std::lock_guard<std::recursive_mutex> lock(uiMutex_);
157         callbackMap = std::map<std::string, sptr<IUIServiceNew>>(callbackMap_);
158     }
159     for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
160         sptr<IUIServiceNew> uiService = iter->second;
161         if (uiService == nullptr) {
162             return UI_SERVICE_IS_NULL;
163         }
164         uiService->OnPushCallBack(want, name, jsonPath, data, extraData);
165     }
166     return NO_ERROR;
167 }
168 
Request(const AAFwk::Want & want,const std::string & name,const std::string & data)169 int32_t UIMgrServiceIdl::Request(const AAFwk::Want& want, const std::string& name, const std::string& data)
170 {
171     std::map<std::string, sptr<IUIServiceNew>> callbackMap;
172     {
173         std::lock_guard<std::recursive_mutex> lock(uiMutex_);
174         callbackMap = std::map<std::string, sptr<IUIServiceNew>>(callbackMap_);
175     }
176     for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
177         sptr<IUIServiceNew> uiService = iter->second;
178         if (uiService == nullptr) {
179             return UI_SERVICE_IS_NULL;
180         }
181         uiService->OnRequestCallBack(want, name, data);
182     }
183     return NO_ERROR;
184 }
185 
ReturnRequest(const AAFwk::Want & want,const std::string & source,const std::string & data,const std::string & extraData)186 int32_t UIMgrServiceIdl::ReturnRequest(
187     const AAFwk::Want& want, const std::string& source, const std::string& data, const std::string& extraData)
188 {
189     std::map<std::string, sptr<IUIServiceNew>> callbackMap;
190     {
191         std::lock_guard<std::recursive_mutex> lock(uiMutex_);
192         callbackMap = std::map<std::string, sptr<IUIServiceNew>>(callbackMap_);
193     }
194     for (auto iter = callbackMap.begin(); iter != callbackMap.end(); ++iter) {
195         sptr<IUIServiceNew> uiService = iter->second;
196         if (uiService == nullptr) {
197             return UI_SERVICE_IS_NULL;
198         }
199         uiService->OnReturnRequest(want, source, data, extraData);
200     }
201     return NO_ERROR;
202 }
203 
HandleRegister(const AAFwk::Want & want,const sptr<IUIServiceNew> & uiService)204 int32_t UIMgrServiceIdl::HandleRegister(const AAFwk::Want& want, const sptr<IUIServiceNew>& uiService)
205 {
206     std::lock_guard<std::recursive_mutex> lock(uiMutex_);
207     std::string keyStr = GetCallBackKeyStr(want);
208     bool exist = CheckCallBackFromMap(keyStr);
209     if (exist) {
210         callbackMap_.erase(keyStr);
211     }
212     callbackMap_.emplace(keyStr, uiService);
213     return NO_ERROR;
214 }
215 
HandleUnregister(const AAFwk::Want & want)216 int32_t UIMgrServiceIdl::HandleUnregister(const AAFwk::Want& want)
217 {
218     std::lock_guard<std::recursive_mutex> lock(uiMutex_);
219     std::string keyStr = GetCallBackKeyStr(want);
220     bool exist = CheckCallBackFromMap(keyStr);
221     if (!exist) {
222         return NO_CALLBACK_FOR_KEY;
223     }
224     callbackMap_.erase(keyStr);
225     return NO_ERROR;
226 }
227 
GetCallBackKeyStr(const AAFwk::Want & want)228 std::string UIMgrServiceIdl::GetCallBackKeyStr(const AAFwk::Want& want)
229 {
230     AppExecFwk::ElementName element = want.GetElement();
231     std::string bundleName = element.GetBundleName();
232     std::string keyStr = bundleName;
233     return keyStr;
234 }
235 
CheckCallBackFromMap(const std::string & key)236 bool UIMgrServiceIdl::CheckCallBackFromMap(const std::string& key)
237 {
238     std::lock_guard<std::recursive_mutex> lock(uiMutex_);
239     auto it = callbackMap_.find(key);
240     if (it == callbackMap_.end()) {
241         return false;
242     }
243     return true;
244 }
245 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)246 int32_t UIMgrServiceIdl::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply,
247     MessageOption& option)
248 {
249     UIServiceMgrXCollie uiServiceMgrXCollie(IpcCodeToString(code), UI_MGR_SERVICE_TIMEOUT);
250     if (!IsSystemApp()) {
251         return ERR_PERMISSION_DENIED;
252     }
253     auto result = UIServiceMgrNewStub::OnRemoteRequest(code, data, reply, option);
254     LOGI("Ace UIServcieIdl OnRemoteRequest res = %{public}d", result);
255     return result;
256 }
257 
IpcCodeToString(uint32_t code)258 const char* UIMgrServiceIdl::IpcCodeToString(uint32_t code)
259 {
260     switch (static_cast<IUIServiceMgrNewIpcCode>(code)) {
261         case IUIServiceMgrNewIpcCode::COMMAND_REGISTER_CALL_BACK:
262             return "UISERVICE_REGISTER_CALLBACK";
263         case IUIServiceMgrNewIpcCode::COMMAND_UNREGISTER_CALL_BACK:
264             return "UISERVICE_UNREGISTER_CALLBACK";
265         case IUIServiceMgrNewIpcCode::COMMAND_PUSH:
266             return "UISERVICE_PUSH";
267         case IUIServiceMgrNewIpcCode::COMMAND_REQUEST:
268             return "UISERVICE_REQUEST";
269         case IUIServiceMgrNewIpcCode::COMMAND_RETURN_REQUEST:
270             return "UISERVICE_RETURN_REQUEST";
271         default:
272             return "UISERVICE_UNKNOWN";
273     }
274 }
275 
IsSystemApp()276 bool UIMgrServiceIdl::IsSystemApp()
277 {
278     uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
279     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIDEx);
280 }
281 
282 } // namespace Ace
283 } // namespace OHOS
284