add system cmd channel

Signed-off-by: guojin31 <guojin31@huawei.com>
This commit is contained in:
guojin31 2024-04-13 14:37:24 +08:00
parent 192db29eea
commit 43aceea457
32 changed files with 717 additions and 30 deletions

View File

@ -88,6 +88,7 @@
"../../../../frameworks/native/inputmethod_controller/include/input_method_property.h",
"../../../../frameworks/native/inputmethod_controller/include/input_method_utils.h",
"../../../../frameworks/native/inputmethod_controller/include/input_window_info.h",
"../../../../frameworks/native/inputmethod_controller/include/i_system_cmd_channel.h",
"ime_event_listener.h",
"ime_event_monitor_manager.h",
"input_method_controller.h"

View File

@ -19,6 +19,7 @@
#include "global.h"
#include "i_input_control_channel.h"
#include "i_input_data_channel.h"
#include "i_system_cmd_channel.h"
#include "input_attribute.h"
#include "input_client_info.h"
#include "input_method_property.h"
@ -46,6 +47,7 @@ public:
IS_PANEL_SHOWN,
SECURITY_CHANGE,
ON_CLIENT_INACTIVE,
ON_CONNECT_SYSTEM_CMD,
CORE_CMD_LAST,
};
@ -61,6 +63,7 @@ public:
virtual bool IsEnable() = 0;
virtual int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) = 0;
virtual int32_t OnSecurityChange(int32_t security) = 0 ;
virtual int32_t OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) = 0 ;
virtual void OnClientInactive(const sptr<IInputDataChannel> &channel) = 0;
};
} // namespace MiscServices

View File

@ -39,6 +39,7 @@
#include "message.h"
#include "message_handler.h"
#include "private_command_interface.h"
#include "system_cmd_channel_proxy.h"
#include "unRegistered_type.h"
namespace OHOS {
@ -85,10 +86,12 @@ public:
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown);
int32_t GetSecurityMode(int32_t &security);
int32_t OnSecurityChange(int32_t security);
int32_t OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent);
void OnClientInactive(const sptr<IRemoteObject> &channel);
void NotifyKeyboardHeight(const std::shared_ptr<InputMethodPanel> inputMethodPanel);
int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
int32_t ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
int32_t ReceivePrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand, bool isSystemCmd = false) override;
bool IsDefaultIme();
int32_t GetCallingWindowInfo(CallingWindowInfo &windowInfo);
@ -103,6 +106,11 @@ private:
std::mutex dataChannelLock_;
sptr<IRemoteObject> dataChannelObject_ = nullptr;
std::shared_ptr<InputDataChannelProxy> dataChannelProxy_ = nullptr;
std::mutex systemCmdChannelLock_;
sptr<IRemoteObject> systemCmdObject_ = nullptr;
std::shared_ptr<SystemCmdChannelProxy> systemCmdChannelProxy_ = nullptr;
std::shared_ptr<InputMethodEngineListener> imeListener_;
std::shared_ptr<KeyboardListener> kdListener_;
@ -114,6 +122,10 @@ private:
sptr<IInputMethodSystemAbility> GetImsaProxy();
void OnRemoteSaDied(const wptr<IRemoteObject> &object);
void SetSystemCmdChannel(const sptr<IRemoteObject> &object);
std::shared_ptr<SystemCmdChannelProxy> GetSystemCmdProxy();
void ClearSystemCmdChannel();
void SetInputDataChannel(const sptr<IRemoteObject> &object);
std::shared_ptr<InputDataChannelProxy> GetInputDataChannelProxy();
void ClearDataChannel(const sptr<IRemoteObject> &channel);
@ -138,12 +150,18 @@ private:
std::shared_ptr<InputMethodPanel> GetSoftKeyboardPanel();
int32_t ShowPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger);
int32_t HidePanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag, Trigger trigger);
int32_t NotifyIsShowSysPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag);
void SaveInputAttribute(const InputAttribute &inputAttribute);
InputAttribute GetInputAttribute();
void NotifyPanelStatusInfo(const PanelStatusInfo &info);
std::shared_ptr<SystemCmdChannelProxy> GetSystemCmdChannelProxy();
ConcurrentMap<PanelType, std::shared_ptr<InputMethodPanel>> panels_{};
std::atomic_bool isBound_{ false };
sptr<InputMethodCoreStub> coreStub_{ nullptr };
sptr<InputMethodAgentStub> agentStub_{ nullptr };
sptr<InputMethodAgentStub> systemAgentStub_{ nullptr };
std::mutex imeCheckMutex_;
bool isCurrentIme_ = false;
@ -154,6 +172,8 @@ private:
std::mutex defaultImeCheckMutex_;
bool isDefaultIme_ = false;
std::mutex inputAttrLock_;
InputAttribute inputAttribute_{};
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -45,6 +45,7 @@ public:
bool IsEnable() override;
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) override;
int32_t OnSecurityChange(int32_t security) override;
int32_t OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) override;
void OnClientInactive(const sptr<IInputDataChannel> &channel) override;
private:

View File

