mirror of
https://github.com/openharmony/miscservices_inputmethod.git
synced 2026-07-18 17:24:37 -04:00
add switch input fuction
Signed-off-by: gaoxiang <gaoxiang75@huawei.com>
This commit is contained in:
@@ -136,6 +136,7 @@ namespace ErrorCode {
|
||||
ERROR_NO_NEXT_IME, // no next ime is available
|
||||
ERROR_CLIENTWINDOW_NOT_FOCUSED, // the input client window is not focused
|
||||
ERROR_CLIENT_NOT_WINDOW, // the input client is not from a valid window
|
||||
ERROR_IME_PROPERTY_MARSHALL, // failed to marshall the ime property
|
||||
// error from ime
|
||||
ERROR_REMOTE_IME_DIED, // remote input method service died abnormally
|
||||
ERROR_RESTART_IME_FAILED, // failed to restart input method service
|
||||
@@ -154,15 +155,15 @@ static constexpr HiviewDFX::HiLogLabel g_SMALL_SERVICES_LABEL = {
|
||||
};
|
||||
|
||||
#define IMSA_HILOGD(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Debug(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
|
||||
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
"line: %{public}d, function: %{public}s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
#define IMSA_HILOGE(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Error(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
|
||||
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
"line: %{public}d, function: %{public}s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
#define IMSA_HILOGF(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Fatal(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
|
||||
"line: %d, function: %s," fmt, __LINE__FILE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
"line: %{public}d, function: %{public}s," fmt, __LINE__FILE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
#define IMSA_HILOGI(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Info(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
|
||||
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
"line: %{public}d, function: %{public}s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
#define IMSA_HILOGW(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Warn(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
|
||||
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
"line: %{public}d, function: %{public}s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
|
||||
}
|
||||
}
|
||||
#endif // SERVICES_INCLUDE_GLOBAL_H
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace MiscServices {
|
||||
LIST_KEYBOARD_TYPE,
|
||||
SET_CORE_AND_AGENT,
|
||||
DISPLAY_OPTIONAL_INPUT_METHOD,
|
||||
SWITCH_INPUT_METHOD,
|
||||
};
|
||||
|
||||
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodSystemAbility");
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace MiscServices {
|
||||
void WorkThread();
|
||||
PerUserSetting *GetUserSetting(int32_t userId);
|
||||
PerUserSession *GetUserSession(int32_t userId);
|
||||
void StartInputService(std::string imeId);
|
||||
bool StartInputService(std::string imeId);
|
||||
void StopInputService(std::string imeId);
|
||||
int32_t OnUserStarted(const Message *msg);
|
||||
int32_t OnUserStopped(const Message *msg);
|
||||
@@ -90,6 +90,7 @@ namespace MiscServices {
|
||||
static sptr<AAFwk::IAbilityManager> GetAbilityManagerService();
|
||||
OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> GetBundleMgr();
|
||||
void StartUserIdListener();
|
||||
int32_t OnSwitchInputMethod(int32_t userId, InputMethodProperty *target);
|
||||
|
||||
ServiceRunningState state_;
|
||||
void InitServiceHandler();
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace MiscServices {
|
||||
void HideCurrentInput(MessageParcel& data) override;
|
||||
void displayOptionalInputMethod(MessageParcel& data) override;
|
||||
virtual int32_t listInputMethodByUserId(int32_t userId, std::vector<InputMethodProperty*> *properties) = 0;
|
||||
int32_t SwitchInputMethod(MessageParcel &data, MessageParcel &reply);
|
||||
|
||||
protected:
|
||||
int32_t getUserId(int32_t uid);
|
||||
|
||||
@@ -25,7 +25,9 @@ namespace MiscServices {
|
||||
public:
|
||||
int32_t msgId_; // message id
|
||||
MessageParcel *msgContent_ = nullptr; // message content
|
||||
MessageParcel *msgReply_ = nullptr; // message reply
|
||||
Message(int32_t msgId, MessageParcel *msgContent);
|
||||
Message(int32_t msgId, MessageParcel *msgContent, MessageParcel *msgReply);
|
||||
explicit Message(const Message& msg);
|
||||
Message& operator =(const Message& msg);
|
||||
~Message();
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace MessageID {
|
||||
MSG_ID_RELEASE_INPUT, // release input
|
||||
MSG_ID_SET_CORE_AND_AGENT,
|
||||
MSG_HIDE_CURRENT_INPUT,
|
||||
MSG_ID_SWITCH_INPUT_METHOD, // switch input method
|
||||
|
||||
// the request to handle the condition that the remote object died
|
||||
MSG_ID_CLIENT_DIED, // input client died
|
||||
|
||||
@@ -198,7 +198,7 @@ namespace MiscServices {
|
||||
serviceHandler_->PostTask(callback, INIT_INTERVAL);
|
||||
}
|
||||
|
||||
void InputMethodSystemAbility::StartInputService(std::string imeId)
|
||||
bool InputMethodSystemAbility::StartInputService(std::string imeId)
|
||||
{
|
||||
IMSA_HILOGE("InputMethodSystemAbility::StartInputService() ime:%{public}s", imeId.c_str());
|
||||
|
||||
@@ -236,6 +236,7 @@ namespace MiscServices {
|
||||
auto callback = [this, imeId]() { StartInputService(imeId); };
|
||||
serviceHandler_->PostTask(callback, INIT_INTERVAL);
|
||||
}
|
||||
return isStartSuccess;
|
||||
}
|
||||
|
||||
void InputMethodSystemAbility::StopInputService(std::string imeId)
|
||||
@@ -562,6 +563,14 @@ namespace MiscServices {
|
||||
msg = nullptr;
|
||||
return;
|
||||
}
|
||||
case MSG_ID_SWITCH_INPUT_METHOD: {
|
||||
MessageParcel *data = msg->msgContent_;
|
||||
int32_t userId = data->ReadInt32();
|
||||
InputMethodProperty *target = InputMethodProperty::Unmarshalling(*data);
|
||||
auto ret = OnSwitchInputMethod(userId, target);
|
||||
msg->msgReply_->WriteInt32(ret);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -890,6 +899,49 @@ namespace MiscServices {
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodSystemAbility::OnSwitchInputMethod(int32_t userId, InputMethodProperty *target)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod");
|
||||
std::vector<InputMethodProperty *> properties;
|
||||
listInputMethodByUserId(userId, &properties);
|
||||
if (!properties.size()) {
|
||||
IMSA_HILOGE("InputMethodSystemAbility::OnSwitchInputMethod has no ime");
|
||||
return ErrorCode::ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
bool isTargetFound = false;
|
||||
for (auto it = properties.begin(); it < properties.end(); ++it) {
|
||||
InputMethodProperty *temp = (InputMethodProperty *)*it;
|
||||
if (temp->mPackageName == target->mPackageName) {
|
||||
*target = *temp;
|
||||
isTargetFound = true;
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod target is found in installed packages!");
|
||||
}
|
||||
delete temp;
|
||||
}
|
||||
if (!isTargetFound) {
|
||||
IMSA_HILOGE("InputMethodSystemAbility::OnSwitchInputMethod target is not an installed package !");
|
||||
return ErrorCode::ERROR_NOT_IME_PACKAGE;
|
||||
}
|
||||
|
||||
std::string defaultIme = ParaHandle::GetDefaultIme(userId_);
|
||||
std::string targetIme = "";
|
||||
std::string imeId = Str16ToStr8(target->mPackageName) + "/" + Str16ToStr8(target->mAbilityName);
|
||||
targetIme += imeId;
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod DefaultIme : %{public}s, TargetIme : %{public}s",
|
||||
defaultIme.c_str(), targetIme.c_str());
|
||||
if (defaultIme != targetIme) {
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod DefaultIme is not target! Start Switching IME !");
|
||||
StopInputService(defaultIme);
|
||||
if (!StartInputService(targetIme)) {
|
||||
return ErrorCode::ERROR_IME_START_FAILED;
|
||||
}
|
||||
ParaHandle::SetDefaultIme(userId_, targetIme);
|
||||
} else {
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod DefaultIme and TargetIme are the same one!");
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
void InputMethodSystemAbility::OnDisplayOptionalInputMethod(int32_t userId)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSystemAbility::OnDisplayOptionalInputMethod");
|
||||
|
||||
@@ -170,6 +170,10 @@ namespace MiscServices {
|
||||
reply.WriteInt32(NO_ERROR);
|
||||
break;
|
||||
}
|
||||
case SWITCH_INPUT_METHOD: {
|
||||
SwitchInputMethod(data, reply);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return BRemoteObject::OnRemoteRequest(code, data, reply, option);
|
||||
}
|
||||
@@ -304,6 +308,27 @@ namespace MiscServices {
|
||||
MessageHandler::Instance()->SendMessage(msg);
|
||||
}
|
||||
|
||||
int32_t InputMethodSystemAbilityStub::SwitchInputMethod(MessageParcel &data, MessageParcel &reply)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSystemAbilityStub::switchInputMethod");
|
||||
int32_t uid = IPCSkeleton::GetCallingUid();
|
||||
int32_t userId = getUserId(uid);
|
||||
|
||||
MessageParcel *parcel = new MessageParcel();
|
||||
InputMethodProperty *target = InputMethodProperty::Unmarshalling(data);
|
||||
parcel->WriteInt32(userId);
|
||||
if (!target->Marshalling(*parcel)) {
|
||||
IMSA_HILOGE("InputMethodSystemAbilityStub::switchInputMethod Failed to marshall the target! ");
|
||||
delete target;
|
||||
delete parcel;
|
||||
return ErrorCode::ERROR_IME_PROPERTY_MARSHALL;
|
||||
}
|
||||
delete target;
|
||||
Message *msg = new Message(MSG_ID_SWITCH_INPUT_METHOD, parcel, &reply);
|
||||
MessageHandler::Instance()->SendMessage(msg);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
/*! Get user id from uid
|
||||
\param uid the uid from which the remote call is
|
||||
\return return user id of the remote caller
|
||||
|
||||
@@ -30,6 +30,10 @@ namespace MiscServices {
|
||||
}
|
||||
}
|
||||
|
||||
Message::Message(int32_t msgId, MessageParcel *msgContent, MessageParcel *msgReply) : Message(msgId, msgContent)
|
||||
{
|
||||
msgReply_ = msgReply;
|
||||
}
|
||||
/*! Constructor
|
||||
\param msg a source message
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 <gtest/gtest.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "global.h"
|
||||
#include "input_method_controller.h"
|
||||
#include "input_method_property.h"
|
||||
#include "message_handler.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class InputMethodSwitchTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
};
|
||||
|
||||
void InputMethodSwitchTest::SetUpTestCase(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSwitchTest::SetUpTestCase");
|
||||
}
|
||||
|
||||
void InputMethodSwitchTest::TearDownTestCase(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSwitchTest::TearDownTestCase");
|
||||
}
|
||||
|
||||
void InputMethodSwitchTest::SetUp(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSwitchTest::SetUp");
|
||||
}
|
||||
|
||||
void InputMethodSwitchTest::TearDown(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodSwitchTest::TearDown");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: intputMethodSwitch_sub_001
|
||||
* @tc.desc: Checkout SwitchInputMethod.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodSwitchTest, intputMethodSwitch_sub_001, TestSize.Level0)
|
||||
{
|
||||
InputMethodProperty *target = new InputMethodProperty();
|
||||
std::string packageName = "com.ohos.inputApp";
|
||||
std::string imeId = "InputDemoService";
|
||||
target->mPackageName = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(packageName);
|
||||
target->mImeId = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(imeId);
|
||||
int32_t ret = InputMethodController::GetInstance()->SwitchInputMethod(target);
|
||||
delete target;
|
||||
EXPECT_TRUE(0 == ret);
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
Reference in New Issue
Block a user