add switch input fuction

Signed-off-by: gaoxiang <gaoxiang75@huawei.com>
This commit is contained in:
gaoxiang
2022-07-05 11:26:50 +08:00
parent 2a937f009f
commit 385852d753
10 changed files with 172 additions and 7 deletions
+6 -5
View File
@@ -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);
+2
View File
@@ -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();
+1
View File
@@ -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
+53 -1
View File
@@ -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
+4
View File
@@ -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
*/
+77
View File
@@ -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