@ -48,6 +48,7 @@ public:
bool IsEnable() override;
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) override;
int32_t OnSecurityChange(int32_t security) override;
int32_t OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) override;
void OnClientInactive(const sptr<IInputDataChannel> &channel) override;
void SetMessageHandler(MessageHandler *msgHandler);
@ -64,6 +65,7 @@ private:
int32_t IsPanelShownOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t SecurityChangeOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t OnClientInactiveOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t OnConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply);
using ParcelHandler = std::function<bool(MessageParcel &)>;
int32_t SendMessage(int code, ParcelHandler input = nullptr);
using RequestHandler = int32_t (InputMethodCoreStub::*)(MessageParcel &, MessageParcel &);
@ -79,6 +81,7 @@ private:
{ static_cast<uint32_t>(IS_PANEL_SHOWN), &InputMethodCoreStub::IsPanelShownOnRemote },
{ static_cast<uint32_t>(SECURITY_CHANGE), &InputMethodCoreStub::SecurityChangeOnRemote },
{ static_cast<uint32_t>(ON_CLIENT_INACTIVE), &InputMethodCoreStub::OnClientInactiveOnRemote },
{ static_cast<uint32_t>(ON_CONNECT_SYSTEM_CMD), &InputMethodCoreStub::OnConnectSystemCmdOnRemote },
};
};
} // namespace MiscServices

View File

