• 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 "ui_service_mgr_client.h"
17 
18 #include "dialog_callback_stub.h"
19 #include "hilog_wrapper.h"
20 #include "if_system_ability_manager.h"
21 #include "ipc_skeleton.h"
22 #include "iservice_registry.h"
23 #include "string_ex.h"
24 #include "system_ability_definition.h"
25 
26 // external dependence
27 #include "ability_manager_client.h"
28 #include "display_manager.h"
29 
30 namespace OHOS {
31 namespace Ace {
32 constexpr int UI_MGR_SERVICE_SA_ID = 7001;
33 constexpr int UI_DIALOG_PICKER_WIDTH = 519 * 2; // 519 vp
34 constexpr int UI_DIALOG_PICKER_HEIGHT = 256 * 2; // 256 vp
35 constexpr int UI_DIALOG_PICKER_WIDTH_NARROW = 360 * 2; // 360 vp
36 constexpr int UI_DIALOG_PICKER_HEIGHT_NARROW = 347 * 2; // 347 vp
37 constexpr int UI_DEFAULT_WIDTH = 2560;
38 constexpr int UI_DEFAULT_HEIGHT = 1600;
39 constexpr int UI_DEFAULT_BUTTOM_CLIP = 50 * 2; // 48vp
40 constexpr int UI_WIDTH_780DP = 780 * 2; // 780vp
41 constexpr int UI_HALF = 2;
42 std::shared_ptr<UIServiceMgrClient> UIServiceMgrClient::instance_ = nullptr;
43 std::mutex UIServiceMgrClient::mutex_;
44 
GetInstance()45 std::shared_ptr<UIServiceMgrClient> UIServiceMgrClient::GetInstance()
46 {
47     if (instance_ == nullptr) {
48         std::lock_guard<std::mutex> lock_l(mutex_);
49         if (instance_ == nullptr) {
50             instance_ = std::make_shared<UIServiceMgrClient>();
51         }
52     }
53     return instance_;
54 }
55 
UIServiceMgrClient()56 UIServiceMgrClient::UIServiceMgrClient()
57 {}
58 
~UIServiceMgrClient()59 UIServiceMgrClient::~UIServiceMgrClient()
60 {}
61 
RegisterCallBack(const AAFwk::Want & want,const sptr<IUIService> & uiService)62 ErrCode UIServiceMgrClient::RegisterCallBack(const AAFwk::Want& want, const sptr<IUIService>& uiService)
63 {
64     if (remoteObject_ == nullptr) {
65         ErrCode err = Connect();
66         if (err != ERR_OK) {
67             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
68             return UI_SERVICE_NOT_CONNECTED;
69         }
70     }
71     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
72     return doms->RegisterCallBack(want, uiService);
73 }
74 
UnregisterCallBack(const AAFwk::Want & want)75 ErrCode UIServiceMgrClient::UnregisterCallBack(const AAFwk::Want& want)
76 {
77     if (remoteObject_ == nullptr) {
78         ErrCode err = Connect();
79         if (err != ERR_OK) {
80             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
81             return UI_SERVICE_NOT_CONNECTED;
82         }
83     }
84     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
85     return doms->UnregisterCallBack(want);
86 }
87 
Push(const AAFwk::Want & want,const std::string & name,const std::string & jsonPath,const std::string & data,const std::string & extraData)88 ErrCode UIServiceMgrClient::Push(const AAFwk::Want& want, const std::string& name, const std::string& jsonPath,
89     const std::string& data, const std::string& extraData)
90 {
91     if (remoteObject_ == nullptr) {
92         ErrCode err = Connect();
93         if (err != ERR_OK) {
94             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
95             return UI_SERVICE_NOT_CONNECTED;
96         }
97     }
98     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
99     return doms->Push(want, name, jsonPath, data, extraData);
100 }
101 
Request(const AAFwk::Want & want,const std::string & name,const std::string & data)102 ErrCode UIServiceMgrClient::Request(const AAFwk::Want& want, const std::string& name, const std::string& data)
103 {
104     if (remoteObject_ == nullptr) {
105         ErrCode err = Connect();
106         if (err != ERR_OK) {
107             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
108             return UI_SERVICE_NOT_CONNECTED;
109         }
110     }
111     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
112     return doms->Request(want, name, data);
113 }
114 
ReturnRequest(const AAFwk::Want & want,const std::string & source,const std::string & data,const std::string & extraData)115 ErrCode UIServiceMgrClient::ReturnRequest(const AAFwk::Want& want, const std::string& source,
116     const std::string& data, const std::string& extraData)
117 {
118     if (remoteObject_ == nullptr) {
119         ErrCode err = Connect();
120         if (err != ERR_OK) {
121             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
122             return UI_SERVICE_NOT_CONNECTED;
123         }
124     }
125     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
126     return doms->ReturnRequest(want, source, data, extraData);
127 }
128 
ShowDialog(const std::string & name,const std::string & params,OHOS::Rosen::WindowType windowType,int x,int y,int width,int height,DialogCallback callback,int * id)129 ErrCode UIServiceMgrClient::ShowDialog(const std::string& name,
130                                        const std::string& params,
131                                        OHOS::Rosen::WindowType windowType,
132                                        int x,
133                                        int y,
134                                        int width,
135                                        int height,
136                                        DialogCallback callback,
137                                        int* id)
138 {
139     if (remoteObject_ == nullptr) {
140         ErrCode err = Connect();
141         if (err != ERR_OK) {
142             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
143             return UI_SERVICE_NOT_CONNECTED;
144         }
145     }
146     const sptr<DialogCallbackStub> dialogCallbackStub(new (std::nothrow)DialogCallbackStub(callback));
147     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
148     if (doms == nullptr) {
149         HILOG_ERROR("doms is nullptr");
150         return UI_SERVICE_GET_PROXY_FAILED;
151     }
152     return doms->ShowDialog(name, params, windowType, x, y, width, height, dialogCallbackStub, id);
153 }
154 
CancelDialog(int32_t id)155 ErrCode UIServiceMgrClient::CancelDialog(int32_t id)
156 {
157     if (id < 0) {
158         HILOG_INFO("invalid parameter");
159         return UI_SERVICE_INVALID_PARAMETER;
160     }
161 
162     if (remoteObject_ == nullptr) {
163         ErrCode err = Connect();
164         if (err != ERR_OK) {
165             HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
166             return UI_SERVICE_NOT_CONNECTED;
167         }
168     }
169 
170     sptr<IUIServiceMgr> doms = iface_cast<IUIServiceMgr>(remoteObject_);
171     if (doms == nullptr) {
172         HILOG_ERROR("doms is nullptr");
173         return UI_SERVICE_GET_PROXY_FAILED;
174     }
175     return doms->CancelDialog(id);
176 }
177 
ShowAppPickerDialog(const AAFwk::Want & want,const std::vector<AppExecFwk::AbilityInfo> & abilityInfos,int32_t userId)178 ErrCode UIServiceMgrClient::ShowAppPickerDialog(
179     const AAFwk::Want& want, const std::vector<AppExecFwk::AbilityInfo>& abilityInfos, int32_t userId)
180 {
181     if (abilityInfos.size() == 0) {
182         HILOG_WARN("abilityInfos size is zero");
183         return UI_SERVICE_INVALID_PARAMETER;
184     }
185     int32_t offsetX = 0;
186     int32_t offsetY = 0;
187     int32_t width = UI_DIALOG_PICKER_WIDTH;
188     int32_t height = UI_DIALOG_PICKER_HEIGHT;
189     bool wideScreen = true;
190     GetDisplayPosition(offsetX, offsetY, width, height, wideScreen);
191     const std::string param = GetPickerDialogParam(want, abilityInfos, wideScreen);
192     HILOG_DEBUG("share dialog position:[%{public}d,%{public}d,%{public}d,%{public}d],str: %{public}s",
193         offsetX, offsetY, width, height, param.c_str());
194     const std::string jsBundleName = "dialog_picker_service";
195     return ShowDialog(jsBundleName, param, OHOS::Rosen::WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW, offsetX, offsetY,
196         width, height, [want, userId](int32_t id, const std::string& event, const std::string& params) mutable {
197             HILOG_DEBUG("dialog callback: event: %{public}s, params: %{public}s", event.c_str(), params.c_str());
198             if (event == "SHARE_EVENT") {
199                 std::string bundleName;
200                 std::string abilityName;
201                 auto pos = params.find(";");
202                 if (pos != std::string::npos) {
203                     bundleName = params.substr(0, pos);
204                     abilityName = params.substr(pos + 1, params.length() - (pos + 1));
205                 }
206                 AAFwk::Want shareWant = want;
207                 shareWant.SetAction("");
208                 shareWant.SetElementName(bundleName, abilityName);
209                 auto abilityClient = AAFwk::AbilityManagerClient::GetInstance();
210                 if (abilityClient != nullptr) {
211                     HILOG_INFO("dialog callback: %{public}s-%{public}s", bundleName.c_str(), abilityName.c_str());
212                     abilityClient->StartAbility(shareWant, AAFwk::DEFAULT_INVAL_VALUE, userId);
213                 }
214             }
215             Ace::UIServiceMgrClient::GetInstance()->CancelDialog(id);
216         });
217 }
218 
219 /**
220  * Connect ui_service manager service.
221  *
222  * @return Returns ERR_OK on success, others on failure.
223  */
Connect()224 ErrCode UIServiceMgrClient::Connect()
225 {
226     std::lock_guard<std::mutex> lock(mutex_);
227     if (remoteObject_ != nullptr) {
228         return ERR_OK;
229     }
230     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
231     if (systemManager == nullptr) {
232         HILOG_ERROR("%{private}s:fail to get Registry", __func__);
233         return GET_UI_SERVICE_FAILED;
234     }
235     remoteObject_ = systemManager->GetSystemAbility(UI_MGR_SERVICE_SA_ID);
236     if (remoteObject_ == nullptr) {
237         HILOG_ERROR("%{private}s:fail to connect UIMgrService", __func__);
238         return GET_UI_SERVICE_FAILED;
239     }
240     HILOG_DEBUG("connect UIMgrService success");
241     return ERR_OK;
242 }
243 
GetPickerDialogParam(const AAFwk::Want & want,const std::vector<AppExecFwk::AbilityInfo> & abilityInfos,bool wideScreen) const244 const std::string UIServiceMgrClient::GetPickerDialogParam(
245     const AAFwk::Want& want, const std::vector<AppExecFwk::AbilityInfo>& abilityInfos, bool wideScreen) const
246 {
247     auto type = want.GetStringParam("ability.picker.type");
248     auto text = want.GetStringParam("ability.picker.text");
249     auto uri = want.GetStringParam("ability.picker.uri");
250     auto fileNames = want.GetStringArrayParam("ability.picker.fileNames");
251     auto fileSizes = want.GetIntArrayParam("ability.picker.fileSizes");
252 
253     std::string param = "{"; // json head
254     if (!wideScreen) {
255         param += "\"deviceType\": \"phone\",";
256     }
257     param += "\"previewCard\": { \"type\": \"";
258     param += type;
259     param += "\", \"icon\": \"";
260     param += "";
261     param += "\", \"mainText\": \"";
262     param += text;
263     param += "\", \"subText\": \"";
264     param += uri;
265     param += "\", \"fileList\": [";
266     for (int i = 0; i < (int)fileNames.size() && i < (int)fileSizes.size(); i++) {
267         param += "{";
268         param += "\"name\": \"";
269         param += fileNames[i];
270         param += "\", \"size\": ";
271         param += std::to_string(fileSizes[i]);
272         param += "}";
273         if (i != (int)fileNames.size() - 1 && i != (int)fileSizes.size() - 1) {
274             param += ",";
275         }
276     }
277     param += "]},";
278     param += "\"hapList\": [";
279     for (int i = 0; i < (int)abilityInfos.size(); i++) {
280         const auto& abilityInfo = abilityInfos[i];
281         param += "{ \"name\": \"";
282         param += std::to_string(abilityInfo.labelId); // or string abilityInfo.label
283         param += "\", \"icon\": \"";
284         param += std::to_string(abilityInfo.iconId); // or string abilityInfo.icon
285         param += "\", \"bundle\": \"";
286         param += abilityInfo.bundleName;
287         param += "\", \"ability\": \"";
288         param += abilityInfo.name;
289         param += "\" }";
290         if (i != (int)abilityInfos.size() - 1) {
291             param += ",";
292         }
293     }
294     param += "]";
295     param += "}"; // json tail
296     return param;
297 }
298 
GetDisplayPosition(int32_t & offsetX,int32_t & offsetY,int32_t & width,int32_t & height,bool & wideScreen)299 void UIServiceMgrClient::GetDisplayPosition(
300     int32_t& offsetX, int32_t& offsetY, int32_t& width, int32_t& height, bool& wideScreen)
301 {
302     wideScreen = true;
303     auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
304     if (display == nullptr) {
305         HILOG_WARN("share dialog GetDefaultDisplay fail, try again.");
306         display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
307     }
308 
309     if (display != nullptr) {
310         if (display->GetWidth() < UI_WIDTH_780DP) {
311             HILOG_INFO("share dialog narrow.");
312             wideScreen = false;
313             width = UI_DIALOG_PICKER_WIDTH_NARROW;
314             height = UI_DIALOG_PICKER_HEIGHT_NARROW;
315         }
316         offsetX = (display->GetWidth() - width) / UI_HALF;
317         offsetY = display->GetHeight() - height - UI_DEFAULT_BUTTOM_CLIP;
318     } else {
319         HILOG_WARN("share dialog get display fail, use default wide.");
320         offsetX = (UI_DEFAULT_WIDTH - width) / UI_HALF;
321         offsetY = UI_DEFAULT_HEIGHT - height - UI_DEFAULT_BUTTOM_CLIP;
322     }
323 }
324 }  // namespace Ace
325 }  // namespace OHOS
326