modify api

Signed-off-by: zhaolinglan <zhaolinglan@huawei.com>
This commit is contained in:
zhaolinglan 2024-03-13 18:48:19 +08:00
parent 6db8855e48
commit 9a74bc479f
9 changed files with 176 additions and 85 deletions

View File

@ -47,7 +47,8 @@
"hitrace",
"graphic_2d",
"config_policy",
"data_share"
"data_share",
"resource_schedule_service"
],
"third_party": [
"cJSON"

View File

@ -13,7 +13,8 @@
"gid" : ["inputmethod", "shell"],
"permission" : [
"ohos.permission.INPUT_MONITORING",
"ohos.permission.GET_BUNDLE_INFO"
"ohos.permission.GET_BUNDLE_INFO",
"ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT"
],
"permission_acls" : ["ohos.permission.INPUT_MONITORING"],
"caps" : [],

View File

@ -51,6 +51,7 @@ ohos_shared_library("inputmethod_service") {
"${inputmethod_path}/services/adapter/wms_connection_monitor/src/wms_connection_monitor_manager.cpp",
"${inputmethod_path}/services/adapter/wms_connection_monitor/src/wms_connection_observer.cpp",
"${inputmethod_path}/services/identity_checker/src/identity_checker_impl.cpp",
"src/freeze_manager.cpp",
"src/global.cpp",
"src/im_common_event_manager.cpp",
"src/ime_aging_manager.cpp",
@ -101,6 +102,7 @@ ohos_shared_library("inputmethod_service") {
"input:libmmi-client",
"ipc:ipc_single",
"os_account:os_account_innerkits",
"resource_schedule_service:ressched_client",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
"window_manager:libwm",

View File

@ -0,0 +1,41 @@
/*
* 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 INPUTMETHOD_IMF_FREEZE_MANAGER_H
#define INPUTMETHOD_IMF_FREEZE_MANAGER_H
#include <atomic>
#include <mutex>
namespace OHOS {
namespace MiscServices {
enum class RequestType : int32_t { NORMAL = 0, START_INPUT, STOP_INPUT, REQUEST_HIDE };
class FreezeManager {
public:
explicit FreezeManager(pid_t pid) : pid_(pid)
{
}
bool BeforeIPC(RequestType type);
void AfterIPC(RequestType type, bool IsIPCSuccess);
private:
void SetState(bool freezable);
std::atomic_bool imeInUse_{ false };
std::atomic_bool freezable_{ true };
pid_t pid_;
};
} // namespace MiscServices
} // namespace OHOS
#endif //INPUTMETHOD_IMF_FREEZE_MANAGER_H

View File

@ -26,6 +26,7 @@
#include "block_data.h"
#include "event_handler.h"
#include "event_status_manager.h"
#include "freeze_manager.h"
#include "global.h"
#include "i_input_client.h"
#include "i_input_control_channel.h"
@ -53,8 +54,11 @@ struct ImeData {
sptr<IInputMethodCore> core{ nullptr };
sptr<IInputMethodAgent> agent{ nullptr };
sptr<InputDeathRecipient> deathRecipient{ nullptr };
ImeData(sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent, sptr<InputDeathRecipient> deathRecipient)
: core(std::move(core)), agent(std::move(agent)), deathRecipient(std::move(deathRecipient))
std::shared_ptr<FreezeManager> freezeMgr;
ImeData(sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent, sptr<InputDeathRecipient> deathRecipient,
pid_t imePid)
: core(std::move(core)), agent(std::move(agent)), deathRecipient(std::move(deathRecipient)),
freezeMgr(std::make_shared<FreezeManager>(imePid))
{
}
};
@ -79,7 +83,7 @@ public:
int32_t OnHideInput(sptr<IInputClient> client);
int32_t OnRequestShowInput();
int32_t OnRequestHideInput();
void OnSecurityChange(int32_t &security);
void OnSecurityChange(int32_t security);
void OnHideSoftKeyBoardSelf();
void NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty);
int32_t SwitchSubtype(const SubProperty &subProperty);
@ -94,8 +98,6 @@ public:
bool StartCurrentIme(int32_t userId, bool isRetry);
void StopCurrentIme();
bool StartInputService(const std::shared_ptr<ImeNativeCfg> &ime, bool isRetry);
bool ActivateIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isRetry);
void DeactivateIme(const std::string &bundleName, const std::string &subName);
bool IsProxyImeEnable();
bool IsBoundToClient();
int32_t ExitCurrentInputType();
@ -122,6 +124,7 @@ private:
sptr<IInputClient> currentClient_; // the current input client
std::mutex resetLock;
ResetManager manager;
using IPCExec = std::function<int32_t()>;
PerUserSession(const PerUserSession &);
PerUserSession &operator=(const PerUserSession &);
@ -141,7 +144,7 @@ private:
const std::unordered_map<UpdateFlag, std::variant<bool, uint32_t, ImeType, ClientState, TextTotalConfig>>
&updateInfos);
int32_t AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent);
int32_t AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent, pid_t pid);
void RemoveImeData(ImeType type, bool isImeDied);
int32_t RemoveIme(const sptr<IInputMethodCore> &core, ImeType type);
std::shared_ptr<ImeData> GetImeData(ImeType type);
@ -175,6 +178,7 @@ private:
bool IsBindImeInProxyImeBind(ImeType bindImeType);
bool IsImeBindChanged(ImeType bindImeType);
std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> GetClientMap();
int32_t RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IPCExec &exec);
BlockData<bool> isImeStarted_{ MAX_IME_START_TIME, false };
std::mutex imeDataLock_;

View File

@ -0,0 +1,75 @@
/*
* 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 "freeze_manager.h"
#include "ability_manager_client.h"
#include "element_name.h"
#include "global.h"
#include "res_sched_client.h"
#include "res_type.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace MiscServices {
const std::string INPUT_METHOD_SERVICE_SA_NAME = "inputmethod_service";
bool FreezeManager::BeforeIPC(RequestType type)
{
if (type == RequestType::REQUEST_HIDE && !imeInUse_.load()) {
return false;
}
if (type == RequestType::START_INPUT) {
imeInUse_.store(true);
}
SetState(false);
return true;
}
void FreezeManager::AfterIPC(RequestType type, bool IsIPCSuccess)
{
if (type == RequestType::START_INPUT) {
imeInUse_.store(IsIPCSuccess);
SetState(!IsIPCSuccess);
return;
}
if (type == RequestType::STOP_INPUT) {
imeInUse_.store(false);
}
SetState(true);
}
void FreezeManager::SetState(bool freezable)
{
if (freezable_.load() == freezable) {
IMSA_HILOGD("already");
return;
}
if (freezable && imeInUse_.load()) {
IMSA_HILOGD("ime in use");
return;
}
uint32_t type = ResourceSchedule::ResType::RES_TYPE_SA_CONTROL_APP_EVENT;
int64_t status = freezable ? ResourceSchedule::ResType::SaControlAppStatus::SA_STOP_APP
: ResourceSchedule::ResType::SaControlAppStatus::SA_START_APP;
std::unordered_map<std::string, std::string> payload;
payload["saId"] = std::to_string(INPUT_METHOD_SYSTEM_ABILITY_ID);
payload["saName"] = INPUT_METHOD_SERVICE_SA_NAME;
payload["extensionType"] = std::to_string(static_cast<int32_t>(AppExecFwk::ExtensionAbilityType::INPUTMETHOD));
payload["pid"] = std::to_string(pid_);
ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, status, payload);
freezable_.store(freezable);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -164,7 +164,7 @@ int32_t PerUserSession::HideKeyboard(const sptr<IInputClient> &currentClient)
IMSA_HILOGE("ime: %{public}d is not exist", clientInfo->bindImeType);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = data->core->HideKeyboard();
auto ret = RequestIme(data, RequestType::NORMAL, [&data] { return data->core->HideKeyboard(); });
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to hide keyboard, ret: %{public}d", ret);
return ErrorCode::ERROR_KBD_HIDE_FAILED;
@ -188,7 +188,7 @@ int32_t PerUserSession::ShowKeyboard(const sptr<IInputClient> &currentClient)
IMSA_HILOGE("ime: %{public}d is not exist", clientInfo->bindImeType);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = data->core->ShowKeyboard();
auto ret = RequestIme(data, RequestType::NORMAL, [&data] { return data->core->ShowKeyboard(); });
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to show keyboard, ret: %{public}d", ret);
return ErrorCode::ERROR_KBD_SHOW_FAILED;
@ -324,7 +324,7 @@ int32_t PerUserSession::OnRequestShowInput()
IMSA_HILOGE("ime: %{public}d doesn't exist", ImeType::IME);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = data->core->ShowKeyboard();
auto ret = RequestIme(data, RequestType::NORMAL, [&data] { return data->core->ShowKeyboard(); });
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to show keyboard, ret: %{public}d", ret);
return ErrorCode::ERROR_KBD_SHOW_FAILED;
@ -344,7 +344,7 @@ int32_t PerUserSession::OnRequestHideInput()
IMSA_HILOGE("ime: %{public}d doesn't exist", ImeType::IME);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = data->core->HideKeyboard();
auto ret = RequestIme(data, RequestType::REQUEST_HIDE, [&data] { return data->core->HideKeyboard(); });
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("failed to hide keyboard, ret: %{public}d", ret);
return ErrorCode::ERROR_KBD_HIDE_FAILED;
@ -451,7 +451,10 @@ void PerUserSession::DeactivateClient(const sptr<IInputClient> &client)
IMSA_HILOGE("ime %{public}d doesn't exist", clientInfo->bindImeType);
return;
}
data->core->OnClientInactive(clientInfo->channel);
RequestIme(data, RequestType::NORMAL, [&data, &clientInfo] {
data->core->OnClientInactive(clientInfo->channel);
return ErrorCode::NO_ERROR;
});
}
bool PerUserSession::IsProxyImeEnable()
@ -506,7 +509,8 @@ int32_t PerUserSession::BindClientWithIme(
if (data == nullptr) {
return ErrorCode::ERROR_IME_NOT_STARTED;
}
auto ret = data->core->StartInput(*clientInfo, isBindFromClient);
auto ret = RequestIme(data, RequestType::START_INPUT,
[&data, &clientInfo, isBindFromClient]() { return data->core->StartInput(*clientInfo, isBindFromClient); });
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("start input failed, ret: %{public}d", ret);
return ErrorCode::ERROR_IME_START_INPUT_FAILED;
@ -550,18 +554,20 @@ void PerUserSession::StopImeInput(ImeType currentType, const sptr<IInputDataChan
if (data == nullptr) {
return;
}
auto ret = data->core->StopInput(currentChannel);
auto ret = RequestIme(
data, RequestType::STOP_INPUT, [&data, &currentChannel]() { return data->core->StopInput(currentChannel); });
IMSA_HILOGI("stop ime input, ret: %{public}d", ret);
}
void PerUserSession::OnSecurityChange(int32_t &security)
void PerUserSession::OnSecurityChange(int32_t security)
{
auto data = GetImeData(ImeType::IME);
if (data == nullptr) {
IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME);
return;
}
auto ret = data->core->OnSecurityChange(security);
auto ret =
RequestIme(data, RequestType::NORMAL, [&data, security] { return data->core->OnSecurityChange(security); });
IMSA_HILOGD("on security change, ret: %{public}d", ret);
}
@ -569,7 +575,7 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr<IInputMethodCore> &core, co
{
IMSA_HILOGI("run in");
auto imeType = ImeType::IME;
auto ret = AddImeData(imeType, core, agent);
auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid());
if (ret != ErrorCode::NO_ERROR) {
return ret;
}
@ -590,7 +596,7 @@ int32_t PerUserSession::OnRegisterProxyIme(const sptr<IInputMethodCore> &core, c
{
IMSA_HILOGD("run in");
auto imeType = ImeType::PROXY_IME;
auto ret = AddImeData(imeType, core, agent);
auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid());
if (ret != ErrorCode::NO_ERROR) {
return ret;
}
@ -643,7 +649,8 @@ int32_t PerUserSession::InitInputControlChannel()
IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
return data->core->InitInputControlChannel(inputControlChannel);
return RequestIme(data, RequestType::NORMAL,
[&data, &inputControlChannel] { return data->core->InitInputControlChannel(inputControlChannel); });
}
bool PerUserSession::IsRestartIme()
@ -748,7 +755,7 @@ void PerUserSession::NotifyImeChangeToClients(const Property &property, const Su
}
}
int32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent)
int32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sptr<IInputMethodAgent> agent, pid_t pid)
{
if (core == nullptr || agent == nullptr) {
IMSA_HILOGE("core or agent is nullptr");
@ -766,7 +773,7 @@ int32_t PerUserSession::AddImeData(ImeType type, sptr<IInputMethodCore> core, sp
return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED;
}
std::lock_guard<std::mutex> lock(imeDataLock_);
imeData_.insert_or_assign(type, std::make_shared<ImeData>(core, agent, deathRecipient));
imeData_.insert_or_assign(type, std::make_shared<ImeData>(core, agent, deathRecipient, pid));
return ErrorCode::NO_ERROR;
}
@ -903,64 +910,10 @@ void PerUserSession::StopCurrentIme()
if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
StopClientInput(client);
}
data->core->StopInputService(true);
}
bool PerUserSession::ActivateIme(const std::shared_ptr<ImeNativeCfg> &ime, bool isRetry)
{
if (ime == nullptr) {
IMSA_HILOGE("target ime is nullptr");
return false;
}
auto cacheData = ImeAgingManager::GetInstance().Pop(ime->bundleName);
if (cacheData == nullptr) {
IMSA_HILOGD("miss the ime cache");
return StartInputService(ime, isRetry);
}
IMSA_HILOGI("start the cached ime");
auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, ime->bundleName, ime->subName);
if (info == nullptr) {
IMSA_HILOGE("failed to get ime info");
return false;
}
if (!info->isNewIme && StartInputService(ime, false)) {
IMSA_HILOGD("old ime, need to start ability");
return true;
}
if (cacheData->core != nullptr) {
IMSA_HILOGD("inform subtype: %{public}s", ime->subName.c_str());
cacheData->core->SetSubtype(info->subProp);
}
return OnSetCoreAndAgent(cacheData->core, cacheData->agent) == ErrorCode::NO_ERROR;
}
void PerUserSession::DeactivateIme(const std::string &bundleName, const std::string &subName)
{
auto data = GetImeData(ImeType::IME);
if (data == nullptr) {
IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME);
return;
}
auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName);
if ((info == nullptr || !info->isNewIme) && data->core != nullptr) {
IMSA_HILOGI("stop ime: %{public}s/%{public}s", bundleName.c_str(), subName.c_str());
RequestIme(data, RequestType::NORMAL, [&data] {
data->core->StopInputService(true);
RemoveImeData(ImeType::IME, true);
return;
}
IMSA_HILOGI("deactivate ime: %{public}s/%{public}s", bundleName.c_str(), subName.c_str());
if (data->deathRecipient != nullptr) {
data->deathRecipient->SetDeathRecipient(
[this, bundleName](const wptr<IRemoteObject> &) { ImeAgingManager::GetInstance().Pop(bundleName); });
}
ImeAgingManager::GetInstance().Push(bundleName, data);
auto client = GetCurrentClient();
auto clientInfo = client != nullptr ? GetClientInfo(client->AsObject()) : nullptr;
if (clientInfo != nullptr && clientInfo->bindImeType == ImeType::IME) {
UnBindClientWithIme(clientInfo, false);
}
RemoveImeData(ImeType::IME, false);
return ErrorCode::NO_ERROR;
});
}
bool PerUserSession::StartInputService(const std::shared_ptr<ImeNativeCfg> &ime, bool isRetry)
@ -1108,7 +1061,7 @@ int32_t PerUserSession::SwitchSubtype(const SubProperty &subProperty)
IMSA_HILOGE("ime: %{public}d is not exist", ImeType::IME);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
return data->core->SetSubtype(subProperty);
return RequestIme(data, RequestType::NORMAL, [&data, &subProperty] { return data->core->SetSubtype(subProperty); });
}
bool PerUserSession::IsBoundToClient()
@ -1153,7 +1106,7 @@ int32_t PerUserSession::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
IMSA_HILOGE("ime not started");
return ErrorCode::ERROR_IME_NOT_STARTED;
}
return ime->core->IsPanelShown(panelInfo, isShown);
return RequestIme(ime, RequestType::NORMAL, [&ime, &panelInfo, &isShown] { return ime->core->IsPanelShown(panelInfo, isShown); });
}
bool PerUserSession::CheckSecurityMode()
@ -1171,5 +1124,23 @@ std::map<sptr<IRemoteObject>, std::shared_ptr<InputClientInfo>> PerUserSession::
std::lock_guard<std::recursive_mutex> lock(mtx);
return mapClients_;
}
int32_t PerUserSession::RequestIme(const std::shared_ptr<ImeData> &data, RequestType type, const IPCExec &exec)
{
if (IsProxyImeEnable()) {
return exec();
}
if (data == nullptr || data->freezeMgr == nullptr) {
IMSA_HILOGE("data nullptr");
return ErrorCode::NO_ERROR;
}
if (!data->freezeMgr->BeforeIPC(type)) {
IMSA_HILOGD("no need to request");
return ErrorCode::NO_ERROR;
}
auto ret = exec();
data->freezeMgr->AfterIPC(type, ret == ErrorCode::NO_ERROR);
return ret;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -109,7 +109,6 @@ bool FuzzPerUserSession(const uint8_t *rawData, size_t size)
userSessions->OnHideCurrentInput();
userSessions->OnHideInput(client);
userSessions->OnReleaseInput(client);
userSessions->DeactivateIme("", "");
return true;
}
} // namespace OHOS

View File

@ -264,7 +264,6 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionCoreOrAgentNullptr, TestSiz
EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOUND);
ret = userSession->InitInputControlChannel();
EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED);
userSession->DeactivateIme("", "");
userSession->StopCurrentIme();
ret = userSession->SwitchSubtype({});
EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED);
@ -318,8 +317,6 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr001, TestSi
EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER);
auto client = userSession->GetClientInfo(nullptr);
EXPECT_EQ(client, nullptr);
bool result = userSession->ActivateIme(nullptr, true);
EXPECT_FALSE(result);
}
/**