1 /*
2 * Copyright (c) 2024-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 "dm_dialog_manager.h"
17
18 #include <pthread.h>
19 #include <thread>
20
21 #include "ability_manager_client.h"
22 #include "auth_message_processor.h"
23 #include "dm_anonymous.h"
24 #include "dm_log.h"
25 #include "dm_crypto.h"
26 #include "json_object.h"
27 #include "parameter.h"
28 #include "dm_single_instance.h"
29 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
30 #include "ffrt.h"
31 #endif
32
33 namespace OHOS {
34 namespace DistributedHardware {
35 namespace {
36 constexpr int32_t INVALID_USERID = -1;
37 constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 3;
38 constexpr int32_t WINDOW_LEVEL_UPPER = 2;
39 constexpr int32_t WINDOW_LEVEL_DEFAULT = 1;
40 constexpr const char* CONNECT_PIN_DIALOG = "pinDialog";
41 constexpr const char* DM_UI_BUNDLE_NAME = "com.ohos.devicemanagerui";
42 constexpr const char* CONFIRM_ABILITY_NAME = "com.ohos.devicemanagerui.ConfirmUIExtAbility";
43 constexpr const char* PIN_ABILITY_NAME = "com.ohos.devicemanagerui.PincodeUIExtAbility";
44 constexpr const char* INPUT_ABILITY_NAME = "com.ohos.devicemanagerui.InputUIExtAbility";
45 constexpr uint32_t CLOSE_DIALOG_CMD_CODE = 3;
46 constexpr uint32_t SHOW_DIALOG_CMD_CODE = 1;
47 }
48 DM_IMPLEMENT_SINGLE_INSTANCE(DmDialogManager);
49
DmDialogManager()50 DmDialogManager::DmDialogManager()
51 {
52 LOGI("DmDialogManager constructor");
53 }
54
~DmDialogManager()55 DmDialogManager::~DmDialogManager()
56 {
57 LOGI("DmDialogManager destructor");
58 }
59
ShowConfirmDialog(const std::string param)60 void DmDialogManager::ShowConfirmDialog(const std::string param)
61 {
62 std::string deviceName = "";
63 std::string appOperationStr = "";
64 std::string customDescriptionStr = "";
65 std::string hostPkgLabel = "";
66 int32_t deviceType = -1;
67 {
68 std::unique_lock<std::mutex> lock(mutex_);
69 JsonObject jsonObject(param);
70 if (!jsonObject.IsDiscarded()) {
71 if (IsString(jsonObject, TAG_REQUESTER)) {
72 deviceName = jsonObject[TAG_REQUESTER].Get<std::string>();
73 }
74 if (IsString(jsonObject, TAG_APP_OPERATION)) {
75 appOperationStr = jsonObject[TAG_APP_OPERATION].Get<std::string>();
76 }
77 if (IsString(jsonObject, TAG_CUSTOM_DESCRIPTION)) {
78 customDescriptionStr = jsonObject[TAG_CUSTOM_DESCRIPTION].Get<std::string>();
79 }
80 if (IsInt32(jsonObject, TAG_LOCAL_DEVICE_TYPE)) {
81 deviceType = jsonObject[TAG_LOCAL_DEVICE_TYPE].Get<std::int32_t>();
82 }
83 if (IsString(jsonObject, TAG_HOST_PKGLABEL)) {
84 hostPkgLabel = jsonObject[TAG_HOST_PKGLABEL].Get<std::string>();
85 }
86 if (IsBool(jsonObject, PARAM_KEY_IS_PROXY_BIND)) {
87 isProxyBind_ = jsonObject[PARAM_KEY_IS_PROXY_BIND].Get<bool>();
88 }
89 if (IsString(jsonObject, APP_USER_DATA)) {
90 appUserData_ = jsonObject[APP_USER_DATA].Get<std::string>();
91 }
92 if (IsString(jsonObject, TITLE)) {
93 title_ = jsonObject[TITLE].Get<std::string>();
94 }
95 }
96
97 bundleName_ = DM_UI_BUNDLE_NAME;
98 abilityName_ = CONFIRM_ABILITY_NAME;
99 deviceName_ = deviceName;
100 appOperationStr_ = appOperationStr;
101 customDescriptionStr_ = customDescriptionStr;
102 deviceType_ = deviceType;
103 hostPkgLabel_ = hostPkgLabel;
104 }
105 ConnectExtension();
106 }
107
ShowPinDialog(const std::string param)108 void DmDialogManager::ShowPinDialog(const std::string param)
109 {
110 LOGI("pinCode: %{public}s", GetAnonyString(param).c_str());
111 {
112 std::lock_guard<std::mutex> lock(mutex_);
113 bundleName_ = DM_UI_BUNDLE_NAME;
114 abilityName_ = PIN_ABILITY_NAME;
115 pinCode_ = param;
116 }
117 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
118 ffrt::submit([]() { DmDialogManager::GetInstance().ConnectExtension(); });
119 #else
120 std::thread pinDilog([]() { DmDialogManager::GetInstance().ConnectExtension(); });
121 int32_t ret = pthread_setname_np(pinDilog.native_handle(), CONNECT_PIN_DIALOG.c_str());
122 if (ret != DM_OK) {
123 LOGE("pinDilog setname failed.");
124 }
125 pinDilog.detach();
126 #endif
127 }
128
ShowInputDialog(const std::string param)129 void DmDialogManager::ShowInputDialog(const std::string param)
130 {
131 {
132 std::lock_guard<std::mutex> lock(mutex_);
133 targetDeviceName_ = param;
134 bundleName_ = DM_UI_BUNDLE_NAME;
135 abilityName_ = INPUT_ABILITY_NAME;
136 }
137 ConnectExtension();
138 }
139
CloseDialog()140 void DmDialogManager::CloseDialog()
141 {
142 LOGI("In");
143 std::unique_lock<std::mutex> lock(mutex_);
144 if (g_remoteObject == nullptr) {
145 LOGW("g_remoteObject is nullptr");
146 isCloseDialog_.store(true);
147 return;
148 }
149 MessageParcel data;
150 MessageParcel reply;
151 MessageOption option;
152 int32_t ret = g_remoteObject->SendRequest(CLOSE_DIALOG_CMD_CODE, data, reply, option);
153 if (ret != ERR_OK) {
154 LOGE("close dm dialog is failed: %{public}d", ret);
155 return;
156 }
157 }
158
ConnectExtension()159 void DmDialogManager::ConnectExtension()
160 {
161 LOGI("DmDialogManager::ConnectExtension start.");
162 isCloseDialog_.store(false);
163 if (isConnectSystemUI_.load() && dialogConnectionCallback_ != nullptr && g_remoteObject != nullptr) {
164 AppExecFwk::ElementName element;
165 OnAbilityConnectDone(element, g_remoteObject, INVALID_USERID);
166 LOGI("DmDialogManager::ConnectExtension dialog has been show.");
167 return;
168 }
169 AAFwk::Want want;
170 std::string bundleName = "com.ohos.sceneboard";
171 std::string abilityName = "com.ohos.sceneboard.systemdialog";
172 want.SetElementName(bundleName, abilityName);
173 auto abilityManager = AAFwk::AbilityManagerClient::GetInstance();
174 if (abilityManager == nullptr) {
175 LOGE("AbilityManagerClient is nullptr");
176 return;
177 }
178
179 std::lock_guard<std::mutex> lock(mutex_);
180 if (dialogConnectionCallback_ == nullptr) {
181 dialogConnectionCallback_ = new (std::nothrow) DialogAbilityConnection();
182 }
183 if (dialogConnectionCallback_ == nullptr) {
184 LOGE("create dialogConnectionCallback_ failed.");
185 return;
186 }
187 LOGI("DmDialogManager::ConnectExtension abilityManager ConnectAbility begin.");
188 auto ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
189 if (ret != ERR_OK) {
190 LOGE("ConnectExtensionAbility sceneboard failed.");
191 bundleName = "com.ohos.systemui";
192 abilityName = "com.ohos.systemui.dialog";
193 want.SetElementName(bundleName, abilityName);
194 ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
195 if (ret != ERR_OK) {
196 LOGE("ConnectExtensionAbility systemui failed again.");
197 }
198 }
199 }
200
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)201 void DmDialogManager::OnAbilityConnectDone(
202 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
203 {
204 LOGI("OnAbilityConnectDone");
205 std::unique_lock<std::mutex> lock(mutex_);
206 if (remoteObject == nullptr) {
207 LOGE("remoteObject is nullptr");
208 return;
209 }
210 if (g_remoteObject == nullptr) {
211 g_remoteObject = remoteObject;
212 }
213 isConnectSystemUI_.store(true);
214 if (isCloseDialog_.load()) {
215 LOGW("isCloseDialog_ is true");
216 isCloseDialog_.store(false);
217 return;
218 }
219 SendMsgRequest(remoteObject);
220 }
221
SendMsgRequest(const sptr<IRemoteObject> & remoteObject)222 void DmDialogManager::SendMsgRequest(const sptr<IRemoteObject>& remoteObject)
223 {
224 MessageParcel data;
225 MessageParcel reply;
226 MessageOption option;
227 data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
228 data.WriteString16(u"bundleName");
229 data.WriteString16(Str8ToStr16(bundleName_));
230 data.WriteString16(u"abilityName");
231 data.WriteString16(Str8ToStr16(abilityName_));
232 data.WriteString16(u"parameters");
233 JsonObject param;
234 param["ability.want.params.uiExtensionType"] = "sysDialog/common";
235 param["sysDialogZOrder"] = WINDOW_LEVEL_DEFAULT;
236 if (abilityName_ == INPUT_ABILITY_NAME) {
237 param["sysDialogZOrder"] = WINDOW_LEVEL_UPPER;
238 }
239 param["isProxyBind"] = isProxyBind_;
240 param["appUserData"] = appUserData_;
241 param["title"] = title_;
242 std::string pinCodeHash = GetAnonyString(Crypto::Sha256(pinCode_));
243 LOGI("OnAbilityConnectDone pinCodeHash: %{public}s", pinCodeHash.c_str());
244 param["pinCode"] = pinCode_;
245 param["deviceName"] = deviceName_;
246 param["appOperationStr"] = appOperationStr_;
247 param["customDescriptionStr"] = customDescriptionStr_;
248 param["deviceType"] = deviceType_;
249 param[TAG_TARGET_DEVICE_NAME] = targetDeviceName_;
250 param[TAG_HOST_PKGLABEL] = hostPkgLabel_;
251 param["disableUpGesture"] = 1;
252 std::string paramStr = param.Dump();
253 data.WriteString16(Str8ToStr16(paramStr));
254 LOGI("show dm dialog is begin");
255 int32_t ret = remoteObject->SendRequest(SHOW_DIALOG_CMD_CODE, data, reply, option);
256 if (ret != ERR_OK) {
257 LOGE("show dm dialog is failed: %{public}d", ret);
258 return;
259 }
260 LOGI("show dm dialog is success");
261 }
262
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)263 void DmDialogManager::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
264 {
265 LOGI("OnAbilityDisconnectDone");
266 std::lock_guard<std::mutex> lock(mutex_);
267 g_remoteObject = nullptr;
268 isConnectSystemUI_.store(false);
269 isCloseDialog_.store(false);
270 }
271
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)272 void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone(
273 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
274 {
275 DmDialogManager::GetInstance().OnAbilityConnectDone(element, remoteObject, resultCode);
276 }
277
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)278 void DmDialogManager::DialogAbilityConnection::OnAbilityDisconnectDone(
279 const AppExecFwk::ElementName& element, int resultCode)
280 {
281 DmDialogManager::GetInstance().OnAbilityDisconnectDone(element, resultCode);
282 }
283 }
284 }