* Copyright (C) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "accessibility_short_key_dialog.h"
#include "hilog_wrapper.h"
#include <algorithm>
#include "ability_connection.h"
#include "ability_connect_callback.h"
#include "bool_wrapper.h"
#include "double_wrapper.h"
#include "extension_manager_client.h"
#include "int_wrapper.h"
#include "ipc_skeleton.h"
#include "refbase.h"
#include "string_wrapper.h"
#include "want_params_wrapper.h"
#include "nlohmann/json.hpp"
constexpr int32_t SHORTKEY_DIALOG_PARAM_NUM = 3;
constexpr int32_t DEFAULT_VALUE_MINUS_ONE = -1;
constexpr int32_t SYS_DIALOG_Z_ORDER_ON_LOCK_SCREEN = 2;
namespace OHOS {
namespace Accessibility {
void ShortkeyAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
{
HILOG_DEBUG("on ability connected");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
data.WriteString16(u"bundleName");
data.WriteString16(u"com.ohos.settings");
data.WriteString16(u"abilityName");
data.WriteString16(u"AccessibilityShortKeyDialog");
data.WriteString16(u"parameters");
data.WriteString16(Str8ToStr16(GetCommandString()));
if (!data.WriteParcelable(&element)) {
HILOG_ERROR("Connect done element error.");
return;
}
if (!data.WriteRemoteObject(remoteObject)) {
HILOG_ERROR("Connect done remote object error.");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Connect done result code error.");
return;
}
int32_t errCode = remoteObject->SendRequest(
AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
}
void ShortkeyAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
int32_t resultCode)
{
HILOG_DEBUG("on ability disconnected");
}
std::string ShortkeyAbilityConnection::GetCommandString()
{
return commandStr_;
}
void ReConfirmAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
{
HILOG_DEBUG("on ability connected");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
data.WriteString16(u"bundleName");
data.WriteString16(u"com.ohos.settings");
data.WriteString16(u"abilityName");
data.WriteString16(u"AccessibilityReConfirmDialog");
data.WriteString16(u"parameters");
data.WriteString16(Str8ToStr16(GetCommandString()));
if (!data.WriteParcelable(&element)) {
HILOG_ERROR("Connect done element error.");
return;
}
if (!data.WriteRemoteObject(remoteObject)) {
HILOG_ERROR("Connect done remote object error.");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Connect done result code error.");
return;
}
int32_t errCode = remoteObject->SendRequest(
AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
}
void ReConfirmAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
int32_t resultCode)
{
HILOG_DEBUG("on ability disconnected");
}
std::string ReConfirmAbilityConnection::GetCommandString()
{
return commandStr_;
}
void ExclusiveAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
{
HILOG_DEBUG("on ability connected");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
data.WriteString16(u"bundleName");
data.WriteString16(u"com.ohos.settings");
data.WriteString16(u"abilityName");
data.WriteString16(u"AccessibilityIgnoreConfirmDialog");
data.WriteString16(u"parameters");
data.WriteString16(Str8ToStr16(GetCommandString()));
if (!data.WriteParcelable(&element)) {
HILOG_ERROR("Connect done element error.");
return;
}
if (!data.WriteRemoteObject(remoteObject)) {
HILOG_ERROR("Connect done remote object error.");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Connect done result code error.");
return;
}
int32_t errCode = remoteObject->SendRequest(
AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
}
void ExclusiveAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
int32_t resultCode)
{
HILOG_DEBUG("on ability disconnected");
}
std::string ExclusiveAbilityConnection::GetCommandString()
{
return commandStr_;
}
void ZoomGestureConflictAbilityConnection::OnAbilityConnectDone(const AppExecFwk::ElementName &element,
const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
{
HILOG_DEBUG("on ability connected");
MessageParcel data;
MessageParcel reply;
MessageOption option;
data.WriteInt32(SHORTKEY_DIALOG_PARAM_NUM);
data.WriteString16(u"bundleName");
data.WriteString16(u"com.ohos.settings");
data.WriteString16(u"abilityName");
data.WriteString16(u"AccessibilityZoomGestureDialog");
data.WriteString16(u"parameters");
data.WriteString16(Str8ToStr16(GetCommandString()));
if (!data.WriteParcelable(&element)) {
HILOG_ERROR("Connect done element error.");
return;
}
if (!data.WriteRemoteObject(remoteObject)) {
HILOG_ERROR("Connect done remote object error.");
return;
}
if (!data.WriteInt32(resultCode)) {
HILOG_ERROR("Connect done result code error.");
return;
}
int32_t errCode = remoteObject->SendRequest(
AAFwk::IAbilityConnection::ON_ABILITY_CONNECT_DONE, data, reply, option);
HILOG_DEBUG("AbilityConnectionWrapperProxy::OnAbilityConnectDone result %{public}d", errCode);
}
void ZoomGestureConflictAbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element,
int32_t resultCode)
{
HILOG_DEBUG("on ability disconnected");
}
std::string ZoomGestureConflictAbilityConnection::GetCommandString()
{
return commandStr_;
}
AccessibilityShortkeyDialog::AccessibilityShortkeyDialog() {}
AccessibilityShortkeyDialog::~AccessibilityShortkeyDialog()
{
HILOG_DEBUG("release AccessibilityShortkeyDialog");
}
bool AccessibilityShortkeyDialog::ConnectDialog(ShortKeyDialogType dialogType)
{
HILOG_DEBUG("AccessibilityShortkeyDialog dialog");
if (!ConnectExtension(dialogType)) {
HILOG_ERROR("failed to connect dialog.");
return false;
}
return true;
}
bool AccessibilityShortkeyDialog::ConnectExtensionAbility(const AAFwk::Want &want, const std::string commandStr,
ShortKeyDialogType dialogType)
{
std::string identity = IPCSkeleton::ResetCallingIdentity();
int32_t ret = ERR_OK;
switch (dialogType) {
case ShortKeyDialogType::FUNCTION_SELECT:
functionSelectConn_ = new(std::nothrow) ShortkeyAbilityConnection(commandStr);
if (functionSelectConn_ == nullptr) {
HILOG_ERROR("connection_ is nullptr.");
IPCSkeleton::SetCallingIdentity(identity);
return false;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
functionSelectConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
break;
case ShortKeyDialogType::READER_EXCLUSIVE:
readerExclusiveConn_ = new(std::nothrow) ExclusiveAbilityConnection(commandStr);
if (readerExclusiveConn_ == nullptr) {
HILOG_ERROR("connection_ is nullptr.");
IPCSkeleton::SetCallingIdentity(identity);
return false;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
readerExclusiveConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
break;
case ShortKeyDialogType::RECONFIRM:
reConfirmConn_ = new(std::nothrow) ReConfirmAbilityConnection(commandStr);
if (reConfirmConn_ == nullptr) {
HILOG_ERROR("connection_ is nullptr.");
IPCSkeleton::SetCallingIdentity(identity);
return false;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
reConfirmConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
break;
case ZOOM_GESTURE_CONFLICT:
zoomGestureConflictConn_ = new(std::nothrow) ZoomGestureConflictAbilityConnection(commandStr);
if (zoomGestureConflictConn_ == nullptr) {
HILOG_ERROR("connection_ is nullptr.");
IPCSkeleton::SetCallingIdentity(identity);
return false;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().ConnectServiceExtensionAbility(want,
zoomGestureConflictConn_, nullptr, DEFAULT_VALUE_MINUS_ONE);
break;
default:
HILOG_ERROR("unknown type");
}
HILOG_DEBUG("ret is: %{public}d.", ret);
IPCSkeleton::SetCallingIdentity(identity);
if (ret != ERR_OK) {
HILOG_ERROR("ret isn't ERR_OK");
return false;
}
return true;
}
bool AccessibilityShortkeyDialog::ConnectExtension(ShortKeyDialogType dialogType)
{
std::string tmp = BuildStartCommand();
HILOG_DEBUG("start command: %{public}s", tmp.c_str());
AAFwk::Want want;
std::string bundleName = "com.ohos.sceneboard";
std::string abilityName = "com.ohos.sceneboard.systemdialog";
want.SetElementName(bundleName, abilityName);
bool ret = ConnectExtensionAbility(want, tmp, dialogType);
if (!ret) {
bundleName = "com.ohos.systemui";
abilityName = "com.ohos.systemui.dialog";
want.SetElementName(bundleName, abilityName);
bool retNot = ConnectExtensionAbility(want, tmp, dialogType);
if (!retNot) {
HILOG_ERROR("ConnectExtensionAbility failed.");
return false;
}
}
HILOG_DEBUG("ConnectExtensionAbility successed.");
return true;
}
bool AccessibilityShortkeyDialog::DisconnectExtension(ShortKeyDialogType dialogType) const
{
ErrCode ret = ERR_OK;
switch (dialogType) {
case ShortKeyDialogType::FUNCTION_SELECT:
if (functionSelectConn_ == nullptr) {
return true;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(functionSelectConn_);
break;
case ShortKeyDialogType::READER_EXCLUSIVE:
if (readerExclusiveConn_ == nullptr) {
return true;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(readerExclusiveConn_);
break;
case ShortKeyDialogType::RECONFIRM:
if (reConfirmConn_ == nullptr) {
return true;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(reConfirmConn_);
break;
case ShortKeyDialogType::ZOOM_GESTURE_CONFLICT:
if (zoomGestureConflictConn_ == nullptr) {
return true;
}
ret = AAFwk::ExtensionManagerClient::GetInstance().DisconnectAbility(zoomGestureConflictConn_);
break;
default:
HILOG_ERROR("unkonwn type");
}
if (ret != ERR_OK) {
HILOG_ERROR("disconnect extension ability failed ret: %{public}d.", ret);
return false;
}
return true;
}
std::string AccessibilityShortkeyDialog::BuildStartCommand()
{
nlohmann::json root;
std::string tmp = "sysDialog/common";
root["ability.want.params.uiExtensionType"] = tmp;
root["sysDialogZOrder"] = SYS_DIALOG_Z_ORDER_ON_LOCK_SCREEN;
std::string cmdData = root.dump();
HILOG_DEBUG("cmdData is: %{public}s.", cmdData.c_str());
return cmdData;
}
}
}