* Copyright (c) 2025 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 <cstdio>
#include <iostream>
#include "accesstoken_kit.h"
#include "global.h"
#include "ime_event_listener.h"
#include "ime_event_monitor_manager.h"
#include "input_method_controller.h"
#include "nativetoken_kit.h"
#include "token_setproc.h"
using namespace std;
using namespace OHOS::Security::AccessToken;
using namespace OHOS::MiscServices;
std::vector<std::shared_ptr<ImeEventListener>> inputStatusChangedListeners_;
std::vector<std::shared_ptr<ImeEventListener>> softKeyboardInfoChangedListeners_;
const int32_t PERMISSION_NUM = 1;
void GrantNativePermission()
{
const char **perms = new const char *[PERMISSION_NUM];
perms[0] = "ohos.permission.MANAGE_SECURE_SETTINGS";
TokenInfoParams infoInstance = {
.dcapsNum = 0,
.permsNum = PERMISSION_NUM,
.aclsNum = 0,
.dcaps = nullptr,
.perms = perms,
.acls = nullptr,
.processName = "imf_imc_inner_test",
.aplStr = "system_core",
};
uint64_t tokenId = GetAccessTokenId(&infoInstance);
int32_t ret = SetSelfTokenID(tokenId);
if (ret == 0) {
IMSA_HILOGI("SetSelfTokenID success!");
} else {
IMSA_HILOGE("SetSelfTokenID fail!");
}
AccessTokenKit::ReloadNativeTokenInfo();
delete[] perms;
}
BoundImeInfo GetSoftKeyboardInfo()
{
auto userId = 100;
BoundImeInfo imeInfo;
auto ret = InputMethodController::GetInstance()->GetSoftKeyboardInfo(userId, imeInfo);
printf("=====GetSoftKeyboardInfo ret/imeInfo:%d/%s.=====\n", ret, imeInfo.ToString().c_str());
return imeInfo;
}
void GetSoftKeyboardWithInvalidUserId()
{
int32_t userId = 1000;
BoundImeInfo imeInfo;
auto ret = InputMethodController::GetInstance()->GetSoftKeyboardInfo(userId, imeInfo);
printf("=====GetSoftKeyboardWithInvalidUserId ret/imeInfo:%d/%s.=====\n", ret, imeInfo.ToString().c_str());
}
class ImeEventListenerImplListener : public ImeEventListener {
public:
void OnInputStart(const InputStartInfo &inputStartInfo) override
{
printf("=====inputStartInfo:%s.=====\n", inputStartInfo.ToString().c_str());
}
void OnInputStop(const InputStopInfo &inputStopInfo) override
{
printf("=====inputStopInfo:%s.=====\n", inputStopInfo.ToString().c_str());
}
void OnSoftKeyboardInfoChanged(
int32_t userId, const BoundImeInfo &oldImeInfo, const BoundImeInfo &newImeInfo) override
{
printf("=====oldInfo/newInfo:%d/%s/%s.=====\n", userId, oldImeInfo.ToString().c_str(),
newImeInfo.ToString().c_str());
auto imeInfo = GetSoftKeyboardInfo();
if (imeInfo == newImeInfo) {
printf("=====get boundImeInfo same with cb.=====\n");
}
}
};
void RegisterSoftKeyboardInfoChangedListener()
{
auto listener = std::make_shared<ImeEventListenerImplListener>();
auto ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(
EVENT_SOFT_KEYBOARD_INFO_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====Register soft keyboard changed changed listener failed:%d.=====\n", ret);
return;
}
softKeyboardInfoChangedListeners_.push_back(listener);
printf("=====Register soft keyboard changed listener succeed, current listener nums:%zu.=====\n",
softKeyboardInfoChangedListeners_.size());
}
void RegisterSameSoftKeyboardInfoChangedListener()
{
if (softKeyboardInfoChangedListeners_.empty()) {
printf("=====has no soft keyboard changed listener.=====\n");
return;
}
auto listener = softKeyboardInfoChangedListeners_.back();
auto ret = ImeEventMonitorManager::GetInstance().RegisterImeEventListener(
EVENT_SOFT_KEYBOARD_INFO_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====Register same soft keyboard changed listener failed:%d.=====\n", ret);
return;
}
printf("=====Register same soft keyboard changed succeed, current listener nums:%zu.=====\n",
softKeyboardInfoChangedListeners_.size());
}
void UnRegisterSoftKeyboardInfoChangedListener()
{
if (softKeyboardInfoChangedListeners_.empty()) {
printf("=====has no soft keyboard listener.=====\n");
return;
}
auto listener = softKeyboardInfoChangedListeners_.back();
auto ret = ImeEventMonitorManager::GetInstance().UnRegisterImeEventListener(
EVENT_SOFT_KEYBOARD_INFO_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====Register soft keyboard changed listener failed:%d.=====\n", ret);
return;
}
softKeyboardInfoChangedListeners_.pop_back();
printf("=====UnRegister soft keyboard changed listener succeed, current listener nums:%zu.=====\n",
softKeyboardInfoChangedListeners_.size());
}
void RegisterInputStatusChangedListener()
{
auto listener = std::make_shared<ImeEventListenerImplListener>();
auto ret =
ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====Register input status changed listener failed:%d.=====\n", ret);
return;
}
inputStatusChangedListeners_.push_back(listener);
printf("=====Register input status changed listener succeed, current listener nums:%zu.=====\n",
inputStatusChangedListeners_.size());
}
void RegisterSameInputStatusChangedListener()
{
if (inputStatusChangedListeners_.empty()) {
printf("=====has no input status changed listener.=====\n");
return;
}
auto listener = inputStatusChangedListeners_.back();
auto ret =
ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====Register same input status changed listener failed:%d.=====\n", ret);
return;
}
printf("=====Register same input status changed succeed, current listener nums:%zu.=====\n",
inputStatusChangedListeners_.size());
}
void UnRegisterInputStatusChangedListener()
{
if (inputStatusChangedListeners_.empty()) {
printf("=====has no listener.=====\n");
return;
}
auto listener = inputStatusChangedListeners_.back();
auto ret =
ImeEventMonitorManager::GetInstance().UnRegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener);
if (ret != ErrorCode::NO_ERROR) {
printf("=====UnRegister input status changed listener failed:%d.=====\n", ret);
return;
}
inputStatusChangedListeners_.pop_back();
printf("=====UnRegister input status changed succeed, current listener nums:%zu.=====\n",
inputStatusChangedListeners_.size());
}
int main()
{
GrantNativePermission();
int32_t input = 0;
while (input != 100) {
printf("=====1:RegisterInputStatusChangedListener 2:RegisterSameInputStatusChangedListener "
"3:UnRegisterInputStatusChangedListener 4.RegisterSoftKeyboardInfoChangedListener, 5. "
"RegisterSameSoftKeyboardInfoChangedListener 6:UnRegisterSoftKeyboardInfoChangedListener "
"7.GetSoftKeyboardInfo 8.GetSoftKeyboardWithInvalidUserId 100.EXIT=====\n");
printf("input: ");
cin >> input;
switch (input) {
case 1:
RegisterInputStatusChangedListener();
break;
case 2:
RegisterSameInputStatusChangedListener();
break;
case 3:
UnRegisterInputStatusChangedListener();
break;
case 4:
RegisterSoftKeyboardInfoChangedListener();
break;
case 5:
RegisterSameSoftKeyboardInfoChangedListener();
break;
case 6:
UnRegisterSoftKeyboardInfoChangedListener();
break;
case 7:
GetSoftKeyboardInfo();
break;
case 8:
GetSoftKeyboardWithInvalidUserId();
break;
case 100:
printf("=====EXIT=====\n");
break;
default:
printf("=====input error!=====\n");
}
}
return 0;
}