初稿形成

Signed-off-by: cy7717 <chenyu301@huawei.com>
This commit is contained in:
cy7717 2023-01-14 09:14:07 +08:00
parent 96010211ba
commit d0ae7cbb32
18 changed files with 464 additions and 190 deletions

View File

@ -1,10 +1,17 @@
{
"jobs" : [{
"name" : "early-boot",
"cmds" : [
"mkdir /data/service/el1/public/imf 0711 inputmethod inputmethod"
]
}
],
"services" : [{
"name" : "inputmethod_service",
"path" : ["/system/bin/sa_main", "/system/profile/inputmethod_service.xml"],
"uid" : "inputmethod",
"gid" : ["inputmethod", "shell"],
"permission" : ["ohos.permission.INPUT_MONITORING"],
"permission" : ["ohos.permission.INPUT_MONITORING", "ohos.permission.MANAGE_USERS permission"],
"caps" : [],
"secon" : "u:r:inputmethod_service:s0"
}

View File

@ -27,7 +27,7 @@
#include "message_parcel.h"
#include "string_ex.h"
#include "system_ability_definition.h"
#include "userImeCfg_manager.h"
//#include "userImeCfg_manager.h"
namespace OHOS {
namespace MiscServices {

View File

@ -45,7 +45,7 @@ ohos_shared_library("inputmethod_service") {
"src/message.cpp",
"src/message_handler.cpp",
"src/peruser_session.cpp",
"src/userImeCfg_manager.cpp",
"src/ime_cfg_manager.cpp",
]
configs = [ ":inputmethod_services_native_config" ]
@ -55,8 +55,8 @@ ohos_shared_library("inputmethod_service") {
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${inputmethod_path}/services/adapter/keyboard:keboard_event_static",
"${inputmethod_path}/services/userImeCfg:userImeCfg_json",
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"${inputmethod_path}/utils:inputmethod_utils",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/etc/para:inputmethod_para",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",

View File

@ -42,13 +42,15 @@ public:
bool UnsubscribeEvent();
class EventSubscriber : public EventFwk::CommonEventSubscriber {
public:
EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo)
: EventFwk::CommonEventSubscriber(subscribeInfo)
{
}
EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo);
void OnReceiveEvent(const EventFwk::CommonEventData &data);
void HandlePackageRemove(const AAFwk::Want &want, const std::string action);
void startUser(int32_t newUserId);
void HandlePackageRemove(const EventFwk::CommonEventData &data);
void startUser(const EventFwk::CommonEventData &data);
void RemoveUser(const EventFwk::CommonEventData &data);
private:
using EventListenerFunc = void (EventSubscriber::*)(const EventFwk::CommonEventData &data);
std::map<std::string, EventListenerFunc> EventManagerFunc_;
};
private:

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2022 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 SERVICES_INCLUDE_USERIMECFG_MANAGER_H
#define SERVICES_INCLUDE_USERIMECFG_MANAGER_H
#include <mutex>
#include <string>
#include <vector>
#include <memory>
#include "third_party/json/include/nlohmann/json.hpp"
struct ImeCfg {
int32_t userId;
std::string currentIme;
};
namespace OHOS {
namespace MiscServices {
class ImeCfgManager {
public:
static ImeCfgManager &GetInstance();
void Init();
void AddImeCfg(const ImeCfg &cfg);
void ModifyImeCfg(const ImeCfg &cfg);
void DeleteImeCfg(int32_t userId);
ImeCfg GetImeCfg(int32_t userId);
private:
bool CreateCfgFile() ;
void ReadCfgFile();
void WriteCfgFile();
inline void from_json(const nlohmann::json &jsonCfg, ImeCfg &cfg)
{
jsonCfg.at("userId").get_to(cfg.userId);
jsonCfg.at("currentIme").get_to(cfg.currentIme);
}
inline void to_json(nlohmann::json &jsonCfg, const ImeCfg &cfg)
{
jsonCfg = nlohmann::json{ { "userId", cfg.userId }, { "currentIme", cfg.currentIme } };
}
void from_json(const nlohmann::json &jsonConfigs, std::vector<ImeCfg> &configs);
void to_json(nlohmann::json &jsonConfigs, const std::vector<ImeCfg> &configs);
std::recursive_mutex imeCfgLock_;
std::vector<ImeCfg> imeConfigs_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_USERIMECFG_MANAGER_H

View File

@ -92,7 +92,7 @@ private:
bool StartInputService(std::string imeId);
void StopInputService(std::string imeId);
int32_t OnUserStarted(const Message *msg);
int32_t OnUserStopped(const Message *msg);
int32_t OnUserRemoved(const Message *msg);
int32_t OnHandleMessage(Message *msg);
int32_t OnPackageRemoved(const Message *msg);
int32_t OnDisplayOptionalInputMethod(int32_t userId);

View File

@ -35,6 +35,7 @@ enum {
MSG_ID_USER_START, // a user started
MSG_ID_USER_STOP, // a user stopped
MSG_ID_USER_UNLOCK, // a user unlocked
MSG_ID_USER_REMOVED, // a user removed
MSG_ID_PACKAGE_ADDED, // a package is installed
MSG_ID_PACKAGE_REMOVED, // a package is removed
MSG_ID_SETTING_CHANGED, // input method setting is changed

View File

@ -98,6 +98,7 @@ public:
void SetCurrentSubProperty(const SubProperty &subProperty);
SubProperty GetCurrentSubProperty();
void UpdateCurrentUserId(int32_t userId);
private:
int userId_; // the id of the user to whom the object is linking

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2022 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 SERVICES_INCLUDE_USERIMECFG_MANAGER_H
#define SERVICES_INCLUDE_USERIMECFG_MANAGER_H
#include <map>
#include <mutex>
#include <string>
#include <unordered_set>
//#include "nlohmann/json.hpp"
#include "refbase.h"
namespace OHOS {
namespace MiscServices {
class UserImeCfgManager: public RefBase {
public:
static sptr<UserImeCfgManager> GetInstance();
void Init();
void AddCurrentIme(int32_t userId, const std::string &currentImeCfg);
void ModifyCurrentIme(int32_t userId, const std::string &currentImeCfg);
void DeleteCurrentIme(int32_t userId);
std::string GetCurrentIme(int32_t userId);
private:
//bool LoadUserImeCfg(const std::string &filePath, nlohmann::json &userImeCfgJson);
static std::mutex instanceLock_;
static sptr<UserImeCfgManager> instance_;
std::map<int32_t, std::string> userCurrentIme_;
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_USERIMECFG_MANAGER_H

View File

@ -30,7 +30,7 @@ namespace MiscServices {
using namespace MessageID;
sptr<ImCommonEventManager> ImCommonEventManager::instance_;
std::mutex ImCommonEventManager::instanceLock_;
using namespace OHOS::EventFwk;
/*! Constructor
*/
ImCommonEventManager::ImCommonEventManager()
@ -59,7 +59,8 @@ bool ImCommonEventManager::SubscribeEvent(const std::string &event)
{
EventFwk::MatchingSkills matchingSkills;
matchingSkills.AddEvent(event);
matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED);
matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills);
@ -120,24 +121,33 @@ bool ImCommonEventManager::UnsubscribeEvent()
return true;
}
ImCommonEventManager::EventSubscriber::EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo)
: EventFwk::CommonEventSubscriber(subscribeInfo)
{
EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_SWITCHED] = &EventSubscriber::startUser;
EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_REMOVED] = &EventSubscriber::HandlePackageRemove;
EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED] = &EventSubscriber::RemoveUser;
}
void ImCommonEventManager::EventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
{
auto want = data.GetWant();
auto const &want = data.GetWant();
std::string action = want.GetAction();
IMSA_HILOGI("ImCommonEventManager::OnReceiveEvent data.GetCode = %{public}u", data.GetCode());
if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
IMSA_HILOGI("ImCommonEventManager::OnReceiveEvent user switched!!!");
startUser(data.GetCode());
} else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
IMSA_HILOGI("ImCommonEventManager::OnReceiveEvent package removed!!!");
HandlePackageRemove(want, action);
IMSA_HILOGI("ImCommonEventManager::action = %{public}s!", action.c_str());
auto iter = EventManagerFunc_.find(action);
if (iter == EventManagerFunc_.end()) {
return;
}
auto EventListenerFunc = iter->second;
if (EventListenerFunc != nullptr) {
(this->*EventListenerFunc)(data);
}
}
void ImCommonEventManager::EventSubscriber::startUser(int newUserId)
void ImCommonEventManager::EventSubscriber::startUser(const CommonEventData &data)
{
IMSA_HILOGI("ImCommonEventManager::startUser 1");
auto newUserId = data.GetCode();
IMSA_HILOGI("ImCommonEventManager::startUser, userId = %{public}d", newUserId);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(newUserId);
@ -147,12 +157,26 @@ void ImCommonEventManager::EventSubscriber::startUser(int newUserId)
IMSA_HILOGI("ImCommonEventManager::startUser 3");
}
void ImCommonEventManager::EventSubscriber::HandlePackageRemove(const AAFwk::Want &want, const std::string action)
void ImCommonEventManager::EventSubscriber::RemoveUser(const CommonEventData &data)
{
auto userId = data.GetCode();
IMSA_HILOGI("ImCommonEventManager::RemoveUser, userId = %{public}d", userId);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId);
Message *msg = new Message(MessageID::MSG_ID_USER_REMOVED, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
void ImCommonEventManager::EventSubscriber::HandlePackageRemove(const CommonEventData &data)
{
auto const &want = data.GetWant();
std::string action = want.GetAction();
auto element = want.GetElement();
std::string bundleName = element.GetBundleName();
int32_t userId = want.GetIntParam("userId", 0);
IMSA_HILOGD("bundleName = %{public}s, userId = %{public}d", bundleName.c_str(), userId);
IMSA_HILOGD("ImCommonEventManager::HandlePackageRemove, bundleName = %{public}s, userId = %{public}d",
bundleName.c_str(), userId);
MessageParcel *parcel = new MessageParcel();
if (!ITypesUtil::Marshal(*parcel, userId, bundleName)) {
IMSA_HILOGE("Failed to write message parcel");

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2022 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 "ime_cfg_manager.h"
#include <sys/stat.h>
#include <fstream>
#include "../../utils/include/file_manager.h"
#include "file_ex.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
namespace {
constexpr const char *IME_CFG_DIR = "/data/service/el1/public/imf/ime_cfg";
constexpr const char *IME_CFG_FILENAME = "ime_cfg.json";
constexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg/ime_cfg.json";
constexpr const int32_t SUCCESS = 0;
using json = nlohmann::json;
} // namespace
ImeCfgManager &ImeCfgManager::GetInstance()
{
static ImeCfgManager instance;
return instance;
}
void ImeCfgManager::Init()
{
if (!CreateCfgFile()) {
return;
}
ReadCfgFile();
}
bool ImeCfgManager::CreateCfgFile()
{
FileInfo info{ IME_CFG_DIR, IME_CFG_FILENAME, S_IRWXU, S_IRWXU };
auto errCode = FileManager::GetInstance().CreateCacheFile(info);
if (errCode != SUCCESS) {
IMSA_HILOGE("ImeCfgManager::CreateCacheFile failed");
return false;
}
return true;
}
void ImeCfgManager::ReadCfgFile()
{
json jsonConfigs;
bool ret = FileManager::GetInstance().ReadJsonFile(IME_CFG_FILE_PATH, jsonConfigs);
if (!ret) {
IMSA_HILOGE("ImeCfgManager::ReadJsonFile failed");
return;
}
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
from_json(jsonConfigs, imeConfigs_);
}
void ImeCfgManager::WriteCfgFile()
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
json jsonConfigs;
to_json(jsonConfigs, imeConfigs_);
if (!FileManager::GetInstance().WriteJsonFile(IME_CFG_FILE_PATH, jsonConfigs)) {
IMSA_HILOGE("ImeCfgManager::WriteJsonFile failed");
}
}
void ImeCfgManager::AddImeCfg(const ImeCfg &cfg)
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
imeConfigs_.push_back(cfg);
WriteCfgFile();
}
void ImeCfgManager::ModifyImeCfg(const ImeCfg &cfg)
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
for (auto &imeConfig : imeConfigs_) {
if (imeConfig.userId == cfg.userId && !cfg.currentIme.empty()) {
imeConfig.currentIme = cfg.currentIme;
}
}
WriteCfgFile();
}
void ImeCfgManager::DeleteImeCfg(int32_t userId)
{
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
for (auto iter = imeConfigs_.begin(); iter != imeConfigs_.end(); iter++) {
if (iter->userId == userId) {
imeConfigs_.erase(iter);
break;
}
}
WriteCfgFile();
}
ImeCfg ImeCfgManager::GetImeCfg(int32_t userId)
{
IMSA_HILOGD("ImeCfgManager::start");
std::lock_guard<std::recursive_mutex> lock(imeCfgLock_);
for (auto &cfg : imeConfigs_) {
if (cfg.userId == userId) {
return cfg;
}
}
return {};
}
void ImeCfgManager::from_json(const json &jsonConfigs, std::vector<ImeCfg> &configs)
{
for (auto &jsonCfg : jsonConfigs["imeCfg_list"]) {
ImeCfg cfg;
from_json(jsonCfg, cfg);
configs.push_back(cfg);
}
}
void ImeCfgManager::to_json(json &jsonConfigs, const std::vector<ImeCfg> &configs)
{
for (auto &cfg : configs) {
json jsonCfg;
to_json(jsonCfg, cfg);
jsonConfigs["imeCfg_list"].push_back(jsonCfg);
}
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -28,6 +28,7 @@
#include "errors.h"
#include "global.h"
#include "im_common_event_manager.h"
#include "ime_cfg_manager.h"
#include "input_method_status.h"
#include "ipc_skeleton.h"
#include "iservice_registry.h"
@ -40,7 +41,6 @@
#include "system_ability.h"
#include "system_ability_definition.h"
#include "ui_service_mgr_client.h"
#include "userImeCfg_manager.h"
namespace OHOS {
namespace MiscServices {
@ -124,7 +124,8 @@ int InputMethodSystemAbility::Dump(int fd, const std::vector<std::u16string> &ar
std::string InputMethodSystemAbility::GetInputMethodParam(const std::vector<InputMethodInfo> &properties)
{
std::string currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto currentIme = cfg.currentIme;
bool isBegin = true;
std::string params = "{\"imeList\":[";
for (const auto &property : properties) {
@ -176,7 +177,7 @@ int32_t InputMethodSystemAbility::Init()
IMSA_HILOGI("Publish ErrorCode::NO_ERROR.");
state_ = ServiceRunningState::STATE_RUNNING;
userSessions.insert({ MAIN_USER_ID, std::make_shared<PerUserSession>(MAIN_USER_ID) });
UserImeCfgManager::GetInstance()->Init();
ImeCfgManager::GetInstance().Init();
//服务异常重启后不会走OnUserStarted但是可以获取到当前userId
//设备启动时可能获取不到当前userId,如果获取不到则等OnUserStarted的时候处理.
userId_ = INVALID_USERID_VALUE;
@ -184,10 +185,12 @@ int32_t InputMethodSystemAbility::Init()
if ((OsAccountManager::QueryActiveOsAccountIds(userIds) == ERR_OK) && !userIds.empty()) {
userId_ = userIds[0];
IMSA_HILOGI("InputMethodSystemAbility::get current userId success, userId: %{public}d", userId_);
std::string newUserIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto newUserIme = cfg.currentIme;
if (newUserIme.empty()) {
newUserIme = ParaHandle::GetDefaultIme();
UserImeCfgManager::GetInstance()->AddCurrentIme(userId_, newUserIme);
ImeCfgManager::GetInstance().AddImeCfg({ userId_, newUserIme });
}
StartInputService(newUserIme);
}
@ -586,7 +589,8 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const std::string &bundleN
{
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod");
std::string targetIme = bundleName + "/" + name;
std::string currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto currentIme = cfg.currentIme;
if (currentIme.empty()) {
IMSA_HILOGE("currentIme is empty");
return ErrorCode::ERROR_PERSIST_CONFIG;
@ -602,7 +606,7 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const std::string &bundleN
IMSA_HILOGE("start input method failed");
return ErrorCode::ERROR_IME_START_FAILED;
}
UserImeCfgManager::GetInstance()->ModifyCurrentIme(userId_, targetIme);
ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, targetIme });
auto session = GetUserSession(MAIN_USER_ID);
if (session == nullptr) {
@ -757,7 +761,8 @@ int32_t InputMethodSystemAbility::ListProperty(int32_t userId, std::vector<Prope
std::shared_ptr<Property> InputMethodSystemAbility::GetCurrentInputMethod()
{
IMSA_HILOGI("InputMethodSystemAbility::GetCurrentInputMethod");
std::string currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto currentIme = cfg.currentIme;
if (currentIme.empty()) {
IMSA_HILOGE("InputMethodSystemAbility::GetCurrentInputMethod currentIme is empty");
return nullptr;
@ -782,7 +787,9 @@ std::shared_ptr<Property> InputMethodSystemAbility::GetCurrentInputMethod()
std::shared_ptr<SubProperty> InputMethodSystemAbility::GetCurrentInputMethodSubtype()
{
IMSA_HILOGI("InputMethodSystemAbility::GetCurrentInputMethodSubtype");
std::string currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto currentIme = cfg.currentIme;
if (currentIme.empty()) {
IMSA_HILOGE("InputMethodSystemAbility currentIme is empty");
return nullptr;
@ -828,6 +835,10 @@ void InputMethodSystemAbility::WorkThread()
OnUserStarted(msg);
break;
}
case MSG_ID_USER_REMOVED: {
OnUserRemoved(msg);
break;
}
case MSG_ID_PACKAGE_REMOVED: {
OnPackageRemoved(msg);
delete msg;
@ -868,7 +879,9 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg)
std::string lastUserIme;
if (userId_ != INVALID_USERID_VALUE) {
deviceStart = false;
lastUserIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
lastUserIme = cfg.currentIme;
if (lastUserIme.empty()) {
IMSA_HILOGE("InputMethodSystemAbility::lastUserIme is empty");
return ErrorCode::ERROR_PERSIST_CONFIG;
@ -877,14 +890,20 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg)
int32_t newUserId = msg->msgContent_->ReadInt32();
userId_ = newUserId;
std::string newUserIme = UserImeCfgManager::GetInstance()->GetCurrentIme(newUserId);
// 需要更新PerUserSession 中的userId_
auto it = userSessions.find(MAIN_USER_ID);
if (it != userSessions.end()) {
it->second->UpdateCurrentUserId(newUserId);
}
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(newUserId);
auto newUserIme = cfg.currentIme;
if (newUserIme.empty()) {
newUserIme = ParaHandle::GetDefaultIme();
if (newUserIme.empty()) {
IMSA_HILOGE("InputMethodSystemAbility::defaultIme is empty");
return ErrorCode::ERROR_PERSIST_CONFIG;
}
UserImeCfgManager::GetInstance()->AddCurrentIme(newUserId, newUserIme);
ImeCfgManager::GetInstance().AddImeCfg({ newUserId, newUserIme });
}
if (deviceStart) {
@ -892,24 +911,22 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg)
StartInputService(newUserIme);
return ErrorCode::NO_ERROR;
}
if (lastUserIme != newUserIme) {
StopInputService(lastUserIme);
StartInputService(newUserIme);
}
StopInputService(lastUserIme);
StartInputService(newUserIme);
return ErrorCode::NO_ERROR;
}
int32_t InputMethodSystemAbility::OnUserStopped(const Message *msg)
int32_t InputMethodSystemAbility::OnUserRemoved(const Message *msg)
{
IMSA_HILOGI("InputMethodSystemAbility::OnUserStopped Start...\n");
IMSA_HILOGI("InputMethodSystemAbility::OnUserRemoved Start...\n");
if (!msg->msgContent_) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
auto userId = msg->msgContent_->ReadInt32();
//TODO 一系列操作
UserImeCfgManager::GetInstance()->DeleteCurrentIme(userId);
ImeCfgManager::GetInstance().DeleteImeCfg(userId);
return ErrorCode::NO_ERROR;
}
@ -951,7 +968,8 @@ int32_t InputMethodSystemAbility::OnPackageRemoved(const Message *msg)
return ErrorCode::ERROR_EX_PARCELABLE;
}
auto currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId);
auto currentIme = cfg.currentIme;
if (currentIme.empty()) {
IMSA_HILOGE("InputMethodSystemAbility::currentIme is empty");
return ErrorCode::ERROR_PERSIST_CONFIG;

View File

@ -17,6 +17,7 @@
#include <vector>
#include "ime_cfg_manager.h"
#include "ability_connect_callback_proxy.h"
#include "ability_manager_interface.h"
#include "element_name.h"
@ -32,7 +33,6 @@
#include "parcel.h"
#include "system_ability_definition.h"
#include "unistd.h"
#include "userImeCfg_manager.h"
#include "utils.h"
#include "want.h"
@ -276,7 +276,8 @@ void PerUserSession::OnImsDied(sptr<IInputMethodCore> remote)
return;
}
IMSA_HILOGI("IME died. Restart input method...[%{public}d]\n", userId_);
const auto & currentIme = UserImeCfgManager::GetInstance()->GetCurrentIme(userId_);
auto cfg = ImeCfgManager::GetInstance().GetImeCfg(userId_);
auto currentIme = cfg.currentIme;
if (currentIme.empty()) {
IMSA_HILOGE("currentIme is empty");
return;
@ -298,6 +299,11 @@ void PerUserSession::OnImsDied(sptr<IInputMethodCore> remote)
IMSA_HILOGD("End...[%{public}d]\n", userId_);
}
void PerUserSession::UpdateCurrentUserId(int32_t userId)
{
userId_ = userId;
}
/*! Hide current keyboard
\param flag the flag to hide keyboard.
*/

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) 2022 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 "userImeCfg_manager.h"
#include <fstream>
#include "file_ex.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
namespace {
const std::string USER_IME_CFG_JSON_PATH = "/system/etc/imf/currentIme.json";
}
std::mutex UserImeCfgManager::instanceLock_;
sptr<UserImeCfgManager> UserImeCfgManager::instance_;
void UserImeCfgManager::Init()
{
//TODO 加载json文件存入userCurrentIme_
}
void UserImeCfgManager::AddCurrentIme(int32_t userId, const std::string &currentImeCfg)
{
//TODO json文件添加对应userId的value
userCurrentIme_.insert_or_assign(userId, currentImeCfg);
}
void UserImeCfgManager::ModifyCurrentIme(int32_t userId, const std::string &currentImeCfg)
{
//TODO json文件修改对应userId的value
userCurrentIme_.insert_or_assign(userId, currentImeCfg);
}
void UserImeCfgManager::DeleteCurrentIme(int32_t userId)
{
//TODO json文件删除对应userId的value
auto it = userCurrentIme_.find(userId);
if (it != userCurrentIme_.end()) {
userCurrentIme_.erase(it);
}
}
std::string UserImeCfgManager::GetCurrentIme(int32_t userId)
{
IMSA_HILOGD("UserImeCfgManager::start");
auto it = userCurrentIme_.find(userId);
if (it == userCurrentIme_.end()) {
IMSA_HILOGD("UserImeCfgManager::CurrentIme not found");
return "";
}
return it->second;
}
sptr<UserImeCfgManager> UserImeCfgManager::GetInstance()
{
if (!instance_) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (!instance_) {
IMSA_HILOGD("UserImeCfgManager::GetInstance instance_ is nullptr");
instance_ = new UserImeCfgManager();
}
}
return instance_;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -1,8 +0,0 @@
{
"100": {
"currentIme": "kika"
},
"101": {
"currentIme": "kika",
}
}

View File

@ -11,12 +11,34 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/inputmethod/imf/inputmethod.gni")
import("//build/ohos.gni")
ohos_prebuilt_etc("userImeCfg_json") {
install_enable = true
source = "userImeCfg.json"
relative_install_dir = "imf"
part_name = "imf"
subsystem_name = "inputmethod"
config("inputmethod_utils_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"${inputmethod_path}/services/include",
"//third_party/json/include",
]
}
ohos_shared_library("inputmethod_utils") {
sources = [
"src/file_manager.cpp",
]
configs = [ ":inputmethod_utils_native_config" ]
deps = [
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
]
external_deps = [
"c_utils:utils",
"hiviewdfx_hilog_native:libhilog",
]
subsystem_name = "inputmethod"
part_name = "imf"
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 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 SERVICES_INCLUDE_FILE_MANAGER_H
#define SERVICES_INCLUDE_FILE_MANAGER_H
#include "third_party/json/include/nlohmann/json.hpp"
namespace OHOS {
namespace MiscServices {
struct FileInfo {
std::string path;
std::string fileName;
mode_t pathMode;
int32_t fileMode;
};
class FileManager {
public:
static FileManager &GetInstance();
int32_t CreateCacheFile(FileInfo &info);
bool ReadJsonFile(const std::string &path, nlohmann::json &jsonCfg);
bool WriteJsonFile(const std::string &path, const nlohmann::json &jsonCfg);
private:
bool isCachePathExit(std::string &path);
static const int SUCCESS = 0;
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_FILE_MANAGER_H

View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2022 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 "file_manager.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdio>
#include <fstream>
#include <string>
#include "global.h"
namespace OHOS {
namespace MiscServices {
using json = nlohmann::json;
FileManager &FileManager::GetInstance()
{
static FileManager instance;
return instance;
}
int32_t FileManager::CreateCacheFile(FileInfo &info)
{
if (!isCachePathExit(info.path)) {
auto errCode = mkdir(info.path.c_str(), info.pathMode);
if (errCode != SUCCESS) {
IMSA_HILOGE("FileManager::CreateDirFailed");
return errCode;
}
}
std::string fileName = info.path + "/" + info.fileName;
if (isCachePathExit(fileName)) {
IMSA_HILOGI("FileManager::file: %{public}s exist", info.fileName.c_str());
return SUCCESS;
}
return creat(fileName.c_str(), info.fileMode);
}
bool FileManager::isCachePathExit(std::string &path)
{
return access(path.c_str(), F_OK) == SUCCESS;
}
bool FileManager::ReadJsonFile(const std::string &path, json &jsonCfg)
{
std::ifstream jsonFs(path);
if (!jsonFs.is_open()) {
IMSA_HILOGE("ImeCfgManager:file read open failed");
return false;
}
json cfgJson;
cfgJson = json::parse(jsonFs, nullptr, false);
if (cfgJson.is_null() || cfgJson.is_discarded()) {
IMSA_HILOGE("parse failed");
return false;
}
IMSA_HILOGI("ImeCfgManager::json %{public}s", cfgJson.dump().c_str());
return true;
}
bool FileManager::WriteJsonFile(const std::string &path, const nlohmann::json &jsonCfg)
{
std::ofstream jsonFs(path);
if (!jsonFs.is_open()) {
IMSA_HILOGE("ImeCfgManager:file write open failed");
return false;
}
jsonFs << jsonCfg;
return true;
}
} // namespace MiscServices
} // namespace OHOS