1 /*
2  * Copyright (C) 2023 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 "accessibility_short_key_dialog.h"
17 #include "hilog_wrapper.h"
18 
19 #include <algorithm>
20 #include "ability_connection.h"
21 #include "ability_connect_callback.h"
22 #include "bool_wrapper.h"
23 #include "double_wrapper.h"
24 #include "extension_manager_client.h"
25 #include "int_wrapper.h"
26 #include "ipc_skeleton.h"
27 #include "refbase.h"
28 #include "string_wrapper.h"
29 #include "want_params_wrapper.h"
30 #include "nlohmann/json.hpp"
31 
32 constexpr int32_t SHORTKEY_DIALOG_PARAM_NUM = 3;
33 constexpr int32_t DEFAULT_VALUE_MINUS_ONE = -1;
34 constexpr int32_t SYS_DIALOG_Z_ORDER_ON_LOCK_SCREEN = 2;
35 
36 namespace OHOS {
37 namespace Accessibility {
38 // ability_connection
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)39 void ShortkeyAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
40     const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
41 {
42     HILOG_DEBUG("on ability connected");
43     MessageParcel data;
44     MessageParcel reply;
45     MessageOption option;
46     data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
47     data.WriteString16(u"bundleName");
48     data.WriteString16(u"com.huawei.hmos.settings");
49     data.WriteString16(u"abilityName");
50     data.WriteString16(u"AccessibilityShortKeyDialog");
51     data.WriteString16(u"parameters");
52     data.WriteString16(Str8ToStr16(GetCommandString()));
53 
54     if (!data.WriteParcelable(&element)) {
55         HILOG_ERROR("Connect done element error.");
56         return;
57     }
58 
59     if (!data.WriteRemoteObject(remoteObject)) {
60         HILOG_ERROR("Connect done remote object error.");
61         return;
62     }
63 
64     if (!data.WriteInt32(resultCode)) {
65         HILOG_ERROR("Connect done result code error.");
66         return;
67     }
68 
69     int32_t errCode = remoteObject->SendRequest(
70         AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
71     HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
72 }
73 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int32_t resultCode)74 void ShortkeyAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
75     int32_t resultCode)
76 {
77     HILOG_DEBUG("on ability disconnected");
78 }
79 
GetCommandString()80 std::string ShortkeyAbilityConnection::GetCommandString()
81 {
82     return commandStr_;
83 }
84 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)85 void ReConfirmAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
86     const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
87 {
88     HILOG_DEBUG("on ability connected");
89     MessageParcel data;
90     MessageParcel reply;
91     MessageOption option;
92     data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
93     data.WriteString16(u"bundleName");
94     data.WriteString16(u"com.huawei.hmos.settings");
95     data.WriteString16(u"abilityName");
96     data.WriteString16(u"AccessibilityReConfirmDialog");
97     data.WriteString16(u"parameters");
98     data.WriteString16(Str8ToStr16(GetCommandString()));
99 
100     if (!data.WriteParcelable(&element)) {
101         HILOG_ERROR("Connect done element error.");
102         return;
103     }
104 
105     if (!data.WriteRemoteObject(remoteObject)) {
106         HILOG_ERROR("Connect done remote object error.");
107         return;
108     }
109 
110     if (!data.WriteInt32(resultCode)) {
111         HILOG_ERROR("Connect done result code error.");
112         return;
113     }
114 
115     int32_t errCode = remoteObject->SendRequest(
116         AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
117     HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
118 }
119 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int32_t resultCode)120 void ReConfirmAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
121     int32_t resultCode)
122 {
123     HILOG_DEBUG("on ability disconnected");
124 }
125 
GetCommandString()126 std::string ReConfirmAbilityConnection::GetCommandString()
127 {
128     return commandStr_;
129 }
130 
131 // dialog
AccessibilityShortkeyDialog()132 AccessibilityShortkeyDialog::AccessibilityShortkeyDialog() {}
133 
~AccessibilityShortkeyDialog()134 AccessibilityShortkeyDialog::~AccessibilityShortkeyDialog()
135 {
136     HILOG_DEBUG("release AccessibilityShortkeyDialog");
137 }
138 
ConnectDialog(ShortKeyDialogType dialogType)139 bool AccessibilityShortkeyDialog::ConnectDialog(ShortKeyDialogType dialogType)
140 {
141     HILOG_DEBUG("AccessibilityShortkeyDialog dialog");
142     if (!ConnectExtension(dialogType)) {
143         HILOG_ERROR("failed to connect dialog.");
144         return false;
145     }
146     return true;
147 }
148 
ConnectExtensionAbility(const AAFwk::Want & want,const std::string commandStr,ShortKeyDialogType dialogType)149 bool AccessibilityShortkeyDialog::ConnectExtensionAbility(const AAFwk::Want &want, const std::string commandStr,
150     ShortKeyDialogType dialogType)
151 {
152     // reset current callingIdentify
153     std::string identity = IPCSkeleton::ResetCallingIdentity();
154     int32_t ret = ERR_OK;
155 
156     if (dialogType == ShortKeyDialogType::FUNCTION_SELECT) {
157         functionSelectConn_ = new(std::nothrow) ShortkeyAbilityConnection(commandStr);
158         if (functionSelectConn_ == nullptr) {
159             HILOG_ERROR("connection_ is nullptr.");
160             return false;
161         }
162         ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
163             functionSelectConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
164     } else {
165         reConfirmConn_ = new(std::nothrow) ReConfirmAbilityConnection(commandStr);
166         if (reConfirmConn_ == nullptr) {
167             HILOG_ERROR("connection_ is nullptr.");
168             return false;
169         }
170         ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
171             reConfirmConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
172     }
173     HILOG_DEBUG("ret is: %{public}d.", ret);
174     // set current callingIdentify back.
175     IPCSkeleton::SetCallingIdentity(identity);
176     if (ret != ERR_OK) {
177         HILOG_ERROR("ret isn't ERR_OK");
178         return false;
179     }
180     return true;
181 }
182 
ConnectExtension(ShortKeyDialogType dialogType)183 bool AccessibilityShortkeyDialog::ConnectExtension(ShortKeyDialogType dialogType)
184 {
185     std::string tmp = BuildStartCommand();
186     HILOG_DEBUG("start command: %{public}s", tmp.c_str());
187 
188     AAFwk::Want want;
189     std::string bundleName = "com.ohos.sceneboard";
190     std::string abilityName = "com.ohos.sceneboard.systemdialog";
191     want.SetElementName(bundleName, abilityName);
192     bool ret = ConnectExtensionAbility(want, tmp, dialogType);
193     if (!ret) {
194         HILOG_ERROR("ConnectExtensionAbility failed.");
195         return false;
196     }
197     HILOG_DEBUG("ConnectExtensionAbility successed.");
198     return true;
199 }
200 
DisconnectExtension(ShortKeyDialogType dialogType) const201 bool AccessibilityShortkeyDialog::DisconnectExtension(ShortKeyDialogType dialogType) const
202 {
203     if (dialogType == ShortKeyDialogType::FUNCTION_SELECT) {
204         if (functionSelectConn_ == nullptr) {
205             return true;
206         }
207         ErrCode ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(functionSelectConn_);
208         if (ret != ERR_OK) {
209             HILOG_ERROR("disconnect extension ability failed ret: %{public}d.", ret);
210             return false;
211         }
212         return true;
213     } else {
214         if (reConfirmConn_ == nullptr) {
215             return true;
216         }
217         ErrCode ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(reConfirmConn_);
218         if (ret != ERR_OK) {
219             HILOG_ERROR("disconnect extension ability failed ret: %{public}d.", ret);
220             return false;
221         }
222         return true;
223     }
224 }
225 
BuildStartCommand()226 std::string AccessibilityShortkeyDialog::BuildStartCommand()
227 {
228     nlohmann::json root;
229     std::string tmp = "sysDialog/common";
230     root["ability.want.params.uiExtensionType"] = tmp;
231     root["sysDialogZOrder"] = SYS_DIALOG_Z_ORDER_ON_LOCK_SCREEN;
232     std::string cmdData = root.dump();
233     HILOG_DEBUG("cmdData is: %{public}s.", cmdData.c_str());
234     return cmdData;
235 }
236 } // namespace Accessibility
237 } // namespace OHOS