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 "ability_manager_client.h"
19 #include "auth_message_processor.h"
20 #include "dm_anonymous.h"
21 #include "dm_constants.h"
22 #include "dm_log.h"
23 #include "nlohmann/json.hpp"
24 #include "parameter.h"
25 #include "single_instance.h"
26
27 namespace OHOS {
28 namespace DistributedHardware {
29 static constexpr int32_t INVALID_USERID = -1;
30 static constexpr int32_t MESSAGE_PARCEL_KEY_SIZE = 3;
31 static constexpr int32_t WAIT_DIALOG_CLOSE_TIME_S = 10;
32 const int32_t USLEEP_SHOW_PIN_TIME_US = 50000; // 50ms
33 const std::string dmUiBundleName = "com.ohos.devicemanagerui";
34 const std::string comfirmAbilityName = "com.ohos.devicemanagerui.ConfirmUIExtAbility";
35 const std::string pinAbilityName = "com.ohos.devicemanagerui.PincodeUIExtAbility";
36 const std::string inputAbilityName = "com.ohos.devicemanagerui.InputUIExtAbility";
37 const std::string peerDeviceName = "deviceName";
38 const std::string appOperation = "appOperation";
39 const std::string customDescription = "customDescription";
40 const std::string peerdeviceType = "deviceType";
41
42 std::string DmDialogManager::bundleName_ = "";
43 std::string DmDialogManager::abilityName_ = "";
44 std::string DmDialogManager::deviceName_ = "";
45 std::string DmDialogManager::appOperationStr_ = "";
46 std::string DmDialogManager::customDescriptionStr_ = "";
47 std::string DmDialogManager::targetDeviceName_ = "";
48 std::string DmDialogManager::pinCode_ = "";
49 std::atomic<bool> DmDialogManager::isDialogDestroy_(true);
50 std::condition_variable DmDialogManager::dialogCondition_;
51 int32_t DmDialogManager::deviceType_ = -1;
52
DmDialogManager()53 DmDialogManager::DmDialogManager() : dialogConnectionCallback_(new DialogAbilityConnection()) {}
~DmDialogManager()54 DmDialogManager::~DmDialogManager()
55 {
56 dialogConnectionCallback_ = nullptr;
57 }
58
ShowConfirmDialog(const std::string param)59 void DmDialogManager::ShowConfirmDialog(const std::string param)
60 {
61 std::string deviceName = "";
62 std::string appOperationStr = "";
63 std::string customDescriptionStr = "";
64 int32_t deviceType = -1;
65 nlohmann::json jsonObject = nlohmann::json::parse(param, nullptr, false);
66 if (!jsonObject.is_discarded()) {
67 if (IsString(jsonObject, TAG_REQUESTER)) {
68 deviceName = jsonObject[TAG_REQUESTER].get<std::string>();
69 }
70 if (IsString(jsonObject, TAG_APP_OPERATION)) {
71 appOperationStr = jsonObject[TAG_APP_OPERATION].get<std::string>();
72 }
73 if (IsString(jsonObject, TAG_CUSTOM_DESCRIPTION)) {
74 customDescriptionStr = jsonObject[TAG_CUSTOM_DESCRIPTION].get<std::string>();
75 }
76 if (IsInt32(jsonObject, TAG_LOCAL_DEVICE_TYPE)) {
77 deviceType = jsonObject[TAG_LOCAL_DEVICE_TYPE].get<std::int32_t>();
78 }
79 }
80
81 bundleName_ = dmUiBundleName;
82 abilityName_ = comfirmAbilityName;
83 deviceName_ = deviceName;
84 appOperationStr_ = appOperationStr;
85 customDescriptionStr_ = customDescriptionStr;
86 deviceType_ = deviceType;
87 ConnectExtension();
88 }
89
ShowPinDialog(const std::string param)90 void DmDialogManager::ShowPinDialog(const std::string param)
91 {
92 bundleName_ = dmUiBundleName;
93 abilityName_ = pinAbilityName;
94 pinCode_ = param;
95 ConnectExtension();
96 }
97
ShowInputDialog(const std::string param)98 void DmDialogManager::ShowInputDialog(const std::string param)
99 {
100 targetDeviceName_ = param;
101 bundleName_ = dmUiBundleName;
102 abilityName_ = inputAbilityName;
103 ConnectExtension();
104 }
105
ConnectExtension()106 void DmDialogManager::ConnectExtension()
107 {
108 AAFwk::Want want;
109 std::string bundleName = "com.ohos.sceneboard";
110 std::string abilityName = "com.ohos.sceneboard.systemdialog";
111 want.SetElementName(bundleName, abilityName);
112 auto abilityManager = AAFwk::AbilityManagerClient::GetInstance();
113 if (abilityManager == nullptr) {
114 LOGE("AbilityManagerClient is nullptr");
115 return;
116 }
117
118 auto ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
119 if (ret != ERR_OK) {
120 LOGE("ConnectExtensionAbility sceneboard failed.");
121 bundleName = "com.ohos.systemui";
122 abilityName = "com.ohos.systemui.dialog";
123 want.SetElementName(bundleName, abilityName);
124 ret = abilityManager->ConnectAbility(want, dialogConnectionCallback_, INVALID_USERID);
125 if (ret != ERR_OK) {
126 LOGE("ConnectExtensionAbility systemui failed.");
127 }
128 }
129 }
130
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)131 void DmDialogManager::DialogAbilityConnection::OnAbilityConnectDone(
132 const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
133 {
134 LOGI("OnAbilityConnectDone");
135 std::unique_lock<std::mutex> lock(mutex_);
136 if (remoteObject == nullptr) {
137 LOGE("remoteObject is nullptr");
138 return;
139 }
140 if (!isDialogDestroy_.load()) {
141 auto status = dialogCondition_.wait_for(lock, std::chrono::seconds(WAIT_DIALOG_CLOSE_TIME_S),
142 [] () { return isDialogDestroy_.load(); });
143 if (!status) {
144 LOGE("wait dm dialog close failed.");
145 return;
146 }
147 usleep(USLEEP_SHOW_PIN_TIME_US); // 50ms
148 }
149 MessageParcel data;
150 MessageParcel reply;
151 MessageOption option;
152 data.WriteInt32(MESSAGE_PARCEL_KEY_SIZE);
153 data.WriteString16(u"bundleName");
154 data.WriteString16(Str8ToStr16(DmDialogManager::GetBundleName()));
155 data.WriteString16(u"abilityName");
156 data.WriteString16(Str8ToStr16(DmDialogManager::GetAbilityName()));
157 data.WriteString16(u"parameters");
158 nlohmann::json param;
159 param["ability.want.params.uiExtensionType"] = "sysDialog/common";
160 param["pinCode"] = DmDialogManager::GetPinCode();
161 param["deviceName"] = DmDialogManager::GetDeviceName();
162 param["appOperationStr"] = DmDialogManager::GetAppOperationStr();
163 param["customDescriptionStr"] = DmDialogManager::GetCustomDescriptionStr();
164 param["deviceType"] = DmDialogManager::GetDeviceType();
165 param[TAG_TARGET_DEVICE_NAME] = DmDialogManager::GetTargetDeviceName();
166 std::string paramStr = param.dump();
167 data.WriteString16(Str8ToStr16(paramStr));
168 LOGI("show dm dialog is begin");
169 const uint32_t cmdCode = 1;
170 int32_t ret = remoteObject->SendRequest(cmdCode, data, reply, option);
171 if (ret != ERR_OK) {
172 LOGE("show dm dialog is failed: %{public}d", ret);
173 return;
174 }
175 isDialogDestroy_.store(false);
176 LOGI("show dm dialog is success");
177 }
178
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)179 void DmDialogManager::DialogAbilityConnection::OnAbilityDisconnectDone(
180 const AppExecFwk::ElementName& element, int resultCode)
181 {
182 LOGI("OnAbilityDisconnectDone");
183 std::lock_guard<std::mutex> lock(mutex_);
184 isDialogDestroy_.store(true);
185 dialogCondition_.notify_all();
186 }
187 }
188 }