@ -241,6 +241,7 @@ int32_t InputMethodAbility::StartInput(const InputClientInfo &clientInfo, bool i
"IMA isShowKeyboard: %{public}d, isBindFromClient: %{public}d", clientInfo.isShowKeyboard, isBindFromClient);
SetInputDataChannel(clientInfo.channel->AsObject());
isBindFromClient ? InvokeTextChangeCallback(clientInfo.config) : NotifyAllTextConfig();
SaveInputAttribute(clientInfo.attribute);
if (imeListener_ == nullptr) {
IMSA_HILOGE("imeListener is nullptr");
return ErrorCode::ERROR_IME;
@ -369,6 +370,12 @@ void InputMethodAbility::OnConfigurationChange(Message *msg)
attribute.inputPattern = data->ReadInt32();
IMSA_HILOGD("InputMethodAbility, enterKeyType: %{public}d, inputPattern: %{public}d", attribute.enterKeyType,
attribute.inputPattern);
SaveInputAttribute(attribute);
// add for mod inputPattern when panel show
auto panel = GetSoftKeyboardPanel();
if (panel != nullptr) {
NotifyIsShowSysPanel(panel, panel->GetPanelFlag());
}
kdListener_->OnEditorAttributeChange(attribute);
}
@ -707,6 +714,7 @@ void InputMethodAbility::OnRemoteSaDied(const wptr<IRemoteObject> &object)
IMSA_HILOGI("input method service died");
isBound_.store(false);
ClearInputControlChannel();
ClearSystemCmdChannel();
{
std::lock_guard<std::mutex> lock(abilityLock_);
abilityManager_ = nullptr;
@ -737,6 +745,44 @@ int32_t InputMethodAbility::GetSecurityMode(int32_t &security)
return proxy->GetSecurityMode(security);
}
void InputMethodAbility::ClearSystemCmdChannel()
{
std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
if (systemCmdObject_ == nullptr || systemCmdChannelProxy_ == nullptr) {
IMSA_HILOGD("systemCmdObject_ already nullptr");
return;
}
systemCmdObject_ = nullptr;
systemCmdChannelProxy_ = nullptr;
IMSA_HILOGD("end");
}
std::shared_ptr<SystemCmdChannelProxy> InputMethodAbility::GetSystemCmdChannelProxy()
{
std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
return systemCmdChannelProxy_;
}
int32_t InputMethodAbility::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent)
{
IMSA_HILOGD("run in SetSystemCmdChannel");
std::lock_guard<std::mutex> lock(systemCmdChannelLock_);
auto channelProxy = std::make_shared<SystemCmdChannelProxy>(channel);
if (channelProxy == nullptr) {
IMSA_HILOGE("failed to new data channel proxy");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
systemCmdObject_ = channel;
systemCmdChannelProxy_ = channelProxy;
systemAgentStub_ = new (std::nothrow) InputMethodAgentStub();
if (systemAgentStub_ == nullptr) {
IMSA_HILOGE("failed to create agent");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
agent = systemAgentStub_->AsObject();
return ErrorCode::NO_ERROR;
}
int32_t InputMethodAbility::OnSecurityChange(int32_t security)
{
IMSA_HILOGI("InputMethodAbility start.");
@ -819,6 +865,7 @@ int32_t InputMethodAbility::ShowPanel(
IMSA_HILOGE("Set Keyboard failed, ret = %{public}d", ret);
}
}
NotifyIsShowSysPanel(inputMethodPanel, flag);
auto ret = inputMethodPanel->ShowPanel();
if (ret == ErrorCode::NO_ERROR) {
NotifyPanelStatusInfo({ { inputMethodPanel->GetPanelType(), flag }, true, trigger });
@ -839,6 +886,36 @@ int32_t InputMethodAbility::HidePanel(
return ret;
}
int32_t InputMethodAbility::NotifyIsShowSysPanel(
const std::shared_ptr<InputMethodPanel> &inputMethodPanel, PanelFlag flag)
{
if (inputMethodPanel->GetPanelType() != SOFT_KEYBOARD) {
return ErrorCode::NO_ERROR;
}
bool isShow = false;
if (flag == FLG_FIXED && !GetInputAttribute().GetSecurityFlag()) {
isShow = true;
}
auto systemChannel = GetSystemCmdChannelProxy();
if (systemChannel == nullptr) {
IMSA_HILOGE("channel is nullptr");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
return systemChannel->NotifyIsShowSysPanel(isShow);
}
void InputMethodAbility::SaveInputAttribute(const InputAttribute &inputAttribute)
{
std::lock_guard<std::mutex> lock(inputAttrLock_);
inputAttribute_ = inputAttribute;
}
InputAttribute InputMethodAbility::GetInputAttribute()
{
std::lock_guard<std::mutex> lock(inputAttrLock_);
return inputAttribute_;
}
int32_t InputMethodAbility::HideKeyboard(Trigger trigger)
{
if (imeListener_ == nullptr) {
@ -1013,16 +1090,29 @@ int32_t InputMethodAbility::SendPrivateCommand(const std::unordered_map<std::str
IMSA_HILOGE("current is not default ime.");
return ErrorCode::ERROR_NOT_DEFAULT_IME;
}
auto channel = GetInputDataChannelProxy();
if (channel == nullptr) {
IMSA_HILOGE("channel is nullptr");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
if (!TextConfig::IsPrivateCommandValid(privateCommand)) {
IMSA_HILOGE("privateCommand is limit 32KB, count limit 5.");
return ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE;
}
if (TextConfig::IsSystemPrivateCommand(privateCommand)) {
auto systemChannel = GetSystemCmdChannelProxy();
if (systemChannel == nullptr) {
IMSA_HILOGE("channel is nullptr");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
return systemChannel->SendPrivateCommand(privateCommand);
} else {
auto channel = GetInputDataChannelProxy();
if (channel == nullptr) {
IMSA_HILOGE("channel is nullptr");
return ErrorCode::ERROR_CLIENT_NULL_POINTER;
}
return channel->SendPrivateCommand(privateCommand);
}
return channel->SendPrivateCommand(privateCommand);
}
int32_t InputMethodAbility::ReceivePrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
const std::unordered_map<std::string, PrivateDataValue> &privateCommand, bool isSystemCmd)
{
if (!IsDefaultIme()) {
IMSA_HILOGE("current is not default ime.");

View File

@ -53,6 +53,16 @@ int32_t InputMethodCoreProxy::OnSecurityChange(int32_t security)
});
}
int32_t InputMethodCoreProxy::OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent)
{
return SendRequest(ON_CONNECT_SYSTEM_CMD, [channel](MessageParcel& data) {
return data.WriteRemoteObject(channel->AsObject());
}, [&agent](MessageParcel &reply) {
agent = reply.ReadRemoteObject();
return true;
});
}
void InputMethodCoreProxy::StopInputService(bool isTerminateIme)
{
SendRequest(STOP_INPUT_SERVICE,

View File

@ -20,6 +20,7 @@
#include "i_input_data_channel.h"
#include "input_control_channel_proxy.h"
#include "system_cmd_channel_proxy.h"
#include "input_method_ability.h"
#include "ipc_skeleton.h"
#include "message_handler.h"
@ -123,6 +124,24 @@ int32_t InputMethodCoreStub::SecurityChangeOnRemote(MessageParcel &data, Message
return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputMethodCoreStub::OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent)
{
return ErrorCode::NO_ERROR;
}
int32_t InputMethodCoreStub::OnConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply)
{
sptr<IRemoteObject> channelObject = nullptr;
if (!ITypesUtil::Unmarshal(data, channelObject)) {
IMSA_HILOGE("failed to read message parcel");
return ErrorCode::ERROR_EX_PARCELABLE;
}
sptr<IRemoteObject> agent = nullptr;
auto ret = InputMethodAbility::GetInstance()->OnConnectSystemCmd(channelObject, agent);
return reply.WriteInt32(ret) && reply.WriteRemoteObject(agent) ? ErrorCode::NO_ERROR
: ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputMethodCoreStub::SetSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
{
SubProperty property;

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2024 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.
*/
#ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_I_SYSTEM_CMD_CHANNEL_H
#define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_I_SYSTEM_CMD_CHANNEL_H
#include <errors.h>
#include <unordered_map>
#include "global.h"
#include "input_method_utils.h"
#include "iremote_broker.h"
/**
* brief Definition of interface IInputDataChannel
* It defines the remote calls from input method service to input client
*/
namespace OHOS {
namespace MiscServices {
class ISystemCmdChannel : public IRemoteBroker {
public:
enum {
SEND_PRIVATE_COMMAND = FIRST_CALL_TRANSACTION,
NOTIFY_IS_SHOW_SYS_PANEL,
SYSTEM_CMD_LAST,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.ISystemCmdChannel");
virtual int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) = 0;
virtual int32_t NotifyIsShowSysPanel(bool isShow) = 0;
};
} // namespace MiscServices
} // namespace OHOS
#endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_I_SYSTEM_CMD_CHANNEL_H

View File

@ -73,7 +73,7 @@ public:
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) override;
int32_t GetSecurityMode(int32_t &security) override;
int32_t IsDefaultIme() override;
int32_t ConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) override;
// Deprecated because of no permission check, kept for compatibility
int32_t HideCurrentInputDeprecated() override;
int32_t ShowCurrentInputDeprecated() override;

View File

@ -31,6 +31,7 @@ constexpr uint32_t INVALID_WINDOW_ID = INIT_WINDOW_ID - 1;
constexpr int32_t INVALID_VALUE = -1;
constexpr size_t MAX_PRIVATE_COMMAND_SIZE = 32 * 1024; // 32K
constexpr size_t MAX_PRIVATE_COMMAND_COUNT = 5;
const constexpr char* SYSTEM_CMD_KEY = "sys_cmd";
enum class EnterKeyType {
UNSPECIFIED = 0,
NONE,
@ -187,7 +188,9 @@ struct TextConfig {
static bool IsPrivateCommandValid(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
size_t privateCommandSize = privateCommand.size();
if (privateCommandSize == 0 || privateCommandSize > MAX_PRIVATE_COMMAND_COUNT) {
size_t maxSize = IsSystemPrivateCommand(privateCommand) ? (MAX_PRIVATE_COMMAND_COUNT + 1)
: MAX_PRIVATE_COMMAND_COUNT;
if (privateCommandSize == 0 || privateCommandSize > maxSize) {
IMSA_HILOGE("privateCommand size must more than 0 and less than 5.");
return false;
}
@ -217,9 +220,23 @@ struct TextConfig {
}
return true;
}
static bool IsSystemPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
IMSA_HILOGI("IsSystemPrivateCommand in.");
size_t privateCommandSize = privateCommand.size();
if (privateCommandSize == 0 || privateCommandSize > MAX_PRIVATE_COMMAND_COUNT) {
IMSA_HILOGE("privateCommand size must more than 0 and less than 5.");
return false;
}
auto it = privateCommand.find(SYSTEM_CMD_KEY);
if (it != privateCommand.end()) {
return true;
}
return false;
}
};
enum class InputType : int32_t { NONE = -1, CAMERA_INPUT = 0, SECURITY_INPUT, END };
enum class InputType : int32_t { NONE = -1, CAMERA_INPUT = 0, SECURITY_INPUT, VOICE_INPUT, END };
enum class SwitchTrigger : uint32_t { CURRENT_IME = 0, SYSTEM_APP, IMSA };
} // namespace MiscServices

View File

@ -23,7 +23,8 @@ namespace MiscServices {
class PrivateCommandInterface {
public:
virtual int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) = 0;
virtual int32_t ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) = 0;
virtual int32_t ReceivePrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand, bool isSystemCmd = false) = 0;
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2024 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.
*/
#ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_PROXY_H
#define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_PROXY_H
#include <cstdint>
#include <functional>
#include <string>
#include "i_system_cmd_channel.h"
#include "iremote_broker.h"
#include "iremote_object.h"
#include "iremote_proxy.h"
#include "nocopyable.h"
#include "refbase.h"
namespace OHOS {
namespace MiscServices {
class SystemCmdChannelProxy : public IRemoteProxy<ISystemCmdChannel> {
public:
explicit SystemCmdChannelProxy(const sptr<IRemoteObject> &object);
~SystemCmdChannelProxy() = default;
DISALLOW_COPY_AND_MOVE(SystemCmdChannelProxy);
int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
int32_t NotifyIsShowSysPanel(bool isShow) override;
private:
static inline BrokerDelegator<SystemCmdChannelProxy> delegator_;
using ParcelHandler = std::function<bool(MessageParcel &)>;
int32_t SendRequest(int code, ParcelHandler input = nullptr, ParcelHandler output = nullptr);
};
} // namespace MiscServices
} // namespace OHOS
#endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_PROXY_H

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2024 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.
*/
#ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_STUB_H
#define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_STUB_H
#include <cstdint>
#include <string>
#include "i_system_cmd_channel.h"
#include "iremote_stub.h"
#include "message_handler.h"
#include "message_option.h"
#include "message_parcel.h"
#include "nocopyable.h"
#include "refbase.h"
namespace OHOS {
namespace MiscServices {
class InputMethodController;
class SystemCmdChannelStub : public IRemoteStub<ISystemCmdChannel> {
public:
DISALLOW_COPY_AND_MOVE(SystemCmdChannelStub);
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
SystemCmdChannelStub();
~SystemCmdChannelStub();
int32_t SendPrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
int32_t NotifyIsShowSysPanel(bool isShow) override;
private:
int32_t NotifyIsShowSysPanelOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t SendPrivateCommandOnRemote(MessageParcel &data, MessageParcel &reply);
using RequestHandler = int32_t (SystemCmdChannelStub::*)(MessageParcel &, MessageParcel &);
static inline const std::unordered_map<int32_t, RequestHandler> HANDLERS = {
{ static_cast<uint32_t>(SEND_PRIVATE_COMMAND), &SystemCmdChannelStub::SendPrivateCommandOnRemote },
{ static_cast<uint32_t>(NOTIFY_IS_SHOW_SYS_PANEL), &SystemCmdChannelStub::NotifyIsShowSysPanelOnRemote },
};
};
} // namespace MiscServices
} // namespace OHOS
#endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_SYSTEM_CMD_CHANNEL_STUB_H

View File

@ -316,7 +316,7 @@ void InputDataChannelStub::NotifyKeyboardHeight(uint32_t height)
int32_t InputDataChannelStub::SendPrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
return InputMethodController::GetInstance()->ReceivePrivateCommand(privateCommand);
return InputMethodController::GetInstance()->ReceivePrivateCommand(privateCommand, false);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -22,6 +22,7 @@
#include "global.h"
#include "input_client_stub.h"
#include "input_data_channel_stub.h"
#include "system_cmd_channel_stub.h"
#include "input_method_agent_proxy.h"
#include "input_method_property.h"
#include "input_method_status.h"
@ -236,6 +237,59 @@ int32_t InputMethodController::Attach(
return ErrorCode::NO_ERROR;
}
int32_t InputMethodController::ConnectSystemCmd(const sptr<OnSystemCmdListener> &listener)
{
IMSA_HILOGD("InputMethodController::ConnectSystemCmd");
SetSystemCmdListener(listener);
if (isSystemCmdConnect_.load()) {
IMSA_HILOGE("in connected state");
return ErrorCode::NO_ERROR;
}
auto channel = new (std::nothrow) SystemCmdChannelStub();
if (channel == nullptr) {
IMSA_HILOGE("channel is nullptr");
return ErrorCode::ERROR_SERVICE_START_FAILED;
}
auto proxy = GetSystemAbilityProxy();
if (proxy == nullptr) {
IMSA_HILOGE("proxy is nullptr");
return ErrorCode::ERROR_SERVICE_START_FAILED;
}
sptr<IRemoteObject> agent = nullptr;
int32_t ret = proxy->ConnectSystemCmd(channel, agent);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to start input, ret:%{public}d", ret);
return ret;
}
OnConnectCmdReady(agent);
IMSA_HILOGI("connect imf successfully");
return ErrorCode::NO_ERROR;
}
void InputMethodController::OnConnectCmdReady(sptr<IRemoteObject> agentObject)
{
IMSA_HILOGI("OnConnectCmdReady");
if (agentObject == nullptr) {
IMSA_HILOGE("agentObject is nullptr");
return;
}
isSystemCmdConnect_.store(true);
std::lock_guard<std::mutex> autoLock(systemAgentLock_);
if (systemAgent_ != nullptr && systemAgentObject_.GetRefPtr() == agentObject.GetRefPtr()) {
IMSA_HILOGD("agent has already been set");
return;
}
systemAgent_ = std::make_shared<InputMethodAgentProxy>(agentObject);
systemAgentObject_ = agentObject;
}
std::shared_ptr<IInputMethodAgent> InputMethodController::GetSystemCmdAgent()
{
IMSA_HILOGD("GetSystemCmdAgent");
std::lock_guard<std::mutex> autoLock(systemAgentLock_);
return systemAgent_;
}
int32_t InputMethodController::ShowTextInput()
{
if (!IsBound()) {
@ -487,6 +541,7 @@ void InputMethodController::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
}
RestoreListenInfoInSaDied();
RestoreAttachInfoInSaDied();
ClearSystemCmdAgent();
}
void InputMethodController::RestoreListenInfoInSaDied()
@ -973,6 +1028,28 @@ void InputMethodController::SetTextListener(sptr<OnTextChangedListener> listener
textListener_ = listener;
}
void InputMethodController::SetSystemCmdListener(sptr<OnSystemCmdListener> listener)
{
std::lock_guard<std::mutex> lock(systemCmdListenerLock_);
systemCmdListener_ = listener;
}
sptr<OnSystemCmdListener> InputMethodController::GetSystemCmdListener()
{
std::lock_guard<std::mutex> lock(systemCmdListenerLock_);
return systemCmdListener_;
}
void InputMethodController::ClearSystemCmdAgent()
{
{
std::lock_guard<std::mutex> autoLock(systemAgentLock_);
systemAgent_ = nullptr;
systemAgentObject_ = nullptr;
}
isSystemCmdConnect_.store(false);
}
bool InputMethodController::IsEditable()
{
std::lock_guard<std::recursive_mutex> lock(clientInfoLock_);
@ -1179,24 +1256,52 @@ void InputMethodController::PrintLogIfAceTimeout(int64_t start)
}
int32_t InputMethodController::ReceivePrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
const std::unordered_map<std::string, PrivateDataValue> &privateCommand, bool isSystemCmd)
{
auto listener = GetTextListener();
if (listener == nullptr) {
IMSA_HILOGE("textListener_ is nullptr");
return ErrorCode::ERROR_EX_NULL_POINTER;
if (isSystemCmd) {
auto cmdlistener = GetSystemCmdListener();
if (cmdlistener == nullptr) {
IMSA_HILOGE("cmdlistener is nullptr");
return ErrorCode::ERROR_EX_NULL_POINTER;
}
auto ret = cmdlistener->ReceivePrivateCommand(privateCommand);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("ReceivePrivateCommand err, ret %{public}d", ret);
return ErrorCode::ERROR_CMD_LISTENER_ERROR;
}
return ErrorCode::NO_ERROR;
} else {
auto listener = GetTextListener();
if (listener == nullptr) {
IMSA_HILOGE("textListener_ is nullptr");
return ErrorCode::ERROR_EX_NULL_POINTER;
}
auto ret = listener->ReceivePrivateCommand(privateCommand);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("ReceivePrivateCommand err, ret %{public}d", ret);
return ErrorCode::ERROR_TEXT_LISTENER_ERROR;
}
return ErrorCode::NO_ERROR;
}
auto ret = listener->ReceivePrivateCommand(privateCommand);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("ReceivePrivateCommand err, ret %{public}d", ret);
return ErrorCode::ERROR_TEXT_LISTENER_ERROR;
}
return ErrorCode::NO_ERROR;
}
int32_t InputMethodController::SendPrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
IMSA_HILOGD("SendPrivateCommand in");
if (!TextConfig::IsPrivateCommandValid(privateCommand)) {
IMSA_HILOGE("invalid private command size.");
return ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE;
}
if (isSystemCmdConnect_.load() && TextConfig::IsSystemPrivateCommand(privateCommand)) {
auto agent = GetSystemCmdAgent();
if (agent == nullptr) {
IMSA_HILOGE("agent is nullptr");
return ErrorCode::ERROR_IME_NOT_STARTED;
}
return agent->SendPrivateCommand(privateCommand);
}
if (!IsBound()) {
IMSA_HILOGD("not bound");
return ErrorCode::ERROR_CLIENT_NOT_BOUND;
@ -1205,10 +1310,6 @@ int32_t InputMethodController::SendPrivateCommand(
IMSA_HILOGD("not editable");
return ErrorCode::ERROR_CLIENT_NOT_EDITABLE;
}
if (!TextConfig::IsPrivateCommandValid(privateCommand)) {
IMSA_HILOGE("invalid private command size.");
return ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE;
}
auto agent = GetAgent();
if (agent == nullptr) {
IMSA_HILOGE("agent is nullptr");
@ -1216,5 +1317,16 @@ int32_t InputMethodController::SendPrivateCommand(
}
return agent->SendPrivateCommand(privateCommand);
}
int32_t InputMethodController::NotifyIsShowSysPanel(bool isShow)
{
auto listener = GetSystemCmdListener();
if (listener == nullptr) {
IMSA_HILOGE("listener is nullptr");
return ErrorCode::ERROR_NULL_POINTER;
}
listener->OnNotifyIsShowSysPanel(isShow);
return ErrorCode::NO_ERROR;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -41,6 +41,18 @@ int32_t InputMethodSystemAbilityProxy::StartInput(InputClientInfo &inputClientIn
});
}
int32_t InputMethodSystemAbilityProxy::ConnectSystemCmd(
const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent)
{
return SendRequest(
static_cast<uint32_t>(InputMethodInterfaceCode::CONNECT_SYSTEM_CMD),
[channel](MessageParcel &data) { return data.WriteRemoteObject(channel->AsObject()); },
[&agent](MessageParcel &reply) {
agent = reply.ReadRemoteObject();
return true;
});
}
int32_t InputMethodSystemAbilityProxy::ShowCurrentInput()
{
return SendRequest(static_cast<uint32_t>(InputMethodInterfaceCode::SHOW_CURRENT_INPUT));

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2024 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 "system_cmd_channel_proxy.h"
#include "global.h"
#include "ipc_types.h"
#include "itypes_util.h"
#include "message_option.h"
#include "message_parcel.h"
namespace OHOS {
namespace MiscServices {
SystemCmdChannelProxy::SystemCmdChannelProxy(const sptr<IRemoteObject> &object)
: IRemoteProxy<ISystemCmdChannel>(object)
{
}
int32_t SystemCmdChannelProxy::SendPrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
return SendRequest(SEND_PRIVATE_COMMAND,
[&privateCommand](MessageParcel &parcel) { return ITypesUtil::Marshal(parcel, privateCommand); });
}
int32_t SystemCmdChannelProxy::NotifyIsShowSysPanel(bool isShow)
{
return SendRequest(
NOTIFY_IS_SHOW_SYS_PANEL, [isShow](MessageParcel &parcel) { return ITypesUtil::Marshal(parcel, isShow); });
}
int32_t SystemCmdChannelProxy::SendRequest(int code, ParcelHandler input, ParcelHandler output)
{
IMSA_HILOGD("SystemCmdChannelProxy run in, code = %{public}d", code);
MessageParcel data;
MessageParcel reply;
MessageOption option{ MessageOption::TF_SYNC };
if (!data.WriteInterfaceToken(GetDescriptor())) {
IMSA_HILOGE("SystemCmdChannelProxy::write interface token failed");
return ErrorCode::ERROR_EX_ILLEGAL_ARGUMENT;
}
if (input != nullptr && (!input(data))) {
IMSA_HILOGE("SystemCmdChannelProxy::write data failed");
return ErrorCode::ERROR_EX_PARCELABLE;
}
auto remote = Remote();
if (remote == nullptr) {
IMSA_HILOGE("SystemCmdChannelProxy::SendRequest remote is nullptr.");
return ErrorCode::ERROR_EX_NULL_POINTER;
}
auto ret = remote->SendRequest(code, data, reply, option);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("SystemCmdChannelProxy send request failed, code: %{public}d, ret: %{public}d", code, ret);
return ret;
}
if (output != nullptr && (!output(reply))) {
IMSA_HILOGE("SystemCmdChannelProxy::reply parcel error");
return ErrorCode::ERROR_EX_PARCELABLE;
}
return ret;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2024 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 "system_cmd_channel_stub.h"
#include "global.h"
#include "input_method_controller.h"
#include "ipc_object_stub.h"
#include "ipc_skeleton.h"
#include "ipc_types.h"
#include "itypes_util.h"
#include "message.h"
namespace OHOS {
namespace MiscServices {
SystemCmdChannelStub::SystemCmdChannelStub()
{
}
SystemCmdChannelStub::~SystemCmdChannelStub()
{
}
int32_t SystemCmdChannelStub::SendPrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
return InputMethodController::GetInstance()->ReceivePrivateCommand(privateCommand, true);
}
int32_t SystemCmdChannelStub::SendPrivateCommandOnRemote(MessageParcel &data, MessageParcel &reply)
{
std::unordered_map<std::string, PrivateDataValue> privateCommand;
if (!ITypesUtil::Unmarshal(data, privateCommand)) {
IMSA_HILOGE("failed to read message parcel");
return ErrorCode::ERROR_EX_PARCELABLE;
}
return reply.WriteInt32(SendPrivateCommand(privateCommand)) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t SystemCmdChannelStub::NotifyIsShowSysPanel(bool isShow)
{
return InputMethodController::GetInstance()->NotifyIsShowSysPanel(isShow);
}
int32_t SystemCmdChannelStub::NotifyIsShowSysPanelOnRemote(MessageParcel &data, MessageParcel &reply)
{
bool isShow = false;
if (!ITypesUtil::Unmarshal(data, isShow)) {
IMSA_HILOGE("failed to read message parcel");
return ErrorCode::ERROR_EX_PARCELABLE;
}
return reply.WriteInt32(NotifyIsShowSysPanel(isShow)) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t SystemCmdChannelStub::OnRemoteRequest(
uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
IMSA_HILOGD("SystemCmdChannelStub, code: %{public}u, callingPid: %{public}d, callingUid: %{public}d", code,
IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != ISystemCmdChannel::GetDescriptor()) {
IMSA_HILOGE("SystemCmdChannelStub descriptor error");
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
if (code >= FIRST_CALL_TRANSACTION && code < static_cast<uint32_t>(SYSTEM_CMD_LAST)) {
return (this->*HANDLERS.at(code))(data, reply);
} else {
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -62,6 +62,7 @@ ohos_shared_library("inputmethod_ability") {
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_system_ability_proxy.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/itypes_util.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_proxy.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_proxy.cpp",
"${inputmethod_path}/services/src/global.cpp",
"${inputmethod_path}/services/src/input_control_channel_proxy.cpp",
"${inputmethod_path}/services/src/message.cpp",

View File

@ -24,6 +24,7 @@
*InputMethodSystemAbilityProxy*;
*ITypesUtil*;
*MessageHandler*;
*SystemCmdChannelProxy*;
local:
*;
};

View File

@ -63,6 +63,7 @@ ohos_shared_library("inputmethod_client") {
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/itypes_util.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_proxy.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_stub.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_stub.cpp",
"${inputmethod_path}/services/src/message.cpp",
"${inputmethod_path}/services/src/message_handler.cpp",
]
@ -123,6 +124,7 @@ ohos_static_library("inputmethod_client_static") {
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/itypes_util.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_proxy.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/keyevent_consumer_stub.cpp",
"${inputmethod_path}/frameworks/native/inputmethod_controller/src/system_cmd_channel_stub.cpp",
"${inputmethod_path}/services/src/message.cpp",
"${inputmethod_path}/services/src/message_handler.cpp",
]

View File

@ -71,6 +71,16 @@ public:
return ErrorCode::NO_ERROR;
}
};
class OnSystemCmdListener : public virtual RefBase {
public:
virtual int32_t ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
{
return ErrorCode::NO_ERROR;
}
virtual void OnNotifyIsShowSysPanel(bool isShow)
{
}
};
using PrivateDataValue = std::variant<std::string, bool, int32_t>;
using KeyEventCallback = std::function<void(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed)>;
class InputMethodController : public RefBase, public PrivateCommandInterface {
@ -124,6 +134,18 @@ public:
*/
IMF_API int32_t Attach(sptr<OnTextChangedListener> &listener, bool isShowKeyboard, const InputAttribute &attribute);
/**
* @brief Show soft keyboard, set listener and bind IMSA with default states and attribute.
*
* This function is used to show soft keyboard, set listener and bind IMSA,
* default state is 'true', default attribute is 'InputAttribute::PATTERN_TEXT'.
*
* @param listener Indicates the listener in order to manipulate text.
* @return Returns 0 for success, others for failure.
* @since 6
*/
IMF_API int32_t ConnectSystemCmd(const sptr<OnSystemCmdListener> &listener);
/**
* @brief Set listener and bind IMSA with given states and textConfig.
*
@ -714,8 +736,9 @@ public:
* @since 12
*/
IMF_API int32_t ReceivePrivateCommand(
const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
const std::unordered_map<std::string, PrivateDataValue> &privateCommand, bool isSystemCmd = false) override;
int32_t NotifyIsShowSysPanel(bool isShow);
void OnConnectCmdReady(sptr<IRemoteObject> agentObject);
private:
InputMethodController();
~InputMethodController();
@ -740,6 +763,10 @@ private:
void SetAgent(sptr<IRemoteObject> &agentObject);
std::shared_ptr<IInputMethodAgent> GetAgent();
void PrintLogIfAceTimeout(int64_t start);
void SetSystemCmdListener(sptr<OnSystemCmdListener> listener);
std::shared_ptr<IInputMethodAgent> GetSystemCmdAgent();
sptr<OnSystemCmdListener> GetSystemCmdListener();
void ClearSystemCmdAgent();
std::shared_ptr<ControllerListener> controllerListener_;
std::mutex abilityLock_;
@ -750,8 +777,15 @@ private:
std::shared_ptr<IInputMethodAgent> agent_ = nullptr;
std::mutex textListenerLock_;
sptr<OnTextChangedListener> textListener_ = nullptr;
std::mutex systemCmdListenerLock_;
sptr<OnSystemCmdListener> systemCmdListener_ = nullptr;
std::atomic_bool isDiedAttached_{ false };
std::mutex systemAgentLock_;
sptr<IRemoteObject> systemAgentObject_ = nullptr;
std::shared_ptr<IInputMethodAgent> systemAgent_ = nullptr;
std::atomic_bool isSystemCmdConnect_{ false };
std::mutex cursorInfoMutex_;
CursorInfo cursorInfo_;

View File

@ -106,6 +106,7 @@ enum {
ERROR_PANEL_NOT_FOUND = 36,
ERROR_WINDOW_MANAGER = 37,
ERROR_GET_TEXT_CONFIG = 38,
ERROR_CMD_LISTENER_ERROR = 39,
};
}; // namespace ErrorCode

View File

@ -27,6 +27,7 @@
#include "i_input_client.h"
#include "i_input_data_channel.h"
#include "i_input_method_core.h"
#include "i_system_cmd_channel.h"
#include "input_attribute.h"
#include "input_client_info.h"
#include "input_method_property.h"
@ -73,6 +74,7 @@ public:
virtual int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) = 0;
virtual int32_t GetSecurityMode(int32_t &security) = 0;
virtual int32_t IsDefaultIme() = 0;
virtual int32_t ConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) = 0;
// Deprecated because of no permission check, and keep for compatibility
virtual int32_t HideCurrentInputDeprecated() = 0;

View File

@ -82,7 +82,7 @@ public:
int32_t ExitCurrentInputType() override;
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown) override;
int32_t GetSecurityMode(int32_t &security) override;
int32_t ConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent) override;
// Deprecated because of no permission check, kept for compatibility
int32_t HideCurrentInputDeprecated() override;
int32_t ShowCurrentInputDeprecated() override;

View File

@ -94,6 +94,8 @@ private:
int32_t IsDefaultImeOnRemote(MessageParcel &data, MessageParcel &reply);
int32_t ConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply);
using RequestHandler = int32_t (InputMethodSystemAbilityStub::*)(MessageParcel &, MessageParcel &);
static inline const std::unordered_map<int32_t, RequestHandler> HANDLERS = {
{ static_cast<uint32_t>(InputMethodInterfaceCode::START_INPUT),
@ -158,6 +160,8 @@ private:
&InputMethodSystemAbilityStub::GetSecurityModeOnRemote },
{ static_cast<uint32_t>(InputMethodInterfaceCode::IS_DEFAULT_IME),
&InputMethodSystemAbilityStub::IsDefaultImeOnRemote },
{ static_cast<uint32_t>(InputMethodInterfaceCode::CONNECT_SYSTEM_CMD),
&InputMethodSystemAbilityStub::ConnectSystemCmdOnRemote },
};
};
} // namespace OHOS::MiscServices

