1 /*
2 * Copyright (c) 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 "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_constants.h"
25 #include "dm_log.h"
26 #include "nlohmann/json.hpp"
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 static constexpr int32_t INVALID_USERID = -1;
36 static constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 3;
37 static constexpr int32_t WINDOW_LEVEL_UPPER = 2;
38 static constexpr int32_t WINDOW_LEVEL_DEFAULT = 1;
39 const std::string CONNECT_PIN_DIALOG = "pinDialog";
40 const std::string DM_UI_BUNDLE_NAME = "com.ohos.devicemanagerui";
41 const std::string CONFIRM_ABILITY_NAME = "com.ohos.devicemanagerui.ConfirmUIExtAbility";
42 const std::string PIN_ABILITY_NAME = "com.ohos.devicemanagerui.PincodeUIExtAbility";
43 const std::string INPUT_ABILITY_NAME = "com.ohos.devicemanagerui.InputUIExtAbility";
44
45 std::string DmDialogManager::bundleName_ = "";
46 std::string DmDialogManager::abilityName_ = "";
47 std::string DmDialogManager::deviceName_ = "";
48 std::string DmDialogManager::appOperationStr_ = "";
49 std::string DmDialogManager::customDescriptionStr_ = "";
50 std::string DmDialogManager::targetDeviceName_ = "";
51 std::string DmDialogManager::pinCode_ = "";
52 std::string DmDialogManager::hostPkgLabel_ = "";
53 int32_t DmDialogManager::deviceType_ = -1;
54 DmDialogManager DmDialogManager::dialogMgr_;
55 sptr<OHOS::AAFwk::IAbilityConnection> DmDialogManager::dialogConnectionCallback_(
56 new (std::nothrow) DialogAbilityConnection());
57
58 std::atomic<bool> DmDialogManager::isConnectSystemUI_(false);
59 sptr<IRemoteObject> g_remoteObject = nullptr;
60
DmDialogManager()61 DmDialogManager::DmDialogManager()
62 {
63 LOGI("DmDialogManager constructor");
64 }
65
~DmDialogManager()66 DmDialogManager::~DmDialogManager()
67 {
68 LOGI("DmDialogManager destructor");
69 }
70
GetInstance()71 DmDialogManager &DmDialogManager::GetInstance()
72 {
73 return dialogMgr_;
74 }
75
ShowConfirmDialog(const std::string param)76 void DmDialogManager::ShowConfirmDialog(const std::string param)
77 {
78 std::string deviceName = "";
79 std::string appOperationStr = "";
80 std::string customDescriptionStr = "";
81 std::string hostPkgLabel = "";
82 int32_t deviceType = -1;
83 nlohmann::json jsonObject = nlohmann::json::parse(param, nullptr, false);
84 if (!jsonObject.is_discarded()) {
85 if (IsString(jsonObject, TAG_REQUESTER)) {
86 deviceName = jsonObject[TAG_REQUESTER].get<std::string>();
87 }
88 if (IsString(jsonObject, TAG_APP_OPERATION)) {
89 appOperationStr = jsonObject[TAG_APP_OPERATION].get<std::string>();
90 }
91 if (IsString(jsonObject, TAG_CUSTOM_DESCRIPTION)) {
92 customDescriptionStr = jsonObject[TAG_CUSTOM_DESCRIPTION].get<std::string>();
93 }
94 if (IsInt32(jsonObject, TAG_LOCAL_DEVICE_TYPE)) {
95 deviceType = jsonObject[TAG_LOCAL_DEVICE_TYPE].get<std::int32_t>();
96 }
97 if (IsString(jsonObject, TAG_HOST_PKGLABEL)) {
98 hostPkgLabel = jsonObject[TAG_HOST_PKGLABEL].get<std::string>();
99 }
100 }
101
102 bundleName_ = DM_UI_BUNDLE_NAME;
103 abilityName_ = CONFIRM_ABILITY_NAME;
104 deviceName_ = deviceName;
105 appOperationStr_ = appOperationStr;
106 customDescriptionStr_ = customDescriptionStr;
107 deviceType_ = deviceType;
108 hostPkgLabel_ = hostPkgLabel;
109 ConnectExtension();
110 }
111
ShowPinDialog(const std::string param)112 void DmDialogManager::ShowPinDialog(const std::string param)
113 {
114 bundleName_ = DM_UI_BUNDLE_NAME;
115 abilityName_ = PIN_ABILITY_NAME;
116 pinCode_ = param;
117 #if !(defined(__LITEOS_M__) || defined(LITE_DEVICE))
118 ffrt::submit([]() { ConnectExtension(); });
119 #else
120 std::thread pinDilog([]() { 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 targetDeviceName_ = param;
132 bundleName_ = DM_UI_BUNDLE_NAME;
133 abilityName_ = INPUT_ABILITY_NAME;
134 ConnectExtension();
135 }
136
ConnectExtension()137 void DmDialogManager::ConnectExtension()
138 {
139 LOGI("DmDialogManager::ConnectExtension start.");
140 if (isConnectSystemUI_.load() && dialogConnectionCallback_ != nullptr) {
141 AppExecFwk::ElementName element;
142 dialogConnectionCallback_->OnAbilityConnectDone(element, g_remoteObject, INVALID_USERID);
143 LOGI("DmDialogManager::ConnectExtension dialog has been show.");
144 return;
145 }
146 AAFwk::Want want;
147 std::string bundleName = "com.ohos.sceneboard";
148 std::string abilityName = "com.ohos.sceneboard.systemdialog";
149 want.SetElementName(bundleName, abilityName);
150 auto abilityManager = AAFwk::AbilityManagerClient::GetInstance();
151 if (abilityManager == nullptr) {
152 LOGE("AbilityManagerClient is nullptr");
153 return;
154 }
155
156 LOGI("DmDialogManager::ConnectExtension abilityManager ConnectAbility begin.");
157 auto ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
158 if (ret != ERR_OK) {
159 LOGE("ConnectExtensionAbility sceneboard failed.");
160 bundleName = "com.ohos.systemui";
161 abilityName = "com.ohos.systemui.dialog";
162 want.SetElementName(bundleName, abilityName);
163 ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
164 if (ret != ERR_OK) {
165 LOGE("ConnectExtensionAbility systemui failed.");
166 }
167 }
168 }
169
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)170 void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone(
171 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
172 {
173 LOGI("OnAbilityConnectDone");
174 std::unique_lock<std::mutex> lock(mutex_);
175 if (remoteObject == nullptr) {
176 LOGE("remoteObject is nullptr");
177 return;
178 }
179 if (g_remoteObject == nullptr) {
180 g_remoteObject = remoteObject;
181 }
182 MessageParcel data;
183 MessageParcel reply;
184 MessageOption option;
185 data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
186 data.WriteString16(u"bundleName");
187 data.WriteString16(Str8ToStr16(DmDialogManager::GetBundleName()));
188 data.WriteString16(u"abilityName");
189 data.WriteString16(Str8ToStr16(DmDialogManager::GetAbilityName()));
190 data.WriteString16(u"parameters");
191 nlohmann::json param;
192 param["ability.want.params.uiExtensionType"] = "sysDialog/common";
193 param["sysDialogZOrder"] = WINDOW_LEVEL_DEFAULT;
194 if (DmDialogManager::GetAbilityName() == INPUT_ABILITY_NAME) {
195 param["sysDialogZOrder"] = WINDOW_LEVEL_UPPER;
196 }
197 param["pinCode"] = DmDialogManager::GetPinCode();
198 param["deviceName"] = DmDialogManager::GetDeviceName();
199 param["appOperationStr"] = DmDialogManager::GetAppOperationStr();
200 param["customDescriptionStr"] = DmDialogManager::GetCustomDescriptionStr();
201 param["deviceType"] = DmDialogManager::GetDeviceType();
202 param[TAG_TARGET_DEVICE_NAME] = DmDialogManager::GetTargetDeviceName();
203 param[TAG_HOST_PKGLABEL] = DmDialogManager::GetHostPkgLabel();
204 param["disableUpGesture"] = 1;
205 std::string paramStr = param.dump();
206 data.WriteString16(Str8ToStr16(paramStr));
207 LOGI("show dm dialog is begin");
208 const uint32_t cmdCode = 1;
209 int32_t ret = remoteObject->SendRequest(cmdCode, data, reply, option);
210 if (ret != ERR_OK) {
211 LOGE("show dm dialog is failed: %{public}d", ret);
212 return;
213 }
214 isConnectSystemUI_.store(true);
215 LOGI("show dm dialog is success");
216 }
217
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)218 void DmDialogManager::DialogAbilityConnection::OnAbilityDisconnectDone(
219 const AppExecFwk::ElementName& element, int resultCode)
220 {
221 LOGI("OnAbilityDisconnectDone");
222 std::lock_guard<std::mutex> lock(mutex_);
223 isConnectSystemUI_.store(false);
224 }
225 }
226 }