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 }