View File

@ -51,6 +51,7 @@ enum class InputMethodInterfaceCode {
IS_PANEL_SHOWN,
GET_SECURITY_MODE,
IS_DEFAULT_IME,
CONNECT_SYSTEM_CMD,
IMS_CMD_LAST,
};
} // namespace MiscServices

View File

@ -30,6 +30,7 @@
#include "global.h"
#include "i_input_client.h"
#include "i_input_control_channel.h"
#include "i_system_cmd_channel.h"
#include "i_input_data_channel.h"
#include "i_input_method_agent.h"
#include "i_input_method_core.h"
@ -104,6 +105,7 @@ public:
int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown);
bool CheckSecurityMode();
bool IsWmsReady();
int32_t OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent);
private:
struct ResetManager {

View File

@ -1179,7 +1179,19 @@ bool InputMethodSystemAbility::IsStartInputTypePermitted()
if (identityChecker_->IsBundleNameValid(tokenId, defaultIme->prop.name)) {
return true;
}
if (identityChecker_->IsSystemApp(tokenId)) {
return true;
}
return identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId) && userSession_->IsBoundToClient();
}
int32_t InputMethodSystemAbility::ConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent)
{
if (!identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID())) {
IMSA_HILOGE("not system app");
return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION;
}
return userSession_->OnConnectSystemCmd(channel, agent);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -19,6 +19,7 @@
#include "element_name.h"
#include "input_client_proxy.h"
#include "system_cmd_channel_proxy.h"
#include "input_data_channel_proxy.h"
#include "input_method_agent_proxy.h"
#include "input_method_core_proxy.h"
@ -348,5 +349,18 @@ int32_t InputMethodSystemAbilityStub::IsDefaultImeOnRemote(MessageParcel &data,
{
return ITypesUtil::Marshal(reply, IsDefaultIme()) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
}
int32_t InputMethodSystemAbilityStub::ConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply)
{
auto systemCmdStub = data.ReadRemoteObject();
if (systemCmdStub == nullptr) {
IMSA_HILOGE("systemCmdStub is nullptr");
return ErrorCode::ERROR_EX_PARCELABLE;
}
sptr<IRemoteObject> agent = nullptr;
int32_t ret = ConnectSystemCmd(iface_cast<ISystemCmdChannel>(systemCmdStub), agent);
return reply.WriteInt32(ret) && reply.WriteRemoteObject(agent) ? ErrorCode::NO_ERROR
: ErrorCode::ERROR_EX_PARCELABLE;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -1149,5 +1149,22 @@ int32_t PerUserSession::RequestIme(const std::shared_ptr<ImeData> &data, Request
data->freezeMgr->AfterIpc(type, ret == ErrorCode::NO_ERROR);
return ret;
}
int32_t PerUserSession::OnConnectSystemCmd(const sptr<ISystemCmdChannel> &channel, sptr<IRemoteObject> &agent)
{
auto data = GetImeData(ImeType::IME);
if (data == nullptr) {
IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = RequestIme(data, RequestType::NORMAL,
[&data, &channel, &agent] { return data->core->OnConnectSystemCmd(channel, agent); });
IMSA_HILOGD("on connect systemCmd, ret: %{public}d", ret);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("bind failed, ret: %{public}d", ret);
return ret;
}
return ErrorCode::NO_ERROR;
}
} // namespace MiscServices
} // namespace OHOS