From 38d60a63bf37ec9b82241941d97d0caabe9b45b3 Mon Sep 17 00:00:00 2001 From: zhaolinglan Date: Tue, 17 Jun 2025 09:43:00 +0800 Subject: [PATCH 1/2] modify service Signed-off-by: zhaolinglan --- .../common/service_proxy/IResponseChannel.idl | 19 + .../include/response_channel_impl.h | 38 ++ .../include/response_data_util.h | 110 +++ .../service_proxy/include/service_proxy.h | 85 +++ .../include/service_response_data.h | 121 ++++ .../src/response_channel_impl.cpp | 38 ++ .../service_proxy/src/service_proxy.cpp | 270 ++++++++ .../src/service_response_data.cpp | 127 ++++ .../include/input_method_ability.h | 8 +- .../src/input_method_ability.cpp | 38 +- .../inputmethod_controller/IInputClient.idl | 2 + .../IInputMethodSystemAbility.idl | 9 +- .../include/input_client_service_impl.h | 2 + .../src/input_client_service_impl.cpp | 11 +- .../src/input_method_controller.cpp | 72 +- .../include/input_method_controller.h | 11 +- .../include/ime_enabled_info_manager.h | 3 +- .../src/ime_enabled_info_manager.cpp | 37 +- .../src/system_language_observer.cpp | 10 +- services/include/client_group.h | 4 + services/include/im_common_event_manager.h | 45 +- services/include/ime_cfg_manager.h | 4 - .../include/input_method_system_ability.h | 53 +- services/include/peruser_session.h | 16 +- services/include/user_session_manager.h | 2 - services/src/client_group.cpp | 12 + services/src/full_ime_info_manager.cpp | 10 +- services/src/im_common_event_manager.cpp | 284 ++------ services/src/ime_cfg_manager.cpp | 38 -- .../input_control_channel_service_impl.cpp | 25 +- services/src/input_method_system_ability.cpp | 630 +++++++++--------- services/src/peruser_session.cpp | 103 +-- services/src/user_session_manager.cpp | 7 +- .../task_manager/include/actions/sa_action.h | 93 +++ .../include/actions/sa_action_report.h | 52 ++ .../include/actions/sa_action_wait.h | 59 ++ services/task_manager/include/caller_info.h | 39 ++ .../task_manager/include/requester_manager.h | 65 ++ .../task_manager/include/sa_task_manager.h | 103 +++ services/task_manager/include/tasks/sa_task.h | 216 ++++++ .../src/actions/sa_action_wait.cpp | 63 ++ services/task_manager/src/caller_info.cpp | 27 + .../task_manager/src/requester_manager.cpp | 120 ++++ services/task_manager/src/sa_task_manager.cpp | 408 ++++++++++++ services/task_manager/src/tasks/sa_task.cpp | 203 ++++++ .../cpp_test/src/response_data_test.cpp | 84 +++ 46 files changed, 2930 insertions(+), 846 deletions(-) create mode 100644 frameworks/native/common/service_proxy/IResponseChannel.idl create mode 100644 frameworks/native/common/service_proxy/include/response_channel_impl.h create mode 100644 frameworks/native/common/service_proxy/include/response_data_util.h create mode 100644 frameworks/native/common/service_proxy/include/service_proxy.h create mode 100644 frameworks/native/common/service_proxy/include/service_response_data.h create mode 100644 frameworks/native/common/service_proxy/src/response_channel_impl.cpp create mode 100644 frameworks/native/common/service_proxy/src/service_proxy.cpp create mode 100644 frameworks/native/common/service_proxy/src/service_response_data.cpp create mode 100644 services/task_manager/include/actions/sa_action.h create mode 100644 services/task_manager/include/actions/sa_action_report.h create mode 100644 services/task_manager/include/actions/sa_action_wait.h create mode 100644 services/task_manager/include/caller_info.h create mode 100644 services/task_manager/include/requester_manager.h create mode 100644 services/task_manager/include/sa_task_manager.h create mode 100644 services/task_manager/include/tasks/sa_task.h create mode 100644 services/task_manager/src/actions/sa_action_wait.cpp create mode 100644 services/task_manager/src/caller_info.cpp create mode 100644 services/task_manager/src/requester_manager.cpp create mode 100644 services/task_manager/src/sa_task_manager.cpp create mode 100644 services/task_manager/src/tasks/sa_task.cpp create mode 100644 test/unittest/cpp_test/src/response_data_test.cpp diff --git a/frameworks/native/common/service_proxy/IResponseChannel.idl b/frameworks/native/common/service_proxy/IResponseChannel.idl new file mode 100644 index 000000000..68324470c --- /dev/null +++ b/frameworks/native/common/service_proxy/IResponseChannel.idl @@ -0,0 +1,19 @@ +/* + * 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. + */ + +sequenceable service_response_data..OHOS.MiscServices.ServiceResponseDataInner; +interface OHOS.MiscServices.IResponseChannel { + [oneway] void OnResponse([in] unsigned int requestId, [in] int result, [in] ServiceResponseDataInner response); +} diff --git a/frameworks/native/common/service_proxy/include/response_channel_impl.h b/frameworks/native/common/service_proxy/include/response_channel_impl.h new file mode 100644 index 000000000..c5bb603dc --- /dev/null +++ b/frameworks/native/common/service_proxy/include/response_channel_impl.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef IMF_RESPONSE_CHANNEL_IMPL_H +#define IMF_RESPONSE_CHANNEL_IMPL_H + +#include "iremote_object.h" +#include "iresponse_channel.h" +#include "response_channel_stub" +#include "service_response_data.h" + +namespace OHOS { +namespace MiscServices { +class ResponseChannelImpl final + : public ResponseChannelStub + , public std::enable_shared_from_this { + DISALLOW_COPY_AND_MOVE(ResponseChannelImpl); + +public: + ResponseChannelImpl(); + ~ResponseChannelImpl(); + ErrCode OnResponse(uint32_t requestId, int32_t result, const ServiceResponseDataInner &response) override; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_RESPONSE_CHANNEL_IMPL_H diff --git a/frameworks/native/common/service_proxy/include/response_data_util.h b/frameworks/native/common/service_proxy/include/response_data_util.h new file mode 100644 index 000000000..3c298d955 --- /dev/null +++ b/frameworks/native/common/service_proxy/include/response_data_util.h @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#ifndef RESPONSE_DATA_UTIL_H +#define RESPONSE_DATA_UTIL_H + +#include +#include + +#include "input_method_property.h" +#include "input_method_utils.h" + +namespace OHOS { +namespace MiscServices { +const int VECTOR_MAX_SIZE = 102400; +class ResponseDataUtil { +public: + template static bool Unmarshall(Parcel &in, std::vector &out) + { + return true; + } + + template static bool Marshall(const std::vector &in, Parcel &out) + { + auto size = in.size(); + if (size > static_cast(VECTOR_MAX_SIZE)) { + return false; + } + if (!out.WriteInt32(size)) { + return false; + } + for (const auto &it : in) { + if (!it.Marshalling(out)) { + return false; + } + } + return true; + } +}; + +struct ResponseReader { + Parcel ∈ + bool result = true; + + ResponseReader(Parcel &parcel) : in(parcel) + { + } + + template void operator()(T &value) + { + if constexpr (std::is_same_v) { + IMSA_HILOGD("no need to unmarshal"); + return; + } else if constexpr (std::is_same_v) { + result = in.ReadBool(value); + } else if constexpr (std::is_same_v) { + result = in.ReadInt32(value); + } else if constexpr (std::is_same_v) { + result = in.ReadUint32(value); + } else if constexpr (std::is_same_v>) { + value = static_cast(&in)->ReadRemoteObject(); + result = (value != nullptr); + } else if constexpr (std::is_base_of_v) { + result = value.ReadFromParcel(in); + } + } +}; + +struct ResponseWriter { + Parcel &out; + bool result = true; + + ResponseWriter(Parcel &parcel) : out(parcel) + { + } + + void operator()(bool val) + { + result = out.WriteBool(val); + } + void operator()(int32_t val) + { + result = out.WriteInt32(val); + } + void operator()(uint32_t val) + { + result = out.WriteUint32(val); + } + void operator()(sptr val) + { + result = static_cast(&out)->WriteRemoteObject(val); + } +}; + +} // namespace MiscServices +} // namespace OHOS + +#endif // RESPONSE_DATA_UTIL_H diff --git a/frameworks/native/common/service_proxy/include/service_proxy.h b/frameworks/native/common/service_proxy/include/service_proxy.h new file mode 100644 index 000000000..1db257f8c --- /dev/null +++ b/frameworks/native/common/service_proxy/include/service_proxy.h @@ -0,0 +1,85 @@ +/* + * 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. + */ + +#ifndef INPUTMETHOD_IMF_SERVICE_PROXY_H +#define INPUTMETHOD_IMF_SERVICE_PROXY_H + +#include +#include +#include +#include + +#include "input_client_info.h" +#include "input_method_utils.h" +#include "service_response_data.h" + +namespace OHOS { +namespace MiscServices { +constexpr int64_t SERVICE_PROXY_TIMEOUT = 1000; // 1s +using RequestId = uint32_t; +using RequestFunc = std::function; +class ServiceProxy { +private: + ServiceProxy(); + +public: + static ServiceProxy &GetInstance(); + + ~ServiceProxy() = default; + ServiceProxy(const ServiceProxy &) = delete; + ServiceProxy(ServiceProxy &&) = delete; + ServiceProxy &operator=(const ServiceProxy &) = delete; + ServiceProxy &operator=(ServiceProxy &&) = delete; + + void OnResponse(RequestId id, const ServiceResponse &responseData); + + int32_t StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response); + int32_t SwitchInputMethod(SwitchTrigger trigger, const std::string &name, const std::string &subName); + int32_t SetCoreAndAgent(const sptr &core, const sptr &agent); + +private: + void Init(); + sptr TryGetSystemAbilityProxy(); + sptr GetSystemAbilityProxy(bool ifRetry = true); + void OnRemoteSaDied(const wptr &remote); + + int32_t SendRequest(const RequestFunc &request); + template int32_t SendRequest(const RequestFunc &request, ResultType &resultValue); + int32_t RegisterToSa(); + + uint32_t GetNextRequestId(); + + struct PendingRequest { + std::promise promise; + std::chrono::time_point timestamp; + }; + void AddRequest(RequestId id, PendingRequest pendingRequest); + void RemoveRequest(RequestId requestId); + std::mutex requestsMutex_; + std::unordered_map pendingRequests_; + + std::mutex abilityLock_; + sptr abilityManager_ = nullptr; + sptr deathRecipient_; + std::atomic isRegistered_{ false }; + + std::atomic lastId_{ 0 }; + + sptr channelStub_ { nullptr }; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif //INPUTMETHOD_IMF_SERVICE_PROXY_H diff --git a/frameworks/native/common/service_proxy/include/service_response_data.h b/frameworks/native/common/service_proxy/include/service_response_data.h new file mode 100644 index 000000000..4cc1f9056 --- /dev/null +++ b/frameworks/native/common/service_proxy/include/service_response_data.h @@ -0,0 +1,121 @@ +/* + * 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. + */ + +#ifndef INPUTMETHOD_IMF_SERVICE_RESPONSE_DATA_H +#define INPUTMETHOD_IMF_SERVICE_RESPONSE_DATA_H + +#include +#include + +#include "element_name.h" +#include "input_method_property.h" +#include "input_method_utils.h" +#include "response_data_util.h" + +namespace OHOS { +namespace MiscServices { +struct StartInputResponse : public Parcelable { + sptr agent{ nullptr }; + int64_t pid{ 0 }; + std::string bundleName; + void Set(sptr imeAgent, int64_t imePid, const std::string &imeBundleName); + bool ReadFromParcel(Parcel &in); + bool Marshalling(Parcel &out) const override; + static StartInputResponse *Unmarshalling(Parcel &in); +}; + +enum class ServiceDataType : int32_t { + TYPE_MONSTATE = 0, + + // basic types + TYPE_BOOL = 1, + TYPE_INT32, + TYPE_UINT32, + TYPE_INT64, + TYPE_UINT64, + TYPE_REMOTE_OBJECT, + + // inner types + TYPE_PROPERTY, + TYPE_PROPERTIES, + TYPE_SUB_PROPERTY, + TYPE_SUB_PROPERTIES, + TYPE_START_INPUT_RESPONSE, + + // external types + TYPE_AMS_ELEMENT_NAME, + + TYPE_END, +}; + +using ServiceResponseData = + std::variant, Property, + std::vector, SubProperty, std::vector, StartInputResponse, AppExecFwk::ElementName>; +struct ServiceResponseDataInner : public Parcelable { +public: + bool ReadFromParcel(Parcel &in); + bool Marshalling(Parcel &out) const override; + static ServiceResponseDataInner *Unmarshalling(Parcel &in); + ServiceResponseData data; + +private: + struct ServiceResponseReader : public ResponseReader { + using ResponseReader::ResponseReader; + template void operator()(T &value) + { + ResponseReader::operator()(value); + + if constexpr (std::is_same_v> || std::is_same_v>) { + result = ResponseDataUtil::Unmarshall(in, value); + } + } + }; + struct ServiceResponseWriter : public ResponseWriter { + using ResponseWriter::ResponseWriter; + void operator()(const Property &val) + { + result = val.Marshalling(out); + } + void operator()(const std::vector &val) + { + result = ResponseDataUtil::Marshall(val, out); + } + void operator()(const SubProperty &val) + { + result = val.Marshalling(out); + } + void operator()(const std::vector &val) + { + result = ResponseDataUtil::Marshall(val, out); + } + void operator()(const StartInputResponse &val) + { + result = val.Marshalling(out); + } + void operator()(const AppExecFwk::ElementName &val) + { + result = val.Marshalling(out); + } + }; +}; + +struct ServiceResponse { + int32_t result{ 0 }; + ServiceResponseData responseData{ std::monstate{} }; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // INPUTMETHOD_IMF_SERVICE_RESPONSE_DATA_H diff --git a/frameworks/native/common/service_proxy/src/response_channel_impl.cpp b/frameworks/native/common/service_proxy/src/response_channel_impl.cpp new file mode 100644 index 000000000..08c60ae8d --- /dev/null +++ b/frameworks/native/common/service_proxy/src/response_channel_impl.cpp @@ -0,0 +1,38 @@ +/* + * 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 "response_channel_impl.h" + +#include "service_proxy.h" + +namespace OHOS { +namespace MiscServices { + +ResponseChannelImpl::ResponseChannelImpl() +{ +} + +ResponseChannelImpl::~ResponseChannelImpl() +{ +} + +ErrCode ResponseChannelImpl::OnResponse(uint32_t requestId, int32_t result, const ServiceResponseDataInner &response) +{ + ServiceResponse serviceResponse = { .result = result, .responseData = response.data }; + ServiceProxy::GetInstance().OnResponse(requestId, serviceResponse); + return ERR_OK; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/common/service_proxy/src/service_proxy.cpp b/frameworks/native/common/service_proxy/src/service_proxy.cpp new file mode 100644 index 000000000..bfd568478 --- /dev/null +++ b/frameworks/native/common/service_proxy/src/service_proxy.cpp @@ -0,0 +1,270 @@ +/* + * 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 "service_proxy.h" + +#include "iinput_method_system_ability.h" +#include "input_method_ability.h" +#include "input_method_controller.h" +#include "input_method_system_ability_proxy.h" +#include "input_method_tools.h" +#include "on_demand_start_stop_sa.h" +#include "response_channel_impl.h" +#include "system_ability_definition.h" + +namespace OHOS { +namespace MiscServices { +#define CHECK_RESPONSE_CHANNEL(retVal) \ + do { \ + auto ret = RegisterToSa(); \ + if (ret != ErrorCode::NO_ERROR) { \ + IMSA_HILOGD("failed to register to sa, ret: %{public}d", ret); \ + return retVal; \ + } \ + } while (0) + +ServiceProxy &ServiceProxy::GetInstance() +{ + static ServiceProxy serviceProxy; + return serviceProxy; +} + +ServiceProxy::ServiceProxy() +{ + Init(); +} + +void ServiceProxy::Init() +{ + IMSA_HILOGD("start"); + sptr channel = new (std::nothrow) ResponseChannelImpl(); + if (channel == nullptr) { + IMSA_HILOGE("failed to create channel!"); + return; + } + channelStub_ = channel; +} + +uint32_t ServiceProxy::GetNextRequestId() +{ + uint32_t id = lastId_.fetch_add(1, std::memory_order_seq_cst); + return id; +} + +void ServiceProxy::OnResponse(RequestId id, const ServiceResponse &responseData) +{ + std::lock_guard lock(requestsMutex_); + auto iter = pendingRequests_.find(id); + if (iter == pendingRequests_.end()) { + IMSA_HILOGE("failed to find pending request, id: %{public}d", id); + return; + } + IMSA_HILOGD("id: %{public}d", id); + iter->second.promise.set_value(responseData); +} + +int32_t ServiceProxy::StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response) +{ + RequestFunc request = [&inputClientInfo, this](RequestId requestId) -> int32_t { + CHECK_RESPONSE_CHANNEL(ErrorCode::ERROR_IMC_NULLPTR); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get proxy"); + return ErrorCode::ERROR_NULL_POINTER; + } + InputClientInfoInner clientInfoInner = InputMethodTools::GetInstance().InputClientInfoToInner(inputClientInfo); + return proxy->StartInput(requestId, clientInfoInner); + }; + return SendRequest(request, response); +} + +int32_t ServiceProxy::SwitchInputMethod(SwitchTrigger trigger, const std::string &name, const std::string &subName) +{ + RequestFunc requestFunc = [trigger, &name, &subName, this](RequestId requestId) -> int32_t { + CHECK_RESPONSE_CHANNEL(ErrorCode::ERROR_IMC_NULLPTR); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get proxy"); + return ErrorCode::ERROR_NULL_POINTER; + } + return proxy->SwitchInputMethod(requestId, name, subName, static_cast(trigger)); + }; + return SendRequest(requestFunc); +} + +int32_t ServiceProxy::SetCoreAndAgent(const sptr &core, const sptr &agent) +{ + RequestFunc requestFunc = [core, agent, this](RequestId requestId) -> int32_t { + CHECK_RESPONSE_CHANNEL(ErrorCode::ERROR_IMA_NULLPTR); + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get proxy"); + return ErrorCode::ERROR_NULL_POINTER; + } + return proxy->SetCoreAndAgent(requestId, core, agent); + }; + return SendRequest(requestFunc); +} + +sptr ServiceProxy::TryGetSystemAbilityProxy() +{ +#ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE + return GetSystemAbilityProxy(false); +#else + return GetSystemAbilityProxy(true); +#endif +} + +sptr ServiceProxy::GetSystemAbilityProxy(bool ifRetry) +{ + std::lock_guard lock(abilityLock_); + if (abilityManager_ != nullptr) { + return abilityManager_; + } + IMSA_HILOGD("get input method service proxy."); + auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(ifRetry); + if (systemAbility == nullptr) { + IMSA_HILOGE("systemAbility is nullptr!"); + return nullptr; + } + + if (deathRecipient_ == nullptr) { + deathRecipient_ = new (std::nothrow) InputDeathRecipient(); + if (deathRecipient_ == nullptr) { + IMSA_HILOGE("create death recipient failed!"); + return nullptr; + } + } + deathRecipient_->SetDeathRecipient([this](const wptr &remote) { OnRemoteSaDied(remote); }); + if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { + IMSA_HILOGE("failed to add death recipient!"); + return nullptr; + } + abilityManager_ = iface_cast(systemAbility); + return abilityManager_; +} + +void ServiceProxy::OnRemoteSaDied(const wptr &remote) +{ + isRegistered_.store(false); + auto instance = InputMethodController::GetInstance(); + if (instance != nullptr) { + instance->OnRemoteSaDied(remote); + } + InputMethodAbility::GetInstance().OnRemoteSaDied(remote); +} + +int32_t ServiceProxy::SendRequest(const RequestFunc &request) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + // wait till timeout + if (future.wait_for(SERVICE_PROXY_TIMEOUT) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + return ErrorCode::NO_ERROR; +} + +template int32_t ServiceProxy::SendRequest(const RequestFunc &request, ResultType &resultValue) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + // wait till timeout + if (future.wait_for(SERVICE_PROXY_TIMEOUT) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + RemoveRequest(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + ServiceResponseData responseData = response.responseData; + resultValue = std::get_if(responseData); + return ErrorCode::NO_ERROR; +} + +int32_t ServiceProxy::RegisterToSa() +{ + if (isRegistered_.load()) { + return ErrorCode::NO_ERROR; + } + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get sa proxy"); + return ErrorCode::ERROR_IPC_REMOTE_NULLPTR; + } + return proxy->RegisterRresponseChannel(channelStub_); +} + +void ServiceProxy::AddRequest(RequestId id, PendingRequest pendingRequest) +{ + std::lock_guard lock(requestsMutex_); + pendingRequest.timestamp = std::chrono::steady_clock::now(); + pendingRequests_[id] = std::move(pendingRequest); +} + +void ServiceProxy::RemoveRequest(RequestId requestId) +{ + std::lock_guard lock(requestsMutex_); + pendingRequests_.erase(requestId); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/common/service_proxy/src/service_response_data.cpp b/frameworks/native/common/service_proxy/src/service_response_data.cpp new file mode 100644 index 000000000..09c8b3f03 --- /dev/null +++ b/frameworks/native/common/service_proxy/src/service_response_data.cpp @@ -0,0 +1,127 @@ +/* + * 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 "service_response_data.h" + +namespace OHOS { +namespace MiscServices { +bool ServiceResponseDataInner::ReadFromParcel(Parcel &in) +{ + int32_t valueType = 0; + if (!in.ReadInt32(valueType)) { + return false; + } + if (valueType < static_cast(ServiceDataType::TYPE_MONSTATE) + || valueType >= static_cast(ServiceDataType::TYPE_END)) { + IMSA_HILOGE("invalid value type"); + return false; + } + if (valueType == static_cast(ServiceDataType::TYPE_MONSTATE)) { + data = std::monstate{}; + return true; + } + ServiceResponseReader reader{ in }; + std::visit(reader, data); + if (!reader.result) { + IMSA_HILOGE("failed to unmarshal response data"); + return false; + } + return true; +} + +bool ServiceResponseDataInner::Marshalling(Parcel &out) const +{ + int32_t valueType = static_cast(data.index()); + if (valueType < static_cast(ServiceDataType::TYPE_MONSTATE) + || valueType >= static_cast(ServiceDataType::TYPE_END)) { + IMSA_HILOGE("valid value type"); + return false; + } + if (!out.WriteInt32(valueType)) { + IMSA_HILOGE("failed to write valueType"); + return false; + } + if (valueType == static_cast(ServiceDataType::TYPE_MONSTATE)) { + return true; + } + ServiceResponseWriter writer{ out }; + std::visit(writer, data); + if (!writer.result) { + IMSA_HILOGE("failed to write response data"); + return false; + } + return true; +} + +ServiceResponseDataInner *ServiceResponseDataInner::Unmarshalling(Parcel &in) +{ + auto data = new (std::nothrow) ServiceResponseDataInner(); + if (data && !data->ReadFromParcel(in)) { + delete data; + data = nullptr; + } + return data; +} + +void StartInputResponse::Set(sptr imeAgent, int64_t imePid, const std::string &imeBundleName) +{ + agent = imeAgent; + pid = imePid; + bundleName = imeBundleName; +} + +bool StartInputResponse::ReadFromParcel(Parcel &in) +{ + agent = static_cast(&in)->ReadRemoteObject(); + if (agent == nullptr) { + return false; + } + if (!in.ReadInt64(pid)) { + return false; + } + if (!in.ReadString(bundleName)) { + return false; + } + return true; +} + +bool StartInputResponse::Marshalling(Parcel &out) const +{ + if (!static_cast(&out)->WriteRemoteObject(agent)) { + return false; + } + if (!out.WriteInt64(pid)) { + return false; + } + if (!out.WriteString(bundleName)) { + return false; + } + return true; +} + +StartInputResponse *StartInputResponse::Unmarshalling(Parcel &in) +{ + auto data = new (std::nothrow) StartInputResponse(); + if (data == nullptr) { + return nullptr; + } + if (!data->ReadFromParcel(in)) { + delete data; + return nullptr; + } + return data; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index d212c80f2..4aad048dd 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -42,6 +42,7 @@ #include "system_cmd_channel_proxy.h" #include "inputmethod_message_handler.h" #include "input_data_channel_proxy_wrap.h" +#include "service_proxy.h" namespace OHOS { namespace MiscServices { @@ -128,6 +129,11 @@ public: int32_t OnStopInputService(bool isTerminateIme); uint64_t GetCallingWindowDisplayId(); + +private: + friend ServiceProxy; + void OnRemoteSaDied(const wptr &object); + private: std::mutex controlChannelLock_; std::shared_ptr controlChannel_ = nullptr; @@ -150,8 +156,6 @@ private: ~InputMethodAbility(); InputMethodAbility(const InputMethodAbility &) = delete; InputMethodAbility &operator=(const InputMethodAbility &) = delete; - sptr GetImsaProxy(); - void OnRemoteSaDied(const wptr &object); sptr GetSystemCmdChannelProxy(); void ClearSystemCmdChannel(); diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 0c4a53175..c6f8ea565 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -38,6 +38,7 @@ #include "tasks/task_imsa.h" #include "input_method_tools.h" #include "variant_util.h" +#include "service_proxy.h" namespace OHOS { namespace MiscServices { @@ -67,36 +68,6 @@ InputMethodAbility &InputMethodAbility::GetInstance() return instance; } -sptr InputMethodAbility::GetImsaProxy() -{ - std::lock_guard lock(abilityLock_); - if (abilityManager_ != nullptr) { - return abilityManager_; - } - IMSA_HILOGI("InputMethodAbility get imsa proxy."); - auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(); - if (systemAbility == nullptr) { - IMSA_HILOGE("systemAbility is nullptr!"); - return nullptr; - } - if (deathRecipient_ == nullptr) { - deathRecipient_ = new (std::nothrow) InputDeathRecipient(); - if (deathRecipient_ == nullptr) { - IMSA_HILOGE("failed to new death recipient!"); - return nullptr; - } - } - deathRecipient_->SetDeathRecipient([this](const wptr &remote) { - OnRemoteSaDied(remote); - }); - if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { - IMSA_HILOGE("failed to add death recipient!"); - return nullptr; - } - abilityManager_ = iface_cast(systemAbility); - return abilityManager_; -} - int32_t InputMethodAbility::SetCoreAndAgent() { IMSA_HILOGD("InputMethodAbility, start."); @@ -106,12 +77,7 @@ int32_t InputMethodAbility::SetCoreAndAgent() IMSA_HILOGD("already bound."); return ErrorCode::NO_ERROR; } - auto proxy = GetImsaProxy(); - if (proxy == nullptr) { - IMSA_HILOGE("imsa proxy is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; - } - int32_t ret = proxy->SetCoreAndAgent(coreStub_, agentStub_->AsObject()); + int32_t ret = ServiceProxy::GetInstance().SetCoreAndAgent(coreStub_, agentStub_->AsObject()); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("set failed, ret: %{public}d!", ret); return ret; diff --git a/frameworks/native/inputmethod_controller/IInputClient.idl b/frameworks/native/inputmethod_controller/IInputClient.idl index ab3a4c8f3..6e93cac45 100644 --- a/frameworks/native/inputmethod_controller/IInputClient.idl +++ b/frameworks/native/inputmethod_controller/IInputClient.idl @@ -17,6 +17,7 @@ sequenceable input_method_property..OHOS.MiscServices.Property; sequenceable input_method_property..OHOS.MiscServices.SubProperty; sequenceable input_window_info..OHOS.MiscServices.InputWindowStatus; sequenceable input_window_info..OHOS.MiscServices.ImeWindowInfo; +sequenceable service_response_data..OHOS.MiscServices.ServiceResponseDataInner; sequenceable OHOS.IRemoteObject; interface OHOS.MiscServices.IInputClient { void OnInputReady([in] IRemoteObject agent, [in] long pid, [in] String bundleName); @@ -27,4 +28,5 @@ interface OHOS.MiscServices.IInputClient { void NotifyInputStart([in] unsigned int callingWndId, [in] int requestKeyboardReason); void NotifyInputStop(); [oneway] void DeactivateClient(); + [oneway] void OnResponse([in] unsigned int requestId, [in] int result, [in] ServiceResponseDataInner response); } diff --git a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl index c12337039..155076982 100644 --- a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl +++ b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl @@ -24,8 +24,8 @@ sequenceable OHOS.IRemoteObject; interface OHOS.MiscServices.IInputClient; interface OHOS.MiscServices.IInputMethodCore; interface OHOS.MiscServices.IInputMethodSystemAbility { - void StartInput([in] InputClientInfoInner inputClientInfoInner, - [out] IRemoteObject agent, [out] long pid, [out] String bundleName); + void RegisterResponseChannel([in] IResponseChannel channel); + void StartInput([in] unsigned int requestId, [in] InputClientInfoInner inputClientInfoInner); void ShowCurrentInput([in] unsigned int type); void HideCurrentInput(); void StopInputSession(); @@ -40,12 +40,13 @@ interface OHOS.MiscServices.IInputMethodSystemAbility { void GetCurrentInputMethodSubtype([out] SubProperty resultValue); void ListInputMethod([in] unsigned int status, [out] Property[] props); void DisplayOptionalInputMethod(); - void SetCoreAndAgent([in] IInputMethodCore core, [in] IRemoteObject agent); + void SetCoreAndAgent([in] unsigned int requestId, [in] IInputMethodCore core, [in] IRemoteObject agent); void InitConnect(); void UnRegisteredProxyIme([in] int type, [in] IInputMethodCore core); void ListCurrentInputMethodSubtype([out] SubProperty[] subProps); void ListInputMethodSubtype([in] String name, [out] SubProperty[] subProps); - void SwitchInputMethod([in] String bundleName, [in] String name, [in] unsigned int trigger); + void SwitchInputMethod( + [in] unsigned int requestId, [in] String bundleName, [in] String name, [in] unsigned int trigger); [oneway] void PanelStatusChange([in] unsigned int status, [in] ImeWindowInfo info); void UpdateListenEventFlag([in] InputClientInfoInner clientInfoInner, [in] unsigned int eventFlag); void IsCurrentIme([out] boolean resultValue); diff --git a/frameworks/native/inputmethod_controller/include/input_client_service_impl.h b/frameworks/native/inputmethod_controller/include/input_client_service_impl.h index a12ab4ffc..4e88da586 100644 --- a/frameworks/native/inputmethod_controller/include/input_client_service_impl.h +++ b/frameworks/native/inputmethod_controller/include/input_client_service_impl.h @@ -19,6 +19,7 @@ #include "iinput_client.h" #include "input_client_stub.h" #include "iremote_object.h" +#include "service_response_data.h" namespace OHOS { namespace MiscServices { @@ -37,6 +38,7 @@ public: ErrCode NotifyInputStart(uint32_t callingWndId, int32_t requestKeyboardReason) override; ErrCode NotifyInputStop() override; ErrCode DeactivateClient() override; + ErrCode OnResponse(uint32_t requestId, int32_t result, const ServiceResponseDataInner& response) override; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_controller/src/input_client_service_impl.cpp b/frameworks/native/inputmethod_controller/src/input_client_service_impl.cpp index a9bcf6077..bb2a0795f 100644 --- a/frameworks/native/inputmethod_controller/src/input_client_service_impl.cpp +++ b/frameworks/native/inputmethod_controller/src/input_client_service_impl.cpp @@ -15,9 +15,10 @@ #include "input_client_service_impl.h" -#include "input_client_stub.h" #include "ime_event_monitor_manager_impl.h" +#include "input_client_stub.h" #include "input_method_controller.h" +#include "service_proxy.h" namespace OHOS { namespace MiscServices { @@ -94,5 +95,13 @@ ErrCode InputClientServiceImpl::DeactivateClient() } return ERR_OK; } + +ErrCode InputClientServiceImpl::OnResponse( + uint32_t requestId, int32_t result, const ServiceResponseDataInner &response) +{ + ServiceResponse serviceResponse = { .result = result, .responseData = response.data }; + ServiceProxy::GetInstance().OnResponse(requestId, serviceResponse); + return ERR_OK; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index 632c53c33..270c2f915 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -146,46 +146,6 @@ int32_t InputMethodController::Initialize() return ErrorCode::NO_ERROR; } -sptr InputMethodController::TryGetSystemAbilityProxy() -{ -#ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE - return GetSystemAbilityProxy(false); -#else - return GetSystemAbilityProxy(true); -#endif -} - -sptr InputMethodController::GetSystemAbilityProxy(bool ifRetry) -{ - std::lock_guard lock(abilityLock_); - if (abilityManager_ != nullptr) { - return abilityManager_; - } - IMSA_HILOGD("get input method service proxy."); - auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(ifRetry); - if (systemAbility == nullptr) { - IMSA_HILOGE("systemAbility is nullptr!"); - return nullptr; - } - - if (deathRecipient_ == nullptr) { - deathRecipient_ = new (std::nothrow) InputDeathRecipient(); - if (deathRecipient_ == nullptr) { - IMSA_HILOGE("create death recipient failed!"); - return nullptr; - } - } - deathRecipient_->SetDeathRecipient([this](const wptr &remote) { - OnRemoteSaDied(remote); - }); - if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { - IMSA_HILOGE("failed to add death recipient!"); - return nullptr; - } - abilityManager_ = iface_cast(systemAbility); - return abilityManager_; -} - void InputMethodController::RemoveDeathRecipient() { std::lock_guard lock(abilityLock_); @@ -328,9 +288,8 @@ int32_t InputMethodController::Attach(sptr listener, cons clientInfo_.requestKeyboardReason = attachOptions.requestKeyboardReason; clientInfo_.type = type; - sptr agent = nullptr; - std::pair imeInfo{ 0, "" }; - int32_t ret = StartInput(clientInfo_, agent, imeInfo); + StartInputResponse response; + int32_t ret = StartInput(clientInfo_, response); if (ret != ErrorCode::NO_ERROR) { auto evenInfo = HiSysOriginalInfo::Builder() .SetErrCode(ret) @@ -342,7 +301,7 @@ int32_t InputMethodController::Attach(sptr listener, cons return ret; } clientInfo_.state = ClientState::ACTIVE; - OnInputReady(agent, imeInfo); + OnInputReady(response.agent, { response.pid, response.bundleName }); if (attachOptions.isShowKeyboard) { InputMethodSysEvent::GetInstance().OperateSoftkeyboardBehaviour(OperateIMEInfoCode::IME_SHOW_ATTACH); } @@ -613,17 +572,10 @@ int32_t InputMethodController::EnableIme( return proxy->EnableIme(bundleName, extensionName, static_cast(status)); } -int32_t InputMethodController::StartInput( - InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo) +int32_t InputMethodController::StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response) { IMSA_HILOGD("InputMethodController::StartInput start."); - auto proxy = GetSystemAbilityProxy(); - if (proxy == nullptr) { - IMSA_HILOGE("proxy is nullptr!"); - return ErrorCode::ERROR_SERVICE_START_FAILED; - } - InputClientInfoInner inner = InputMethodTools::GetInstance().InputClientInfoToInner(inputClientInfo); - int32_t ret = proxy->StartInput(inner, agent, imeInfo.first, imeInfo.second); + int32_t ret = ServiceProxy::GetInstance().StartInput(inputClientInfo, response); return ret; } @@ -867,13 +819,12 @@ int32_t InputMethodController::OnConfigurationChange(Configuration info) "IMC enterKeyType: %{public}d, textInputType: %{public}d.", attribute.enterKeyType, attribute.inputPattern); if (oldSecurityFlag != attribute.GetSecurityFlag()) { GetTextConfig(clientInfo_.config); - sptr agent = nullptr; - std::pair imeInfo{ 0, "" }; - int32_t ret = StartInput(clientInfo_, agent, imeInfo); + StartInputResponse response; + int32_t ret = StartInput(clientInfo_, response); if (ret != ErrorCode::NO_ERROR) { return ret; } - OnInputReady(agent, imeInfo); + OnInputReady(response.agent, { response.pid, response.bundleName }); } auto agent = GetAgent(); if (agent == nullptr) { @@ -1140,14 +1091,9 @@ int32_t InputMethodController::SwitchInputMethod( SwitchTrigger trigger, const std::string &name, const std::string &subName) { InputMethodSyncTrace tracer("IMC_SwitchInputMethod"); - auto proxy = GetSystemAbilityProxy(); - if (proxy == nullptr) { - IMSA_HILOGE("proxy is nullptr!"); - return ErrorCode::ERROR_EX_NULL_POINTER; - } IMSA_HILOGI("name: %{public}s, subName: %{public}s, trigger: %{public}d.", name.c_str(), subName.c_str(), static_cast(trigger)); - return proxy->SwitchInputMethod(name, subName, static_cast(trigger)); + return ServiceProxy::GetInstance().SwitchInputMethod(trigger, name, subName); } void InputMethodController::OnInputReady( diff --git a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h index b6a613968..b1395f2e8 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -43,6 +43,7 @@ #include "inputmethod_message_handler.h" #include "panel_info.h" #include "private_command_interface.h" +#include "service_proxy.h" #include "visibility.h" namespace OHOS { @@ -970,23 +971,23 @@ public: void SetAgent(const sptr &agentObject); +private: + friend ServiceProxy; + void OnRemoteSaDied(const wptr &object); + private: InputMethodController(); ~InputMethodController(); int32_t Initialize(); - sptr GetSystemAbilityProxy(bool ifRetry = true); - sptr TryGetSystemAbilityProxy(); void RemoveDeathRecipient(); - int32_t StartInput( - InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo); + int32_t StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response); int32_t ShowInput( sptr &client, ClientType type = ClientType::INNER_KIT, int32_t requestKeyboardReason = 0); int32_t HideInput(sptr &client); int32_t ReleaseInput(sptr &client); int32_t ListInputMethodCommon(InputMethodStatus status, std::vector &props); void ClearEditorCache(bool isNewEditor, sptr lastListener); - void OnRemoteSaDied(const wptr &object); void RestoreListenInfoInSaDied(); void RestoreClientInfoInSaDied(); int32_t RestoreListenEventFlag(); diff --git a/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h b/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h index 0381b33cb..2ca620bcb 100644 --- a/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h +++ b/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h @@ -116,11 +116,10 @@ struct ImeEnabledCfg : public Serializable { }; using CurrentImeStatusChangedHandler = std::function; -class ImeEnabledInfoManager { +class ImeEnabledInfoManager : public std::enable_shared_from_this { public: static ImeEnabledInfoManager &GetInstance(); void SetCurrentImeStatusChangedHandler(CurrentImeStatusChangedHandler handler); - void SetEventHandler(const std::shared_ptr &eventHandler); int32_t Init(const std::map> &fullImeInfos); int32_t Switch(int32_t userId, const std::vector &imeInfos); int32_t Delete(int32_t userId); diff --git a/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp b/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp index 918ce7a64..3b8e54d6f 100644 --- a/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp +++ b/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp @@ -23,6 +23,8 @@ #include "enable_upgrade_manager.h" #include "ime_info_inquirer.h" +#include "sa_task_manager.h" + namespace OHOS { namespace MiscServices { using namespace std::chrono; @@ -44,11 +46,6 @@ void ImeEnabledInfoManager::SetCurrentImeStatusChangedHandler(CurrentImeStatusCh currentImeStatusChangedHandler_ = std::move(handler); } -void ImeEnabledInfoManager::SetEventHandler(const std::shared_ptr &eventHandler) -{ - serviceHandler_ = eventHandler; -} - int32_t ImeEnabledInfoManager::Init(const std::map> &fullImeInfos) { std::lock_guard lock(operateLock_); @@ -506,15 +503,19 @@ int32_t ImeEnabledInfoManager::UpdateEnabledCfgCache(int32_t userId, const ImeEn void ImeEnabledInfoManager::NotifyCurrentImeStatusChanged( int32_t userId, const std::string &bundleName, EnabledStatus newStatus) { - if (serviceHandler_ == nullptr) { - return; - } - auto notifyTask = [this, userId, bundleName, newStatus]() { - if (currentImeStatusChangedHandler_ != nullptr) { - currentImeStatusChangedHandler_(userId, bundleName, newStatus); + std::weak_ptr weakThis = shared_from_this(); + auto func = [weakThis, userId, bundleName, newStatus](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; } + if (sharedThis->currentImeStatusChangedHandler_ != nullptr) { + sharedThis->currentImeStatusChangedHandler_(userId, bundleName, newStatus); + } + return ErrorCode::NO_ERROR; }; - serviceHandler_->PostTask(notifyTask, "NotifyCurrentImeStatusChanged", 0, AppExecFwk::EventQueue::Priority::VIP); + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::CURRENT_IME_STATUS_CHANGED, func)); } bool ImeEnabledInfoManager::HasEnabledSwitch() @@ -573,15 +574,13 @@ bool ImeEnabledInfoManager::IsExpired(const std::string &expirationTime) void ImeEnabledInfoManager::UpdateGlobalEnabledTable(int32_t userId, const ImeEnabledCfg &newEnabledCfg) { - IMSA_HILOGD("start."); - if (serviceHandler_ == nullptr) { - return; - } - auto task = [userId, newEnabledCfg]() { + auto func = [userId, newEnabledCfg](ServiceResponseData &data) -> int32_t { + IMSA_HILOGD("start."); EnableUpgradeManager::GetInstance().UpdateGlobalEnabledTable(userId, newEnabledCfg); + IMSA_HILOGD("end."); + return ErrorCode::NO_ERROR; }; - serviceHandler_->PostTask(task, "UpdateGlobalEnabledTable", 0, AppExecFwk::EventQueue::Priority::LOW); - IMSA_HILOGD("end."); + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::UPDATE_GLOBAL_ENABLED_TABLE, func)); } void ImeEnabledInfoManager::OnFullExperienceTableChanged(int32_t userId) diff --git a/services/adapter/system_language_observer/src/system_language_observer.cpp b/services/adapter/system_language_observer/src/system_language_observer.cpp index 239954dd1..a8f9fbdf3 100644 --- a/services/adapter/system_language_observer/src/system_language_observer.cpp +++ b/services/adapter/system_language_observer/src/system_language_observer.cpp @@ -14,8 +14,11 @@ */ #include "system_language_observer.h" + #include "inputmethod_message_handler.h" #include "parameter.h" +#include "sa_task_manager.h" +#include "full_ime_info_manager.h" namespace OHOS { namespace MiscServices { @@ -38,11 +41,8 @@ void SystemLanguageObserver::OnChange(const char *key, const char *value, void * return; } IMSA_HILOGD("value: %{public}s.", value); - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_SYS_LANGUAGE_CHANGED, nullptr); - if (msg == nullptr) { - return; - } - MessageHandler::Instance()->SendMessage(msg); + auto task = [](ServiceResponseData &) -> int32_t { FullImeInfoManager::GetInstance().Update(); }; + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::ON_SYSTEM_LANGUAGE_CHANGED, task)); } } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/include/client_group.h b/services/include/client_group.h index ad3918935..55422f5c1 100644 --- a/services/include/client_group.h +++ b/services/include/client_group.h @@ -21,6 +21,7 @@ #include "input_client_info.h" #include "input_death_recipient.h" +#include "service_response_data.h" namespace OHOS { namespace MiscServices { @@ -68,6 +69,9 @@ public: int32_t NotifyPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info); int32_t NotifyImeChangeToClients(const Property &property, const SubProperty &subProperty); + void NotifyServiceResponse(uint32_t requestId, int32_t result, const sptr &client, + const ServiceResponseData &responseData); + private: std::map, std::shared_ptr> GetClientMap(); bool IsSameClient(sptr source, sptr dest); diff --git a/services/include/im_common_event_manager.h b/services/include/im_common_event_manager.h index 17a444d1d..fef40850e 100644 --- a/services/include/im_common_event_manager.h +++ b/services/include/im_common_event_manager.h @@ -25,39 +25,42 @@ namespace OHOS { namespace MiscServices { using Handler = std::function; +using CommonEventHandler = std::function; class ImCommonEventManager : public RefBase { +private: + ImCommonEventManager() = default; + public: - ImCommonEventManager(); - ~ImCommonEventManager(); - static sptr GetInstance(); + static ImCommonEventManager &GetInstance(); + + ~ImCommonEventManager() = default; + ImCommonEventManager(const ImCommonEventManager &) = delete; + ImCommonEventManager(ImCommonEventManager &&) = delete; + ImCommonEventManager &operator=(const ImCommonEventManager &) = delete; + ImCommonEventManager &operator=(ImCommonEventManager &&) = delete; + bool SubscribeEvent(); bool SubscribeKeyboardEvent(const Handler &handler); bool SubscribeWindowManagerService(const Handler &handler); bool SubscribeMemMgrService(const Handler &handler); bool SubscribeAccountManagerService(Handler handle); - bool UnsubscribeEvent(); + + void RegisterHandler(const std::string &eventName, const CommonEventHandler &handler); + // only public the status change of softKeyboard in FLG_FIXED or FLG_FLOATING int32_t PublishPanelStatusChangeEvent(int32_t userId, const InputWindowStatus &status, const ImeWindowInfo &info); class EventSubscriber : public EventFwk::CommonEventSubscriber { public: - EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo); + EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo) : CommonEventSubscriber(subscribeInfo) + { + } void OnReceiveEvent(const EventFwk::CommonEventData &data); - void RemovePackage(const EventFwk::CommonEventData &data); - void StartUser(const EventFwk::CommonEventData &data); - void RemoveUser(const EventFwk::CommonEventData &data); - void StopUser(const EventFwk::CommonEventData &data); - void OnBundleScanFinished(const EventFwk::CommonEventData &data); - void OnDataShareReady(const EventFwk::CommonEventData &data); - void AddPackage(const EventFwk::CommonEventData &data); - void ChangePackage(const EventFwk::CommonEventData &data); - void HandleBootCompleted(const EventFwk::CommonEventData &data); - void OnScreenUnlock(const EventFwk::CommonEventData &data); + void SetHandlers(std::map handlers); private: - using EventListenerFunc = std::function; - std::map EventManagerFunc_; - void HandlePackageEvent(int32_t messageId, const EventFwk::CommonEventData &data); - void HandleUserEvent(int32_t messageId, const EventFwk::CommonEventData &data); + CommonEventHandler GetHandler(const std::string &event); + std::mutex handlersMutex_; + std::map eventHandlers_; }; private: @@ -74,8 +77,8 @@ private: }; private: - static std::mutex instanceLock_; - static sptr instance_; + std::mutex handlersMutex_; + std::map eventHandlers_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/ime_cfg_manager.h b/services/include/ime_cfg_manager.h index fd0e6ad92..20dee1dcc 100644 --- a/services/include/ime_cfg_manager.h +++ b/services/include/ime_cfg_manager.h @@ -33,22 +33,18 @@ public: void AddImeCfg(const ImePersistInfo &cfg); void ModifyImeCfg(const ImePersistInfo &cfg); void ModifyTempScreenLockImeCfg(int32_t userId, const std::string &ime); - void DeleteImeCfg(int32_t userId); std::shared_ptr GetCurrentImeCfg(int32_t userId); bool IsDefaultImeSet(int32_t userId); - void SetEventHandler(const std::shared_ptr &eventHandler); private: ImeCfgManager() = default; ~ImeCfgManager() = default; void ReadImeCfg(); - void WriteImeCfg(); ImePersistInfo GetImeCfg(int32_t userId); bool ParseImeCfg(const std::string &content); std::string PackageImeCfg(); std::recursive_mutex imeCfgLock_; std::vector imeConfigs_; - static std::shared_ptr serviceHandler_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 88d318410..54161520f 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -16,6 +16,7 @@ #ifndef SERVICES_INCLUDE_INPUT_METHOD_SYSTEM_ABILITY_H #define SERVICES_INCLUDE_INPUT_METHOD_SYSTEM_ABILITY_H +#include "caller_info.h" #include "identity_checker_impl.h" #include "ime_info_inquirer.h" #include "input_method_system_ability_stub.h" @@ -25,11 +26,15 @@ #include "input_method_types.h" #include "user_session_manager.h" #include "input_type_manager.h" +#include "common_event_manager.h" namespace OHOS { namespace MiscServices { enum class ServiceRunningState { STATE_NOT_START, STATE_RUNNING }; -class InputMethodSystemAbility : public SystemAbility, public InputMethodSystemAbilityStub { +class InputMethodSystemAbility + : public SystemAbility + , public InputMethodSystemAbilityStub + , public std::enable_shared_from_this { DECLARE_SYSTEM_ABILITY(InputMethodSystemAbility); public: @@ -39,8 +44,8 @@ public: ~InputMethodSystemAbility(); int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - ErrCode StartInput(const InputClientInfoInner &inputClientInfoInner, sptr &agent, - int64_t &pid, std::string &bundleName) override; + ErrCode RegisterResponseChannel(sptr channel) override; + ErrCode StartInput(uint32_t requestId, const InputClientInfoInner &inputClientInfoInner) override; ErrCode ShowCurrentInput(uint32_t type = static_cast(ClientType::INNER_KIT)) override; ErrCode HideCurrentInput() override; ErrCode ShowInput(const sptr& client, uint32_t type = static_cast(ClientType::INNER_KIT), @@ -58,9 +63,10 @@ public: ErrCode ListCurrentInputMethodSubtype(std::vector &subProps) override; ErrCode ListInputMethodSubtype(const std::string &bundleName, std::vector &subProps) override; ErrCode SwitchInputMethod( - const std::string &bundleName, const std::string &subName, uint32_t trigger) override; + uint32_t requestId, const std::string &bundleName, const std::string &subName, uint32_t trigger) override; ErrCode DisplayOptionalInputMethod() override; - ErrCode SetCoreAndAgent(const sptr &core, const sptr &agent) override; + ErrCode SetCoreAndAgent( + uint32_t requestId, const sptr &core, const sptr &agent) override; ErrCode InitConnect() override; ErrCode UnRegisteredProxyIme(int32_t type, const sptr &core) override; ErrCode PanelStatusChange(uint32_t status, const ImeWindowInfo &info) override; @@ -103,22 +109,29 @@ private: int32_t Init(); void Initialize(); - std::thread workThreadHandler; /*!< thread handler of the WorkThread */ void RestartSessionIme(std::shared_ptr &session); std::shared_ptr GetSessionFromMsg(const Message *msg); int32_t PrepareForOperateKeyboard(std::shared_ptr &session); int32_t SwitchByCondition(const Condition &condition, const std::shared_ptr &info); + CallerInfo GetCallerInfo(uint32_t requestId); int32_t GetUserId(int32_t uid); int32_t GetCallingUserId(); uint64_t GetCallingDisplayId(sptr abilityToken = nullptr); + uint64_t GetCallingDisplayId(int32_t callingPid, sptr abilityToken = nullptr); std::shared_ptr identityChecker_ = nullptr; int32_t PrepareInput(int32_t userId, InputClientInfo &clientInfo); - void WorkThread(); - int32_t OnUserStarted(const Message *msg); - int32_t OnUserRemoved(const Message *msg); - int32_t OnUserStop(const Message *msg); - int32_t OnHideKeyboardSelf(const Message *msg); + + int32_t OnUserStarted(const EventFwk::CommonEventData &data); + int32_t OnUserRemoved(const EventFwk::CommonEventData &data); + int32_t OnUserStop(const EventFwk::CommonEventData &data); + void OnPackageAdded(const EventFwk::CommonEventData &data); + void OnPackageChanged(const EventFwk::CommonEventData &data); + void OnPackageRemoved(const EventFwk::CommonEventData &data); + void OnScreenUnlock(const EventFwk::CommonEventData &data); + void OnDataShareReady(); + void OnBundleScanFinished(); + bool IsNeedSwitch(int32_t userId, const std::string &bundleName, const std::string &subName); int32_t CheckEnableAndSwitchPermission(); int32_t CheckSwitchPermission(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger); @@ -127,14 +140,8 @@ private: int32_t StartSwitch(int32_t userId, const SwitchInfo &switchInfo, const std::shared_ptr &session); int32_t OnStartInputType(int32_t userId, const SwitchInfo &switchInfo, bool isCheckPermission); - int32_t HandlePackageEvent(const Message *msg); - int32_t OnPackageRemoved(int32_t userId, const std::string &packageName); - void OnScreenUnlock(const Message *msg); int32_t OnDisplayOptionalInputMethod(); void SubscribeCommonEvent(); - int32_t Switch(int32_t userId, const std::string &bundleName, const std::shared_ptr &info); - int32_t SwitchExtension(int32_t userId, const std::shared_ptr &info); - int32_t SwitchSubType(int32_t userId, const std::shared_ptr &info); int32_t SwitchInputType(int32_t userId, const SwitchInfo &switchInfo); void GetValidSubtype(const std::string &subName, const std::shared_ptr &info); ServiceRunningState state_; @@ -146,7 +153,6 @@ private: void HandleUserSwitched(int32_t userId); void HandleWmsStarted(); void HandleMemStarted(); - void HandleDataShareReady(); void HandleOsAccountStarted(); void HandleFocusChanged(bool isFocused, uint64_t displayId, int32_t pid, int32_t uid); void HandleImeCfgCapsState(); @@ -178,9 +184,8 @@ private: void NeedHideWhenSwitchInputType(int32_t userId, InputType type, bool &needHide); bool GetDeviceFunctionKeyState(int32_t functionKey, bool &isEnable); bool ModifyImeCfgWithWrongCaps(); - void HandleBundleScanFinished(); int32_t StartInputInner( - InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo); + const CallerInfo &callerInfo, InputClientInfo &inputClientInfo, StartInputResponse &response); int32_t ShowInputInner(sptr client, int32_t requestKeyboardReason = 0); int32_t ShowCurrentInputInner(); std::pair GetCurrentImeInfoForHiSysEvent(int32_t userId); @@ -211,6 +216,14 @@ private: void ChangeToDefaultImeForHiCar(int32_t userId, InputClientInfo &inputClientInfo); bool IsDefaultImeScreen(uint64_t displayId); + + int32_t StartInputTask(const CallerInfo &callerInfo, InputClientInfo clientInfo, StartInputResponse &response); + int32_t SwitchInputMethodTask(const std::string &bundleName, const std::string &subName, uint32_t trigger); + int32_t SetCoreAndAgentTask( + const CallerInfo &callerInfo, const sptr &core, const sptr &agent); + + void ReportStartInput(const CallerInfo &callerInfo, const InputClientInfo &clientInfo, + const StartInputResponse &response, int32_t ret); }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index 29c619691..08129debe 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -19,16 +19,17 @@ #include #include "block_queue.h" +#include "caller_info.h" #include "client_group.h" #include "event_status_manager.h" #include "iinput_method_core.h" #include "ime_cfg_manager.h" +#include "ime_state_manager.h" #include "input_method_types.h" #include "input_type_manager.h" #include "inputmethod_message_handler.h" #include "inputmethod_sysevent.h" #include "want.h" -#include "ime_state_manager.h" namespace OHOS { namespace Rosen { @@ -77,17 +78,16 @@ struct ImeData { * * This class manages the sessions between input clients and input method engines for each unlocked user. */ -class PerUserSession { +class PerUserSession : public std::enable_shared_from_this { public: explicit PerUserSession(int userId); - PerUserSession(int32_t userId, const std::shared_ptr &eventHandler); ~PerUserSession(); int32_t OnPrepareInput(const InputClientInfo &clientInfo); - int32_t OnStartInput( - const InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo); + int32_t OnStartInput(const InputClientInfo &inputClientInfo, StartInputResponse &response); int32_t OnReleaseInput(const sptr &client, uint32_t sessionId); - int32_t OnSetCoreAndAgent(const sptr &core, const sptr &agent); + int32_t OnSetCoreAndAgent( + const CallerInfo &callerInfo, const sptr &core, const sptr &agent); int32_t OnHideCurrentInput(uint64_t displayId); int32_t OnShowCurrentInput(uint64_t displayId); int32_t OnShowInput(sptr client, int32_t requestKeyboardReason = 0); @@ -176,6 +176,7 @@ private: void OnClientDied(sptr remote); void OnImeDied(const sptr &remote, ImeType type); + void OnImeDied(const sptr &remote, ImeType type, const std::string &bundleName, pid_t pid); int AddClientInfo(sptr inputClient, const InputClientInfo &clientInfo, ClientAddEvent event); int32_t RemoveClient(const sptr &client, const std::shared_ptr &clientGroup, @@ -196,7 +197,7 @@ private: std::shared_ptr GetValidIme(ImeType type); int32_t BindClientWithIme(const std::shared_ptr &clientInfo, ImeType type, - bool isBindFromClient = false, uint64_t displayId = DEFAULT_DISPLAY_ID); + bool isBindFromClient = false, uint64_t displayId = DEFAULT_DISPLAY_ID, bool mustStartIme = false); void UnBindClientWithIme(const std::shared_ptr ¤tClientInfo, const DetachOptions &options); void StopClientInput( const std::shared_ptr &clientInfo, bool isStopInactiveClient = false, bool isAsync = false); @@ -228,6 +229,7 @@ private: int32_t StartCurrentIme(const std::shared_ptr &ime); int32_t StartNewIme(const std::shared_ptr &ime); int32_t StartInputService(const std::shared_ptr &ime); + int32_t StartInputServiceTask(const std::shared_ptr &imeToStart); int32_t ForceStopCurrentIme(bool isNeedWait = true); int32_t StopReadyCurrentIme(); int32_t HandleFirstStart(const std::shared_ptr &ime, bool isStopCurrentIme); diff --git a/services/include/user_session_manager.h b/services/include/user_session_manager.h index 69fb2b64b..508b81121 100644 --- a/services/include/user_session_manager.h +++ b/services/include/user_session_manager.h @@ -26,14 +26,12 @@ public: std::shared_ptr GetUserSession(int32_t userId); void AddUserSession(int32_t userId); void RemoveUserSession(int32_t userId); - void SetEventHandler(const std::shared_ptr &eventHandler); private: UserSessionManager() = default; ~UserSessionManager() = default; std::mutex userSessionsLock_; std::unordered_map> userSessions_; - std::shared_ptr eventHandler_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/src/client_group.cpp b/services/src/client_group.cpp index 3c8852eee..7efd210ff 100644 --- a/services/src/client_group.cpp +++ b/services/src/client_group.cpp @@ -339,6 +339,18 @@ int32_t ClientGroup::NotifyImeChangeToClients(const Property &property, const Su return ErrorCode::NO_ERROR; } +void ClientGroup::NotifyServiceResponse( + uint32_t requestId, int32_t result, const sptr &client, const ServiceResponseData &responseData) +{ + auto clientInfo = GetClientInfo(client); + auto clientProxy = clientInfo != nullptr ? clientInfo->client : nullptr; + if (clientProxy != nullptr) { + ServiceResponseDataInner inner; + inner.data = responseData; + clientProxy->OnResponse(requestId, result, inner); + } +} + bool ClientGroup::IsCurClientUnFocused(int32_t pid, int32_t uid) { auto clientInfo = GetCurrentClientInfo(); diff --git a/services/src/full_ime_info_manager.cpp b/services/src/full_ime_info_manager.cpp index bd00b0ed1..53cdfdaea 100644 --- a/services/src/full_ime_info_manager.cpp +++ b/services/src/full_ime_info_manager.cpp @@ -20,6 +20,7 @@ #include "ime_info_inquirer.h" #include "inputmethod_message_handler.h" #include "message.h" +#include "sa_task_manager.h" namespace OHOS { namespace MiscServices { constexpr uint32_t TIMER_TASK_INTERNAL = 1 * 60 * 60 * 1000; // updated hourly @@ -39,10 +40,11 @@ FullImeInfoManager::FullImeInfoManager() } timerId_ = timer_.Register( []() { - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_REGULAR_UPDATE_IME_INFO, nullptr); - if (msg != nullptr) { - MessageHandler::Instance()->SendMessage(msg); - } + auto task = [](ServiceResponseData &data) -> int32_t { + FullImeInfoManager::GetInstance().RegularInit(); + return ErrorCode::NO_ERROR; + }; + SaTaskManager::GetInstance().PostTask() }, TIMER_TASK_INTERNAL, false); } diff --git a/services/src/im_common_event_manager.cpp b/services/src/im_common_event_manager.cpp index 0861e98e9..cd5b2a4fd 100644 --- a/services/src/im_common_event_manager.cpp +++ b/services/src/im_common_event_manager.cpp @@ -22,57 +22,54 @@ #include "os_account_adapter.h" #include "system_ability_definition.h" +#include "sa_task_manager.h" + namespace OHOS { namespace MiscServices { using namespace MessageID; -sptr ImCommonEventManager::instance_; -std::mutex ImCommonEventManager::instanceLock_; using namespace OHOS::EventFwk; constexpr const char *COMMON_EVENT_INPUT_PANEL_STATUS_CHANGED = "usual.event.imf.input_panel_status_changed"; constexpr const char *COMMON_EVENT_PARAM_USER_ID = "userId"; constexpr const char *COMMON_EVENT_PARAM_PANEL_STATE = "panelState"; constexpr const char *COMMON_EVENT_PARAM_PANEL_RECT = "panelRect"; -ImCommonEventManager::ImCommonEventManager() -{ -} - -ImCommonEventManager::~ImCommonEventManager() +const std::unordered_map EVENT_TASK_CODE{ + { CommonEventSupport::COMMON_EVENT_USER_SWITCHED, SaTaskCode::ON_USER_STARTED }, + { CommonEventSupport::COMMON_EVENT_USER_REMOVED, SaTaskCode::ON_USER_REMOVED }, + { CommonEventSupport::COMMON_EVENT_USER_STOPPED, SaTaskCode::ON_USER_STOPPED }, + { CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED, SaTaskCode::ON_PACKAGE_ADDED }, + { CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED, SaTaskCode::ON_PACKAGE_CHANGED }, + { CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED, SaTaskCode::ON_PACKAGE_REMOVED }, + { CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED, SaTaskCode::ON_BUNDLE_SCAN_FINISHED }, + { CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY, SaTaskCode::ON_DATA_SHARE_READY }, + { CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED, SaTaskCode::ON_BOOT_COMPLETED }, + { CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED, SaTaskCode::ON_SCREEN_UNLOCKED }, +}; +ImCommonEventManager & ImCommonEventManager::GetInstance() { + static ImCommonEventManager imCommonEventManager; + return imCommonEventManager; } -sptr ImCommonEventManager::GetInstance() +void ImCommonEventManager::RegisterHandler(const std::string &event, const CommonEventHandler &handler) { - if (instance_ == nullptr) { - std::lock_guard autoLock(instanceLock_); - if (instance_ == nullptr) { - IMSA_HILOGI("instance_ is nullptr."); - instance_ = new (std::nothrow) ImCommonEventManager(); - } - } - return instance_; + std::lock_guard lock(handlersMutex_); + eventHandlers_.insert_or_assign(event, handler); } bool ImCommonEventManager::SubscribeEvent() { EventFwk::MatchingSkills matchingSkills; - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_STOPPED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED); - + { + std::lock_guard lock(handlersMutex_); + for (const auto &eventHandler : eventHandlers_) { + matchingSkills.AddEvent(eventHandler.first); + } + } EventFwk::CommonEventSubscribeInfo subscriberInfo(matchingSkills); - std::shared_ptr subscriber = std::make_shared(subscriberInfo); - auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (abilityManager == nullptr) { - IMSA_HILOGE("SubscribeEvent abilityManager is nullptr!"); - return false; + { + std::lock_guard lock(handlersMutex_); + subscriber->SetHandlers(eventHandlers_); } sptr listener = new (std::nothrow) SystemAbilityStatusChangeListener([subscriber]() { bool subscribeResult = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber); @@ -82,6 +79,11 @@ bool ImCommonEventManager::SubscribeEvent() IMSA_HILOGE("SubscribeEvent listener is nullptr!"); return false; } + auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (abilityManager == nullptr) { + IMSA_HILOGE("SubscribeEvent abilityManager is nullptr!"); + return false; + } int32_t ret = abilityManager->SubscribeSystemAbility(COMMON_EVENT_SERVICE_ID, listener); if (ret != ERR_OK) { IMSA_HILOGE("SubscribeEvent SubscribeSystemAbility failed. ret: %{public}d", ret); @@ -131,216 +133,42 @@ bool ImCommonEventManager::SubscribeAccountManagerService(Handler handler) return SubscribeManagerServiceCommon(handler, SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN); } -bool ImCommonEventManager::UnsubscribeEvent() -{ - return true; -} - -ImCommonEventManager::EventSubscriber::EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo) - : EventFwk::CommonEventSubscriber(subscribeInfo) -{ - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_SWITCHED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->StartUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_STOPPED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->StopUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_REMOVED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->RemoveUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->RemovePackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnBundleScanFinished(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnDataShareReady(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->AddPackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->ChangePackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->HandleBootCompleted(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnScreenUnlock(data); - }; -} - void ImCommonEventManager::EventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data) { auto const &want = data.GetWant(); - std::string action = want.GetAction(); - IMSA_HILOGD("ImCommonEventManager::action: %{public}s!", action.c_str()); - auto iter = EventManagerFunc_.find(action); - if (iter != EventManagerFunc_.end()) { - EventManagerFunc_[action] (this, data); - } -} - -void ImCommonEventManager::EventSubscriber::StopUser(const CommonEventData &data) -{ - HandleUserEvent(MessageID::MSG_ID_USER_STOP, data); -} - -void ImCommonEventManager::EventSubscriber::StartUser(const CommonEventData &data) -{ - HandleUserEvent(MessageID::MSG_ID_USER_START, data); -} - -void ImCommonEventManager::EventSubscriber::RemoveUser(const CommonEventData &data) -{ - HandleUserEvent(MessageID::MSG_ID_USER_REMOVED, data); -} - -void ImCommonEventManager::EventSubscriber::HandleUserEvent(int32_t messageId, const EventFwk::CommonEventData &data) -{ - auto userId = data.GetCode(); - MessageParcel *parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { + std::string eventName = want.GetAction(); + IMSA_HILOGD("ImCommonEventManager::action: %{public}s!", eventName.c_str()); + auto handler = GetHandler(eventName); + if (handler == nullptr) { return; } - IMSA_HILOGD("userId:%{public}d, messageId:%{public}d", userId, messageId); - parcel->WriteInt32(userId); - Message *msg = new (std::nothrow) Message(messageId, parcel); - if (msg == nullptr) { - delete parcel; + auto iter = EVENT_TASK_CODE.find(eventName); + if (iter == EVENT_TASK_CODE.end()) { + IMSA_HILOGE("event not found"); return; } - MessageHandler::Instance()->SendMessage(msg); + SaTaskCode code = iter->second; + auto task = [handler, data](ServiceResponseData &) -> int32_t { + handler(data); + return ErrorCode::NO_ERROR; + }; + SaTaskManager::GetInstance().PostTask(std::make_shared(code, task)); } -void ImCommonEventManager::EventSubscriber::OnBundleScanFinished(const EventFwk::CommonEventData &data) +void ImCommonEventManager::EventSubscriber::SetHandlers(std::map handlers) { - IMSA_HILOGI("ImCommonEventManager start."); - auto parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { - IMSA_HILOGE("failed to create MessageParcel!"); - return; - } - auto msg = new (std::nothrow) Message(MessageID::MSG_ID_BUNDLE_SCAN_FINISHED, parcel); - if (msg == nullptr) { - IMSA_HILOGE("failed to create Message!"); - delete parcel; - return; - } - MessageHandler::Instance()->SendMessage(msg); + std::lock_guard lock(handlersMutex_); + eventHandlers_ = handlers; } -void ImCommonEventManager::EventSubscriber::OnDataShareReady(const EventFwk::CommonEventData &data) +CommonEventHandler ImCommonEventManager::EventSubscriber::GetHandler(const std::string &event) { - IMSA_HILOGI("ImCommonEventManager start."); - auto parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { - IMSA_HILOGE("failed to create MessageParcel!"); - return; - } - auto msg = new (std::nothrow) Message(MessageID::MSG_ID_DATA_SHARE_READY, parcel); - if (msg == nullptr) { - IMSA_HILOGE("failed to create Message!"); - delete parcel; - return; - } - MessageHandler::Instance()->SendMessage(msg); -} - -void ImCommonEventManager::EventSubscriber::RemovePackage(const CommonEventData &data) -{ - HandlePackageEvent(MessageID::MSG_ID_PACKAGE_REMOVED, data); -} - -void ImCommonEventManager::EventSubscriber::AddPackage(const EventFwk::CommonEventData &data) -{ - HandlePackageEvent(MessageID::MSG_ID_PACKAGE_ADDED, data); -} - -void ImCommonEventManager::EventSubscriber::ChangePackage(const EventFwk::CommonEventData &data) -{ - HandlePackageEvent(MessageID::MSG_ID_PACKAGE_CHANGED, data); -} - -void ImCommonEventManager::EventSubscriber::HandlePackageEvent(int32_t messageId, const EventFwk::CommonEventData &data) -{ - auto const &want = data.GetWant(); - auto element = want.GetElement(); - std::string bundleName = element.GetBundleName(); - int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); - if (userId == OsAccountAdapter::INVALID_USER_ID) { - IMSA_HILOGE("invalid user id, messageId:%{public}d", messageId); - return; - } - if (messageId == MessageID::MSG_ID_PACKAGE_REMOVED) { - if (!FullImeInfoManager::GetInstance().Has(userId, bundleName)) { - return; - } - } else { - if (!ImeInfoInquirer::GetInstance().IsInputMethod(userId, bundleName)) { - return; - } - } - MessageParcel *parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { - IMSA_HILOGE("parcel is nullptr!"); - return; - } - if (!ITypesUtil::Marshal(*parcel, userId, bundleName)) { - IMSA_HILOGE("Failed to write message parcel!"); - delete parcel; - return; - } - Message *msg = new (std::nothrow) Message(messageId, parcel); - if (msg == nullptr) { - IMSA_HILOGE("failed to create Message!"); - delete parcel; - return; - } - MessageHandler::Instance()->SendMessage(msg); -} - -void ImCommonEventManager::EventSubscriber::HandleBootCompleted(const EventFwk::CommonEventData &data) -{ - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_BOOT_COMPLETED, nullptr); - if (msg == nullptr) { - return; - } - MessageHandler::Instance()->SendMessage(msg); -} - -void ImCommonEventManager::EventSubscriber::OnScreenUnlock(const EventFwk::CommonEventData &data) -{ - MessageParcel *parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { - IMSA_HILOGE("parcel is nullptr!"); - return; - } - auto const &want = data.GetWant(); - int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); - if (!ITypesUtil::Marshal(*parcel, userId)) { - IMSA_HILOGE("Failed to write message parcel!"); - delete parcel; - return; - } - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_SCREEN_UNLOCK, parcel); - if (msg == nullptr) { - IMSA_HILOGE("failed to create Message!"); - delete parcel; - return; + std::lock_guard lock(handlersMutex_); + auto iter = eventHandlers_.find(event); + if (iter == eventHandlers_.end()) { + return nullptr; } - MessageHandler::Instance()->SendMessage(msg); + return iter->second; } ImCommonEventManager::SystemAbilityStatusChangeListener::SystemAbilityStatusChangeListener(std::function func) diff --git a/services/src/ime_cfg_manager.cpp b/services/src/ime_cfg_manager.cpp index 2c95ab8c6..c7f5d7f97 100644 --- a/services/src/ime_cfg_manager.cpp +++ b/services/src/ime_cfg_manager.cpp @@ -21,7 +21,6 @@ namespace MiscServices { namespace { constexpr const char *IME_CFG_FILE_PATH = "/data/service/el1/public/imf/ime_cfg.json"; } // namespace -std::shared_ptr ImeCfgManager::serviceHandler_ = nullptr; ImeCfgManager &ImeCfgManager::GetInstance() { static ImeCfgManager instance; @@ -48,26 +47,6 @@ void ImeCfgManager::ReadImeCfg() ParseImeCfg(cfg); } -void ImeCfgManager::WriteImeCfg() -{ - auto content = PackageImeCfg(); - if (content.empty()) { - IMSA_HILOGE("failed to Package imeCfg!"); - return; - } - if (serviceHandler_ == nullptr) { - IMSA_HILOGE("serviceHandler_ is nullptr!"); - return; - } - auto task = [content]() { - IMSA_HILOGD("start WriteJsonFile!"); - if (!FileOperator::Write(IME_CFG_FILE_PATH, content, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC)) { - IMSA_HILOGE("failed to WriteJsonFile!"); - } - }; - serviceHandler_->PostTask(task, "WriteImeCfg", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); -} - bool ImeCfgManager::ParseImeCfg(const std::string &content) { IMSA_HILOGD("content: %{public}s", content.c_str()); @@ -113,18 +92,6 @@ void ImeCfgManager::ModifyTempScreenLockImeCfg(int32_t userId, const std::string ImeEnabledInfoManager::GetInstance().SetTmpIme(userId, ime); } -void ImeCfgManager::DeleteImeCfg(int32_t userId) -{ - std::lock_guard lock(imeCfgLock_); - for (auto iter = imeConfigs_.begin(); iter != imeConfigs_.end(); iter++) { - if (iter->userId == userId) { - imeConfigs_.erase(iter); - break; - } - } - WriteImeCfg(); -} - ImePersistInfo ImeCfgManager::GetImeCfg(int32_t userId) { std::lock_guard lock(imeCfgLock_); @@ -148,10 +115,5 @@ bool ImeCfgManager::IsDefaultImeSet(int32_t userId) IMSA_HILOGI("isDefaultImeSet: %{public}d", ret); return ret; } - -void ImeCfgManager::SetEventHandler(const std::shared_ptr &eventHandler) -{ - serviceHandler_ = eventHandler; -} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/src/input_control_channel_service_impl.cpp b/services/src/input_control_channel_service_impl.cpp index 49e65de28..b5d041c94 100644 --- a/services/src/input_control_channel_service_impl.cpp +++ b/services/src/input_control_channel_service_impl.cpp @@ -15,10 +15,11 @@ #include "input_control_channel_service_impl.h" -#include "ipc_skeleton.h" #include "inputmethod_message_handler.h" -#include "message_parcel.h" +#include "ipc_skeleton.h" #include "os_account_adapter.h" +#include "sa_task_manager.h" +#include "user_session_manager.h" namespace OHOS { namespace MiscServices { @@ -35,17 +36,15 @@ ErrCode InputControlChannelServiceImpl::HideKeyboardSelf() if (userId == OsAccountAdapter::INVALID_USER_ID) { return ErrorCode::ERROR_EX_ILLEGAL_STATE; } - MessageParcel *parcel = new (std::nothrow) MessageParcel(); - if (parcel == nullptr) { - return ErrorCode::ERROR_NULL_POINTER; - } - parcel->WriteInt32(userId); - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_HIDE_KEYBOARD_SELF, parcel); - if (msg == nullptr) { - delete parcel; - return ErrorCode::ERROR_NULL_POINTER; - } - MessageHandler::Instance()->SendMessage(msg); + auto task = [userId](ServiceResponseData &) -> int32_t { + auto session = UserSessionManager::GetInstance().GetUserSession(userId); + if (session == nullptr) { + return ErrorCode::ERROR_NULL_POINTER; + } + session->OnHideSoftKeyBoardSelf(); + return ErrorCode::NO_ERROR; + }; + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::HIDE_KEYBOARD_SELF, task)); return ERR_OK; } } // namespace MiscServices diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 685f09b7e..2b293bee4 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -50,11 +50,15 @@ #include "display_info.h" #include "input_method_tools.h" #include "ime_state_manager_factory.h" +#include "requester_manager.h" +#include "sa_task_manager.h" +#include "variant_util.h" namespace OHOS { namespace MiscServices { using namespace MessageID; using namespace AppExecFwk; +using namespace OHOS::EventFwk; using namespace Security::AccessToken; using namespace std::chrono; using namespace HiviewDFX; @@ -69,6 +73,7 @@ constexpr uint32_t START_SA_TIMEOUT = 6; // 6s constexpr const char *SELECT_DIALOG_ACTION = "action.system.inputmethodchoose"; constexpr const char *SELECT_DIALOG_HAP = "com.ohos.inputmethodchoosedialog"; constexpr const char *SELECT_DIALOG_ABILITY = "InputMethod"; +constexpr uint32_t MAX_REQUEST_COUNT = 6; #ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE constexpr const char *UNLOAD_SA_TASK = "unloadInputMethodSaTask"; constexpr int64_t DELAY_UNLOAD_SA_TIME = 20000; // 20s @@ -89,9 +94,6 @@ InputMethodSystemAbility::~InputMethodSystemAbility() stop_ = true; Message *msg = new Message(MessageID::MSG_ID_QUIT_WORKER_THREAD, nullptr); MessageHandler::Instance()->SendMessage(msg); - if (workThreadHandler.joinable()) { - workThreadHandler.join(); - } } #ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE @@ -403,6 +405,7 @@ void InputMethodSystemAbility::OnStop() UserSessionManager::GetInstance().SetEventHandler(nullptr); ImeEnabledInfoManager::GetInstance().SetEventHandler(nullptr); ImeCfgManager::GetInstance().SetEventHandler(nullptr); + SaTaskManager::GetInstance().Reset(); serviceHandler_ = nullptr; state_ = ServiceRunningState::STATE_NOT_START; Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, INPUT_METHOD_SYSTEM_ABILITY_ID); @@ -418,7 +421,6 @@ void InputMethodSystemAbility::InitServiceHandler() std::shared_ptr runner = AppExecFwk::EventRunner::Create("OS_InputMethodSystemAbility"); serviceHandler_ = std::make_shared(runner); ImeStateManager::SetEventHandler(serviceHandler_); - ImeEnabledInfoManager::GetInstance().SetEventHandler(serviceHandler_); IMSA_HILOGI("InitServiceHandler succeeded."); } @@ -429,12 +431,8 @@ void InputMethodSystemAbility::InitServiceHandler() void InputMethodSystemAbility::Initialize() { IMSA_HILOGI("InputMethodSystemAbility::Initialize."); - // init work thread to handle the messages - workThreadHandler = std::thread([this] { this->WorkThread(); }); identityChecker_ = std::make_shared(); userId_ = OsAccountAdapter::MAIN_USER_ID; - UserSessionManager::GetInstance().SetEventHandler(serviceHandler_); - ImeCfgManager::GetInstance().SetEventHandler(serviceHandler_); UserSessionManager::GetInstance().AddUserSession(userId_); InputMethodSysEvent::GetInstance().SetUserId(userId_); IMSA_HILOGI("start get scene board enable status"); @@ -517,16 +515,26 @@ int32_t InputMethodSystemAbility::SwitchByCondition(const Condition &condition, void InputMethodSystemAbility::SubscribeCommonEvent() { - sptr imCommonEventManager = ImCommonEventManager::GetInstance(); - bool isSuccess = imCommonEventManager->SubscribeEvent(); - if (isSuccess) { - IMSA_HILOGI("initialize subscribe service event success."); - return; - } - - IMSA_HILOGE("failed, try again 10s later!"); - auto callback = [this]() { SubscribeCommonEvent(); }; - serviceHandler_->PostTask(callback, INIT_INTERVAL); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_USER_SWITCHED, + [this](const EventFwk::CommonEventData &data) { OnUserStarted(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_USER_REMOVED, + [this](const EventFwk::CommonEventData &data) { OnUserRemoved(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_USER_STOPPED, + [this](const EventFwk::CommonEventData &data) { OnUserStop(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED, + [this](const EventFwk::CommonEventData &data) { OnPackageAdded(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED, + [this](const EventFwk::CommonEventData &data) { OnPackageChanged(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED, + [this](const EventFwk::CommonEventData &data) { OnPackageRemoved(data); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED, + [this](const EventFwk::CommonEventData &data) { OnBundleScanFinished(); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY, + [this](const EventFwk::CommonEventData &data) { OnDataShareReady(); }); + ImCommonEventManager::GetInstance().RegisterHandler(CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED, + [this](const EventFwk::CommonEventData &data) { OnScreenUnlock(data); }); + + ImCommonEventManager::GetInstance().SubscribeEvent(); } int32_t InputMethodSystemAbility::PrepareInput(int32_t userId, InputClientInfo &clientInfo) @@ -595,40 +603,69 @@ ErrCode InputMethodSystemAbility::ReleaseInput(const sptr& client, return session->OnReleaseInput(client, sessionId); } -ErrCode InputMethodSystemAbility::StartInput( - const InputClientInfoInner &inputClientInfoInner, sptr &agent, int64_t &pid, std::string &bundleName) +ErrCode InputMethodSystemAbility::RegisterResponseChannel(sptr channel) { - InputClientInfo inputClientInfo = - InputMethodTools::GetInstance().InnerToInputClientInfo(inputClientInfoInner); - agent = nullptr; - pid = 0; - bundleName = ""; - std::pair imeInfo{ pid, bundleName }; - auto ret = StartInputInner(const_cast(inputClientInfo), agent, imeInfo); - IMSA_HILOGD("HiSysEvent report start!"); - auto evenInfo = HiSysOriginalInfo::Builder() - .SetPeerName(ImfHiSysEventUtil::GetAppName(IPCSkeleton::GetCallingTokenID())) - .SetPeerPid(IPCSkeleton::GetCallingPid()) - .SetPeerUserId(GetCallingUserId()) - .SetClientType(inputClientInfo.type) - .SetInputPattern(inputClientInfo.attribute.inputPattern) - .SetIsShowKeyboard(inputClientInfo.isShowKeyboard) - .SetImeName(imeInfo.second) - .SetErrCode(ret) - .Build(); - ImsaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::CLIENT_ATTACH, *evenInfo); - IMSA_HILOGE("HiSysEvent report end!"); + return RequesterManager::GetInstance().Add(IPCSkeleton::GetCallingPid(), channel); +} + +ErrCode InputMethodSystemAbility::StartInput(uint32_t requestId, const InputClientInfoInner &inputClientInfoInner) +{ + CallerInfo callerInfo = GetCallerInfo(requestId); + auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); + if (requester == nullptr) { + return ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND; + } + auto clientInfo = InputMethodTools::GetInstance().InnerToInputClientInfo(inputClientInfoInner); + + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc action = [callerInfo, clientInfo, weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + StartInputResponse response; + auto ret = sharedThis->StartInputTask(callerInfo, clientInfo, response); + data = response; + return ret; + }; + + ReportFunc reporter = [callerInfo, clientInfo, weakThis](int32_t ret, const ServiceResponseData &data) { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + StartInputResponse response; + if (!VariantUtil::GetValue(data, response)) { + return ErrorCode::ERROR_IMSA_NULLPTR; + } + sharedThis->ReportStartInput(callerInfo, clientInfo, response, ret); + }; + auto reportAction = std::make_unique(reporter); + + auto task = std::make_shared(SaTaskCode::START_INPUT, action, callerInfo, requester->channel); + task->SetReportAction(std::move(reportAction)); + SaTaskManager::GetInstance().PostTask(task); + return ErrorCode::NO_ERROR; +} + +int32_t InputMethodSystemAbility::StartInputTask( + const CallerInfo &callerInfo, InputClientInfo clientInfo, StartInputResponse &response) +{ + auto imeInfo = GetCurrentImeInfoForHiSysEvent(callerInfo.userId); + response.Set(nullptr, imeInfo.first, imeInfo.second); + auto ret = StartInputInner(callerInfo, clientInfo, response); return ret; } int32_t InputMethodSystemAbility::StartInputInner( - InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo) + const CallerInfo &callerInfo, InputClientInfo &inputClientInfo, StartInputResponse &response) { - auto userId = GetCallingUserId(); - imeInfo = GetCurrentImeInfoForHiSysEvent(userId); - AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID(); - if (!identityChecker_->IsBroker(tokenId) && !identityChecker_->IsFocused(IPCSkeleton::GetCallingPid(), tokenId, - IdentityChecker::INVALID_PID, true, inputClientInfo.config.abilityToken)) { + auto userId = callerInfo.userId; + if (!identityChecker_->IsBroker(callerInfo.tokenId) + && !identityChecker_->IsFocused(callerInfo.pid, callerInfo.tokenId, IdentityChecker::INVALID_PID, true, + inputClientInfo.config.abilityToken)) { return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; } auto session = UserSessionManager::GetInstance().GetUserSession(userId); @@ -636,9 +673,9 @@ int32_t InputMethodSystemAbility::StartInputInner( IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; } - auto displayId = GetCallingDisplayId(); - if (session->GetCurrentClientPid(displayId) != IPCSkeleton::GetCallingPid() - && session->GetInactiveClientPid(displayId) != IPCSkeleton::GetCallingPid()) { + auto displayId = GetCallingDisplayId(callerInfo.pid); + if (session->GetCurrentClientPid(displayId) != callerInfo.pid + && session->GetInactiveClientPid(displayId) != callerInfo.pid) { // notify inputStart when caller pid different from both current client and inactive client inputClientInfo.isNotifyInputStart = true; } @@ -653,14 +690,14 @@ int32_t InputMethodSystemAbility::StartInputInner( return ret; } } - inputClientInfo.config.inputAttribute.bundleName = identityChecker_->GetBundleNameByToken(tokenId); + inputClientInfo.config.inputAttribute.bundleName = identityChecker_->GetBundleNameByToken(callerInfo.tokenId); int32_t ret = PrepareInput(userId, inputClientInfo); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to PrepareInput!"); return ret; } session->SetInputType(); - return session->OnStartInput(inputClientInfo, agent, imeInfo); + return session->OnStartInput(inputClientInfo, response); } int32_t InputMethodSystemAbility::CheckInputTypeOption(int32_t userId, InputClientInfo &inputClientInfo) @@ -827,16 +864,38 @@ ErrCode InputMethodSystemAbility::RequestHideInput(bool isFocusTriggered) return session->OnRequestHideInput(pid, GetCallingDisplayId()); } -ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr &core, const sptr &agent) +ErrCode InputMethodSystemAbility::SetCoreAndAgent( + uint32_t requestId, const sptr &core, const sptr &agent) +{ + CallerInfo callerInfo = GetCallerInfo(requestId); + auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); + if (requester == nullptr) { + return ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND; + } + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc action = [core, agent, weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + return sharedThis->SetCoreAndAgentTask(core, agent); + }; + auto task = std::make_shared(SaTaskCode::SET_CORE_AND_AGENT, action, callerInfo, requester->channel); + SaTaskManager::GetInstance().PostTask(task); +} + +int32_t InputMethodSystemAbility::SetCoreAndAgentTask( + const CallerInfo &callerInfo, const sptr &core, const sptr &agent) { IMSA_HILOGD("InputMethodSystemAbility start."); - auto userId = GetCallingUserId(); + auto userId = callerInfo.userId; auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_NULL_POINTER; } - if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { + if (identityChecker_->IsNativeSa(callerInfo.tokenId)) { return session->OnRegisterProxyIme(core, agent); } if (!IsCurrentIme(userId)) { @@ -1140,7 +1199,29 @@ int32_t InputMethodSystemAbility::DisplayOptionalInputMethod() return OnDisplayOptionalInputMethod(); } -ErrCode InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleName, +ErrCode InputMethodSystemAbility::SwitchInputMethod( + uint32_t requestId, const std::string &bundleName, const std::string &subName, uint32_t trigger) +{ + CallerInfo callerInfo = GetCallerInfo(requestId); + auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); + if (requester == nullptr) { + return ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND; + } + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc action = [bundleName, subName, trigger, weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + return sharedThis->SwitchInputMethodTask(bundleName, subName, trigger); + }; + auto task = std::make_shared(SaTaskCode::SWITCH_INPUT_METHOD, action, callerInfo, requester->channel); + SaTaskManager::GetInstance().PostTask(task); + return ErrorCode::NO_ERROR; +} + +int32_t InputMethodSystemAbility::SwitchInputMethodTask(const std::string &bundleName, const std::string &subName, uint32_t trigger) { // IMSA not check permission, add this verify for prevent counterfeit @@ -1298,29 +1379,16 @@ void InputMethodSystemAbility::GetValidSubtype(const std::string &subName, const int32_t InputMethodSystemAbility::OnStartInputType(int32_t userId, const SwitchInfo &switchInfo, bool isCheckPermission) { - auto session = UserSessionManager::GetInstance().GetUserSession(userId); - if (session == nullptr) { - IMSA_HILOGE("%{public}d session is nullptr!", userId); - return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; - } - if (!session->GetSwitchQueue().IsReady(switchInfo)) { - IMSA_HILOGD("start wait."); - session->GetSwitchQueue().Wait(switchInfo); - } IMSA_HILOGD("start switch %{public}s|%{public}s.", switchInfo.bundleName.c_str(), switchInfo.subName.c_str()); if (isCheckPermission && !IsStartInputTypePermitted(userId)) { IMSA_HILOGE("not permitted to start input type!"); - session->GetSwitchQueue().Pop(); return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; } if (!IsNeedSwitch(userId, switchInfo.bundleName, switchInfo.subName)) { IMSA_HILOGI("no need to switch."); - session->GetSwitchQueue().Pop(); return ErrorCode::NO_ERROR; } - int32_t ret = SwitchInputType(userId, switchInfo); - session->GetSwitchQueue().Pop(); - return ret; + return SwitchInputType(userId, switchInfo); } bool InputMethodSystemAbility::IsNeedSwitch(int32_t userId, const std::string &bundleName, @@ -1341,91 +1409,44 @@ bool InputMethodSystemAbility::IsNeedSwitch(int32_t userId, const std::string &b return true; } -int32_t InputMethodSystemAbility::Switch(int32_t userId, const std::string &bundleName, - const std::shared_ptr &info) -{ - auto currentImeBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; - if (bundleName != currentImeBundleName) { - IMSA_HILOGI("switch input method to: %{public}s", bundleName.c_str()); - return SwitchExtension(userId, info); - } - auto currentInputType = InputTypeManager::GetInstance().GetCurrentIme(); - auto isInputTypeStarted = InputTypeManager::GetInstance().IsStarted(); - if (isInputTypeStarted && bundleName != currentInputType.bundleName) { - IMSA_HILOGI("right click on state, switch input method to: %{public}s", bundleName.c_str()); - return SwitchExtension(userId, info); - } - return SwitchSubType(userId, info); -} - -// Switch the current InputMethodExtension to the new InputMethodExtension -int32_t InputMethodSystemAbility::SwitchExtension(int32_t userId, const std::shared_ptr &info) -{ - auto session = UserSessionManager::GetInstance().GetUserSession(userId); - if (session == nullptr) { - IMSA_HILOGE("%{public}d session is nullptr!", userId); - return ErrorCode::ERROR_NULL_POINTER; - } - std::string targetImeName = info->prop.name + "/" + info->prop.id; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, info->subProp.id, false }); - ImeNativeCfg targetIme = { targetImeName, info->prop.name, info->subProp.id, info->prop.id }; - auto ret = session->StartIme(std::make_shared(targetIme)); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("start input method failed!"); - return ret; - } - session->NotifyImeChangeToClients(info->prop, info->subProp); - GetValidSubtype("", info); - session->SwitchSubtype(info->subProp); - return ErrorCode::NO_ERROR; -} - -// Inform current InputMethodExtension to switch subtype -int32_t InputMethodSystemAbility::SwitchSubType(int32_t userId, const std::shared_ptr &info) -{ - auto session = UserSessionManager::GetInstance().GetUserSession(userId); - if (session == nullptr) { - IMSA_HILOGE("%{public}d session is nullptr!", userId); - return ErrorCode::ERROR_NULL_POINTER; - } - auto ret = session->SwitchSubtype(info->subProp); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("failed to inform ime to switch subtype, ret: %{public}d!", ret); - return ret; - } - auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->imeId; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, currentIme, info->subProp.id, false }); - session->NotifyImeChangeToClients(info->prop, info->subProp); - return ErrorCode::NO_ERROR; -} - int32_t InputMethodSystemAbility::SwitchInputType(int32_t userId, const SwitchInfo &switchInfo) { - auto session = UserSessionManager::GetInstance().GetUserSession(userId); - if (session == nullptr) { - IMSA_HILOGE("%{public}d session is nullptr!", userId); - return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; - } - auto targetIme = session->GetImeNativeCfg(userId, switchInfo.bundleName, switchInfo.subName); - if (targetIme == nullptr) { - IMSA_HILOGE("targetIme is nullptr!"); - return ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED; - } - auto ret = session->StartIme(targetIme); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("start input method failed!"); - return ret; - } - SubProperty prop; - prop.name = switchInfo.bundleName; - prop.id = switchInfo.subName; - ret = session->SwitchSubtype(prop); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("switch subtype failed!"); - return ret; - } - InputTypeManager::GetInstance().Set(true, { switchInfo.bundleName, switchInfo.subName }); - session->SetInputType(); + SaActionFunc doStart = [userId, switchInfo](ServiceResponseData &data) -> int32_t { + auto session = UserSessionManager::GetInstance().GetUserSession(userId); + if (session == nullptr) { + IMSA_HILOGE("%{public}d session is nullptr!", userId); + return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; + } + auto targetIme = session->GetImeNativeCfg(userId, switchInfo.bundleName, switchInfo.subName); + if (targetIme == nullptr) { + IMSA_HILOGE("targetIme is nullptr!"); + return ErrorCode::ERROR_IMSA_GET_IME_INFO_FAILED; + } + auto ret = session->StartIme(targetIme); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("start input method failed!"); + return ret; + } + }; + SaActionFunc afterStart = [switchInfo, userId](ServiceResponseData &data) -> int32_t { + auto session = UserSessionManager::GetInstance().GetUserSession(userId); + if (session == nullptr) { + IMSA_HILOGE("%{public}d session is nullptr!", userId); + return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; + } + SubProperty prop; + prop.name = switchInfo.bundleName; + prop.id = switchInfo.subName; + auto ret = session->SwitchSubtypeWithoutStartIme(prop); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("switch subtype failed!"); + return ret; + } + InputTypeManager::GetInstance().Set(true, { switchInfo.bundleName, switchInfo.subName }); + session->SetInputType(); + return ErrorCode::NO_ERROR; + }; + SaTaskManager::GetInstance().Pend(doStart, afterStart); return ErrorCode::NO_ERROR; } @@ -1510,85 +1531,9 @@ int32_t InputMethodSystemAbility::ListInputMethodSubtype(const std::string &bund return ImeInfoInquirer::GetInstance().ListInputMethodSubtype(GetCallingUserId(), bundleName, subProps); } -/** - * Work Thread of input method management service - * \n Remote commands which may change the state or data in the service will be handled sequentially in this thread. - */ -void InputMethodSystemAbility::WorkThread() -{ - pthread_setname_np(pthread_self(), "OS_IMSAWorkThread"); - while (!stop_) { - Message *msg = MessageHandler::Instance()->GetMessage(); - switch (msg->msgId_) { - case MSG_ID_USER_START: { - OnUserStarted(msg); - break; - } - case MSG_ID_USER_REMOVED: { - OnUserRemoved(msg); - break; - } - case MSG_ID_USER_STOP: { - OnUserStop(msg); - break; - } - case MSG_ID_HIDE_KEYBOARD_SELF: { - OnHideKeyboardSelf(msg); - break; - } - case MSG_ID_BUNDLE_SCAN_FINISHED: { - HandleBundleScanFinished(); - break; - } - case MSG_ID_DATA_SHARE_READY: { - HandleDataShareReady(); - break; - } - case MSG_ID_PACKAGE_ADDED: - case MSG_ID_PACKAGE_CHANGED: - case MSG_ID_PACKAGE_REMOVED: { - HandlePackageEvent(msg); - break; - } - case MSG_ID_SYS_LANGUAGE_CHANGED: { - FullImeInfoManager::GetInstance().Update(); - break; - } - case MSG_ID_BOOT_COMPLETED: - case MSG_ID_OS_ACCOUNT_STARTED: { - FullImeInfoManager::GetInstance().Init(); - break; - } - case MSG_ID_SCREEN_UNLOCK: { - OnScreenUnlock(msg); - break; - } - case MSG_ID_REGULAR_UPDATE_IME_INFO: { - FullImeInfoManager::GetInstance().RegularInit(); - break; - } - default: { - IMSA_HILOGD("the message is %{public}d.", msg->msgId_); - break; - } - } - delete msg; - } -} - -/** - * Called when a user is started. (EVENT_USER_STARTED is received) - * \n Run in work thread of input method management service - * \param msg the parameters are saved in msg->msgContent_ - * \return ErrorCode - */ -int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg) +int32_t InputMethodSystemAbility::OnUserStarted(const EventFwk::CommonEventData &data) { - if (msg->msgContent_ == nullptr) { - IMSA_HILOGE("msgContent_ is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; - } - auto newUserId = msg->msgContent_->ReadInt32(); + auto newUserId = data.GetCode(); FullImeInfoManager::GetInstance().Switch(newUserId); // if scb enable, deal when receive wmsConnected. if (isScbEnable_.load()) { @@ -1601,13 +1546,9 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg) return ErrorCode::NO_ERROR; } -int32_t InputMethodSystemAbility::OnUserRemoved(const Message *msg) +int32_t InputMethodSystemAbility::OnUserRemoved(const EventFwk::CommonEventData &data) { - if (msg == nullptr || msg->msgContent_ == nullptr) { - IMSA_HILOGE("Aborted! Message is nullptr!"); - return ErrorCode::ERROR_NULL_POINTER; - } - auto userId = msg->msgContent_->ReadInt32(); + auto userId = data.GetCode(); IMSA_HILOGI("start: %{public}d", userId); auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session != nullptr) { @@ -1619,76 +1560,59 @@ int32_t InputMethodSystemAbility::OnUserRemoved(const Message *msg) return ErrorCode::NO_ERROR; } -int32_t InputMethodSystemAbility::OnUserStop(const Message *msg) +int32_t InputMethodSystemAbility::OnUserStop(const EventFwk::CommonEventData &data) { - auto session = GetSessionFromMsg(msg); + auto userId = data.GetCode(); + IMSA_HILOGI("start: %{public}d", userId); + auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { - return ErrorCode::ERROR_NULL_POINTER; + IMSA_HILOGE("%{public}d session is nullptr!", userId); + return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; } session->StopCurrentIme(); return ErrorCode::NO_ERROR; } -int32_t InputMethodSystemAbility::OnHideKeyboardSelf(const Message *msg) +void InputMethodSystemAbility::OnPackageAdded(const EventFwk::CommonEventData &data) { - auto session = GetSessionFromMsg(msg); - if (session == nullptr) { - return ErrorCode::ERROR_NULL_POINTER; + auto const &want = data.GetWant(); + auto bundleName = want.GetElement().GetBundleName(); + int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); + if (userId == OsAccountAdapter::INVALID_USER_ID) { + IMSA_HILOGE("invalid user id"); + return; } - session->OnHideSoftKeyBoardSelf(); - return ErrorCode::NO_ERROR; + FullImeInfoManager::GetInstance().Add(userId, bundleName); } -int32_t InputMethodSystemAbility::HandlePackageEvent(const Message *msg) +void InputMethodSystemAbility::OnPackageChanged(const EventFwk::CommonEventData &data) { - MessageParcel *data = msg->msgContent_; - if (data == nullptr) { - IMSA_HILOGD("data is nullptr"); - return ErrorCode::ERROR_NULL_POINTER; - } - int32_t userId = 0; - std::string packageName; - if (!ITypesUtil::Unmarshal(*data, userId, packageName)) { - IMSA_HILOGE("Failed to read message parcel!"); - return ErrorCode::ERROR_EX_PARCELABLE; - } - if (msg->msgId_ == MSG_ID_PACKAGE_CHANGED) { - return FullImeInfoManager::GetInstance().Update(userId, packageName); - } - if (msg->msgId_ == MSG_ID_PACKAGE_ADDED) { - return FullImeInfoManager::GetInstance().Add(userId, packageName); - } - if (msg->msgId_ == MSG_ID_PACKAGE_REMOVED) { - return OnPackageRemoved(userId, packageName); + auto const &want = data.GetWant(); + auto bundleName = want.GetElement().GetBundleName(); + int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); + if (userId == OsAccountAdapter::INVALID_USER_ID) { + IMSA_HILOGE("invalid user id"); + return; } - return ErrorCode::NO_ERROR; + FullImeInfoManager::GetInstance().Update(userId, bundleName); } -/** - * Called when a package is removed. - * \n Run in work thread of input method management service - * \param msg the parameters are saved in msg->msgContent_ - * \return ErrorCode::NO_ERROR - * \return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked - * \return ErrorCode::ERROR_BAD_PARAMETERS bad parameter - */ -int32_t InputMethodSystemAbility::OnPackageRemoved(int32_t userId, const std::string &packageName) +void InputMethodSystemAbility::OnPackageRemoved(const EventFwk::CommonEventData &data) { - FullImeInfoManager::GetInstance().Delete(userId, packageName); - return ErrorCode::NO_ERROR; + auto const &want = data.GetWant(); + auto bundleName = want.GetElement().GetBundleName(); + int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); + if (userId == OsAccountAdapter::INVALID_USER_ID) { + IMSA_HILOGE("invalid user id"); + return; + } + FullImeInfoManager::GetInstance().Delete(userId, bundleName); } -void InputMethodSystemAbility::OnScreenUnlock(const Message *msg) +void InputMethodSystemAbility::OnScreenUnlock(const EventFwk::CommonEventData &data) { - if (msg == nullptr || msg->msgContent_ == nullptr) { - IMSA_HILOGE("message is nullptr"); - return; - } - int32_t userId = 0; - if (!ITypesUtil::Unmarshal(*msg->msgContent_, userId)) { - IMSA_HILOGE("failed to read message"); - return; - } + auto const &want = data.GetWant(); + int32_t userId = want.GetIntParam("userId", OsAccountAdapter::INVALID_USER_ID); IMSA_HILOGI("userId: %{public}d", userId); if (userId != userId_) { return; @@ -1770,21 +1694,26 @@ void InputMethodSystemAbility::DealSwitchRequest() ++targetSwitchCount_; } } - auto switchTask = [this]() { - auto checkSwitchCount = [this]() { + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc switchTask = [weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + auto checkSwitchCount = [sharedThis]() { std::lock_guard lock(switchImeMutex_); - if (targetSwitchCount_ > 0) { + if (sharedThis->targetSwitchCount_ > 0) { return true; } - switchTaskExecuting_.store(false); + sharedThis->switchTaskExecuting_.store(false); return false; }; do { - SwitchType(); + sharedThis->SwitchType(); } while (checkSwitchCount()); }; - // 0 means delay time is 0. - serviceHandler_->PostTask(switchTask, "SwitchImeTask", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::SWITCH_INPUT_METHOD, switchTask)); } int32_t InputMethodSystemAbility::SwitchMode() @@ -1867,7 +1796,7 @@ void InputMethodSystemAbility::InitMonitors() InitSystemLanguageMonitor(); } -void InputMethodSystemAbility::HandleDataShareReady() +void InputMethodSystemAbility::OnDataShareReady() { IMSA_HILOGI("run in."); if (ImeInfoInquirer::GetInstance().GetSystemConfig().enableFullExperienceFeature) { @@ -1964,12 +1893,11 @@ void InputMethodSystemAbility::DataShareCallback(const std::string &key) if (key != SettingsDataUtils::SECURITY_MODE) { return; } - IMSA_HILOGI("%{public}d full experience change.", userId_); - if (serviceHandler_ == nullptr) { - return; - } - auto task = [userId = userId_]() { ImeEnabledInfoManager::GetInstance().OnFullExperienceTableChanged(userId); }; - serviceHandler_->PostTask(task, "OnFullExperienceTableChanged", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); + SaActionFunc func = [userId = userId_](ServiceResponseData &data) -> int32_t { + IMSA_HILOGI("%{public}d full experience change.", userId_); + ImeEnabledInfoManager::GetInstance().OnFullExperienceTableChanged(userId); + }; + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::ON_DATA_SHARE_CALLBACK, func)); } void InputMethodSystemAbility::OnCurrentImeStatusChanged( @@ -2148,13 +2076,23 @@ int32_t InputMethodSystemAbility::ConnectSystemCmd(const sptr &ch void InputMethodSystemAbility::HandleWmsConnected(int32_t userId, int32_t screenId) { - if (userId == userId_) { - // device boot or scb in foreground reboot - HandleScbStarted(userId, screenId); - return; - } - // user switched - HandleUserSwitched(userId); + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc func = [userId, screenId, weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + if (userId == sharedThis->userId_) { + // device boot or scb in foreground reboot + sharedThis->HandleScbStarted(userId, screenId); + return ErrorCode::NO_ERROR; + } + // user switched + sharedThis->HandleUserSwitched(userId); + return ErrorCode::NO_ERROR; + }; + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::ON_WMS_CONNECTED, func)); } void InputMethodSystemAbility::HandleScbStarted(int32_t userId, int32_t screenId) @@ -2255,32 +2193,51 @@ void InputMethodSystemAbility::HandleMemStarted() void InputMethodSystemAbility::HandleOsAccountStarted() { - IMSA_HILOGI("account start"); - auto userId = OsAccountAdapter::GetForegroundOsAccountLocalId(); - if (userId_ != userId) { - UpdateUserInfo(userId); - } - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_OS_ACCOUNT_STARTED, nullptr); - if (msg == nullptr) { - return; - } - MessageHandler::Instance()->SendMessage(msg); + std::weak_ptr weakThis = shared_from_this(); + auto func = [weakThis](ServiceResponseData &data) -> int32_t { + IMSA_HILOGI("account start"); + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + auto userId = OsAccountAdapter::GetForegroundOsAccountLocalId(); + if (sharedThis->userId_ != userId) { + sharedThis->UpdateUserInfo(userId); + } + FullImeInfoManager::GetInstance().Init(); + }; + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::ON_OS_ACCOUNT_STARTED, func)); } void InputMethodSystemAbility::StopImeInBackground() { - auto task = [this]() { + std::weak_ptr weakThis = shared_from_this(); + auto func = [weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } auto sessions = UserSessionManager::GetInstance().GetUserSessions(); for (const auto &tempSession : sessions) { - if (tempSession.first != userId_) { + if (tempSession.first != sharedThis->userId_) { tempSession.second->StopCurrentIme(); } } }; - if (serviceHandler_ == nullptr) { - return; - } - serviceHandler_->PostTask(task, "StopImeInBackground", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); + SaTaskManager::GetInstance().PostTask(std::make_shared(SaTaskCode::STOP_IME_IN_BACKGROUND, func)); +} + +CallerInfo InputMethodSystemAbility::GetCallerInfo(uint32_t requestId) +{ + auto uid = IPCSkeleton::GetCallingUid(); + return { .requestId = requestId, + .pid = IPCSkeleton::GetCallingPid(), + .uid = uid, + .userId = GetUserId(uid), + .tokenId = IPCSkeleton::GetCallingTokenID(), + .fullTokenId = IPCSkeleton::GetCallingFullTokenID() }; } int32_t InputMethodSystemAbility::GetUserId(int32_t uid) @@ -2306,6 +2263,11 @@ uint64_t InputMethodSystemAbility::GetCallingDisplayId(sptr abili return identityChecker_->GetDisplayIdByPid(IPCSkeleton::GetCallingPid(), abilityToken); } +uint64_t InputMethodSystemAbility::GetCallingDisplayId(int32_t callingPid, sptr abilityToken) +{ + return identityChecker_->GetDisplayIdByPid(callingPid, abilityToken); +} + bool InputMethodSystemAbility::IsCurrentIme(int32_t userId) { auto session = UserSessionManager::GetInstance().GetUserSession(userId); @@ -2372,7 +2334,7 @@ void InputMethodSystemAbility::NeedHideWhenSwitchInputType(int32_t userId, Input needHide = imeData->ime.first == ime.bundleName; } -void InputMethodSystemAbility::HandleBundleScanFinished() +void InputMethodSystemAbility::OnBundleScanFinished() { isBundleScanFinished_.store(true); HandleImeCfgCapsState(); @@ -2637,5 +2599,23 @@ int32_t InputMethodSystemAbility::StartSecurityIme(int32_t &userId, InputClientI } return ErrorCode::NO_ERROR; } + +void InputMethodSystemAbility::ReportStartInput( + const CallerInfo &callerInfo, const InputClientInfo &clientInfo, const StartInputResponse &response, int32_t ret) +{ + IMSA_HILOGD("HiSysEvent report start!"); + auto evenInfo = HiSysOriginalInfo::Builder() + .SetPeerName(ImfHiSysEventUtil::GetAppName(IPCSkeleton::GetCallingTokenID())) + .SetPeerPid(callerInfo.pid) + .SetPeerUserId(callerInfo.userId) + .SetClientType(clientInfo.type) + .SetInputPattern(clientInfo.attribute.inputPattern) + .SetIsShowKeyboard(clientInfo.isShowKeyboard) + .SetImeName(response.bundleName) + .SetErrCode(ret) + .Build(); + ImsaHiSysEventReporter::GetInstance().ReportEvent(ImfEventType::CLIENT_ATTACH, *evenInfo); + IMSA_HILOGE("HiSysEvent report end!"); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 8d64d2f5d..beb41590e 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -45,6 +45,7 @@ #include "window_adapter.h" #include "input_method_tools.h" #include "ime_state_manager_factory.h" +#include "sa_task_manager.h" namespace OHOS { namespace MiscServices { @@ -61,10 +62,7 @@ constexpr int32_t MAX_RESTART_NUM = 3; constexpr int32_t IME_RESET_TIME_OUT = 3; constexpr int32_t MAX_RESTART_TASKS = 2; constexpr const char *UNDEFINED = "undefined"; -PerUserSession::PerUserSession(int userId) : userId_(userId) { } - -PerUserSession::PerUserSession(int32_t userId, const std::shared_ptr &eventHandler) - : userId_(userId), eventHandler_(eventHandler) +PerUserSession::PerUserSession(int32_t userId) : userId_(userId) { // if bms not start, AppMgrClient::GetProcessRunningInfosByUserId will blocked if (IsSaReady(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID)) { @@ -197,7 +195,8 @@ void PerUserSession::OnClientDied(sptr remote) * It's called when an ime died * @param the remote object handler of the ime who died. */ -void PerUserSession::OnImeDied(const sptr &remote, ImeType type) +void PerUserSession::OnImeDied( + const sptr &remote, ImeType type, const std::string &bundleName, pid_t pid) { if (remote == nullptr) { return; @@ -517,8 +516,7 @@ bool PerUserSession::IsProxyImeEnable() return ret; } -int32_t PerUserSession::OnStartInput( - const InputClientInfo &inputClientInfo, sptr &agent, std::pair &imeInfo) +int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, StartInputResponse &response) { const sptr &client = inputClientInfo.client; if (client == nullptr) { @@ -547,7 +545,7 @@ int32_t PerUserSession::OnStartInput( infoTemp.requestKeyboardReason = inputClientInfo.requestKeyboardReason; infoTemp.config.requestKeyboardReason = inputClientInfo.requestKeyboardReason; int32_t ret = - BindClientWithIme(std::make_shared(infoTemp), imeType, true, inputClientInfo.displayId); + BindClientWithIme(std::make_shared(infoTemp), imeType, true, inputClientInfo.displayId, true); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("bind failed, ret: %{public}d!", ret); return ret; @@ -557,13 +555,12 @@ int32_t PerUserSession::OnStartInput( IMSA_HILOGE("data or agent is nullptr!"); return ErrorCode::ERROR_IME_NOT_STARTED; } - agent = data->agent; - imeInfo = { data->pid, data->ime.first }; + response.Set(data->agent, data->pid, data->ime.first); return ErrorCode::NO_ERROR; } -int32_t PerUserSession::BindClientWithIme( - const std::shared_ptr &clientInfo, ImeType type, bool isBindFromClient, uint64_t displayId) +int32_t PerUserSession::BindClientWithIme(const std::shared_ptr &clientInfo, ImeType type, + bool isBindFromClient, uint64_t displayId, bool mustStartIme) { if (clientInfo == nullptr) { IMSA_HILOGE("clientInfo is nullptr!"); @@ -576,7 +573,7 @@ int32_t PerUserSession::BindClientWithIme( } IMSA_HILOGD("imeType: %{public}d, isShowKeyboard: %{public}d, isBindFromClient: %{public}d.", type, clientInfo->isShowKeyboard, isBindFromClient); - auto data = GetValidIme(type); + auto data = mustStartIme ? GetValidIme(type) : GetReadyImeData(type); if (data == nullptr) { return ErrorCode::ERROR_IME_NOT_STARTED; } @@ -680,7 +677,8 @@ void PerUserSession::OnSecurityChange(int32_t security) IMSA_HILOGD("on security change, ret: %{public}d.", ret); } -int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, const sptr &agent) +int32_t PerUserSession::OnSetCoreAndAgent( + const CallerInfo &callerInfo, const sptr &core, const sptr &agent) { IMSA_HILOGI("start."); auto ret = UpdateImeData(core, agent, IPCSkeleton::GetCallingPid()); @@ -703,8 +701,7 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, co BindClientWithIme(clientInfo, imeType); SetInputType(); } - bool isStarted = true; - isImeStarted_.SetValue(isStarted); + SaTaskManager::GetInstance().TryResume(PauseType::PAUSE_TYPE_START_IME, callerInfo); return ErrorCode::NO_ERROR; } @@ -1184,26 +1181,44 @@ int32_t PerUserSession::StartInputService(const std::shared_ptr &i return ret; } InitImeData({ imeToStart->bundleName, imeToStart->extName }, ime); - isImeStarted_.Clear(false); + ret = StartInputServiceTask(imeToStart); + if (ret != ErrorCode::NO_ERROR) { + return ret; + } + + SaActionFunc onComplete = [imeToStart](ServiceResponseData &data) -> int32_t { + IMSA_HILOGI("%{public}s started successfully.", imeToStart->imeId.c_str()); + InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::START_IME); + return ErrorCode::NO_ERROR; + }; + SaActionFunc onTimeout = [imeToStart](ServiceResponseData &data) -> int32_t { + IMSA_HILOGE("start %{public}s timeout!", imeToStart->imeId.c_str()); + return ErrorCode::ERROR_IMSA_IME_START_TIMEOUT; + }; + PauseInfo info = { .state = PauseType::PAUSE_FOR_START_IME, .target = imeToStart->bundleName }; + auto waitAction = std::make_unique(MAX_IME_START_TIME, info, onComplete, onTimeout); + SaTaskManager::GetInstance().WaitExec(std::move(waitAction)); + return ErrorCode::NO_ERROR; +} + +int32_t PerUserSession::StartInputServiceTask(const std::shared_ptr &imeToStart) +{ + if (imeToStart == nullptr) { + return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR; + } sptr connection = new (std::nothrow) ImeConnection(); if (connection == nullptr) { IMSA_HILOGE("failed to create connection!"); return ErrorCode::ERROR_IMSA_MALLOC_FAILED; } auto want = GetWant(imeToStart); - ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_); + auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("connect %{public}s failed, ret: %{public}d!", imeToStart->imeId.c_str(), ret); InputMethodSysEvent::GetInstance().InputmethodFaultReporter( ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, imeToStart->imeId, "failed to start ability."); return ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED; } - if (!isImeStarted_.GetValue()) { - IMSA_HILOGE("start %{public}s timeout!", imeToStart->imeId.c_str()); - return ErrorCode::ERROR_IMSA_IME_START_TIMEOUT; - } - IMSA_HILOGI("%{public}s started successfully.", imeToStart->imeId.c_str()); - InputMethodSysEvent::GetInstance().RecordEvent(IMEBehaviour::START_IME); return ErrorCode::NO_ERROR; } @@ -1364,7 +1379,7 @@ int32_t PerUserSession::SwitchSubtypeWithoutStartIme(const SubProperty &subPrope int32_t PerUserSession::SetInputType() { InputType inputType = InputTypeManager::GetInstance().GetCurrentInputType(); - auto data = GetValidIme(ImeType::IME); + auto data = GetReadyImeData(ImeType::IME); if (data == nullptr) { IMSA_HILOGE("ime: %{public}d is not exist!", ImeType::IME); return ErrorCode::ERROR_IME_NOT_STARTED; @@ -1416,7 +1431,7 @@ int32_t PerUserSession::RestoreCurrentImeSubType(uint64_t callingDisplayId) subProp = *subPropTemp; } IMSA_HILOGD("same ime, restore subtype: %{public}s.", cfgIme->subName.c_str()); - return SwitchSubtype(subProp); + return SwitchSubtypeWithoutStartIme(subProp); } bool PerUserSession::IsCurrentImeByPid(int32_t pid) @@ -1570,28 +1585,31 @@ void PerUserSession::AddRestartIme() bool PerUserSession::RestartIme() { - auto task = [this]() { - if (CanStartIme()) { - auto ret = StartCurrentIme(true); + std::weak_ptr weakThis = shared_from_this(); + auto func = [weakThis](ServiceResponseData &data) -> int32_t { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return ErrorCode::ERROR_NULL_POINTER; + } + if (sharedThis->CanStartIme()) { + auto ret = sharedThis->StartCurrentIme(true); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("start ime failed!"); } } int32_t tasks = 0; { - std::lock_guard lock(restartMutex_); - tasks = --restartTasks_; + std::lock_guard lock(sharedThis->restartMutex_); + tasks = --sharedThis->restartTasks_; } - if (tasks > 0 && !RestartIme()) { - std::lock_guard lock(restartMutex_); - restartTasks_ = 0; + if (tasks > 0 && !sharedThis->RestartIme()) { + std::lock_guard lock(sharedThis->restartMutex_); + sharedThis->restartTasks_ = 0; } }; - if (eventHandler_ == nullptr) { - IMSA_HILOGE("eventHandler_ is nullptr!"); - return false; - } - return eventHandler_->PostTask(task, "RestartCurrentImeTask", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); + auto task = std::make_shared(SaTaskCode::RESTART_CURRENT_IME, func); + return SaTaskManager::GetInstance().PostTask(task) != 0; } BlockQueue& PerUserSession::GetSwitchQueue() @@ -1643,7 +1661,10 @@ int32_t PerUserSession::UpdateImeData(sptr core, sptrSetDeathRecipient([this, core, type](const wptr &) { this->OnImeDied(core, type); }); + std::string bundleName = it->second->ime.first; + deathRecipient->SetDeathRecipient([this, core, type, bundleName, pid](const wptr &) { + this->OnImeDied(core, type, bundleName, pid); + }); auto coreObject = core->AsObject(); if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) { IMSA_HILOGE("failed to add death recipient!"); @@ -2103,7 +2124,7 @@ int32_t PerUserSession::NotifyCallingDisplayChanged(uint64_t displayId) IMSA_HILOGD("not default display"); return ErrorCode::NO_ERROR; } - auto data = GetValidIme(ImeType::IME); + auto data = GetReadyImeData(ImeType::IME); if (data == nullptr) { IMSA_HILOGE("ime is nullptr!"); return ErrorCode::ERROR_IME_NOT_STARTED; diff --git a/services/src/user_session_manager.cpp b/services/src/user_session_manager.cpp index 23001ff1a..b3b135b46 100644 --- a/services/src/user_session_manager.cpp +++ b/services/src/user_session_manager.cpp @@ -47,7 +47,7 @@ void UserSessionManager::AddUserSession(int32_t userId) if (session != userSessions_.end()) { return; } - auto sessionTemp = std::make_shared(userId, eventHandler_); + auto sessionTemp = std::make_shared(userId); userSessions_.insert({ userId, sessionTemp }); } @@ -56,10 +56,5 @@ void UserSessionManager::RemoveUserSession(int32_t userId) std::lock_guard lock(userSessionsLock_); userSessions_.erase(userId); } - -void UserSessionManager::SetEventHandler(const std::shared_ptr &eventHandler) -{ - eventHandler_ = eventHandler; -} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/task_manager/include/actions/sa_action.h b/services/task_manager/include/actions/sa_action.h new file mode 100644 index 000000000..313c28e70 --- /dev/null +++ b/services/task_manager/include/actions/sa_action.h @@ -0,0 +1,93 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_SA_ACTION_H +#define IMF_SERVICES_SA_ACTION_H + +#include +#include +#include + +#include "action.h" +#include "service_response_data.h" + +namespace OHOS { +namespace MiscServices { +enum class PauseType : int32_t { + PAUSED_TYPE_INVALID = -1, + PAUSE_TYPE_START_IME = 0, + PAUSE_TYPE_STOP_IME, +}; + +struct PauseInfo { + PauseType type{ PauseType::PAUSED_TYPE_INVALID }; // pause state + pid_t pid{ 0 }; // pid of waiting target + std::string target; // bundleName of waiting target + uint64_t resumeId{ 0 }; + inline std::string ToString() const + { + std::stringstream ss; + ss << "PausedInfo:[" + << "type: " << static_cast(type) << " pid: " << static_cast(pid) + << " target: " << target.c_str() << " resumeId: " << resumeId << "]"; + } +}; + +using SaActionFunc = std::function; +class SaAction { +public: + SaAction() = default; + explicit SaAction(SaActionFunc func) : func_(std::move(func)) + { + } + ~SaAction() = default; + + virtual RunningState Execute(int32_t &ret, ServiceResponseData &responseData) + { + if (state_ != RUNNING_STATE_IDLE) { + return RUNNING_STATE_ERROR; + } + state_ = RUNNING_STATE_RUNNING; + if (func_ != nullptr) { + ret = func_(responseData); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + + virtual RunningState Resume(uint64_t resumedId) + { + return state_; + } + + virtual PauseInfo GetPausedInfo() + { + return {}; + } + + RunningState GetState() + { + return state_; + } + +protected: + RunningState state_{ RUNNING_STATE_IDLE }; + +private: + SaActionFunc func_; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_SERVICES_SA_ACTION_H diff --git a/services/task_manager/include/actions/sa_action_report.h b/services/task_manager/include/actions/sa_action_report.h new file mode 100644 index 000000000..bcfd40e94 --- /dev/null +++ b/services/task_manager/include/actions/sa_action_report.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_SA_ACTION_REPORT_H +#define IMF_SERVICES_SA_ACTION_REPORT_H + +#include "sa_action.h" + +namespace OHOS { +namespace MiscServices { +using ReportFunc = std::function; +class SaActionReport : public SaAction { +public: + SaActionReport() = default; + explicit SaActionReport(ReportFunc func) : func_(std::move(func)) + { + } + ~SaActionReport() = default; + + RunningState Execute(int32_t ret, const ServiceResponseData &data) + { + if (state_ != RUNNING_STATE_IDLE) { + return RUNNING_STATE_ERROR; + } + + state_ = RUNNING_STATE_RUNNING; + if (func_) { + func_(ret, data); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + +private: + ReportFunc func_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // IMF_SERVICES_SA_ACTION_REPORT_H diff --git a/services/task_manager/include/actions/sa_action_wait.h b/services/task_manager/include/actions/sa_action_wait.h new file mode 100644 index 000000000..dd7a426e2 --- /dev/null +++ b/services/task_manager/include/actions/sa_action_wait.h @@ -0,0 +1,59 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_SA_ACTION_WAIT_H +#define IMF_SERVICES_SA_ACTION_WAIT_H + +#include + +#include "sa_action.h" +#include "sa_task.h" + +namespace OHOS { +namespace MiscServices { +class SaActionWait : public SaAction { +public: + SaActionWait(uint32_t timeoutMs, PauseInfo info) + : completeId_(SaTask::GetNextSeqId()), timeoutMs_(timeoutMs), pauseInfo_(std::move(info)), + timeoutId_(SaTask::GetNextSeqId()) + { + pauseInfo_.resumeId = completeId_; + } + SaActionWait(uint32_t timeoutMs, PauseInfo info, SaActionFunc onComplete, SaActionFunc onTimeout) + : completeId_(SaTask::GetNextSeqId()), timeoutMs_(timeoutMs), pauseInfo_(std::move(info)), + timeoutId_(SaTask::GetNextSeqId()), onComplete_(std::move(onComplete)), onTimeout_(std::move(onTimeout)) + { + pauseInfo_.resumeId = completeId_; + } + + ~SaActionWait() = default; + + RunningState Execute(int32_t &ret, ServiceResponseData &responseData) override; + + RunningState Resume(uint64_t resumedId) override; + + PauseInfo GetPausedInfo() override; + +private: + const uint32_t timeoutMs_; + const uint64_t completeId_; + const uint64_t timeoutId_; + SaActionFunc onComplete_; + SaActionFunc onTimeout_; + PauseInfo pauseInfo_{}; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_SERVICES_SA_ACTION_WAIT_H diff --git a/services/task_manager/include/caller_info.h b/services/task_manager/include/caller_info.h new file mode 100644 index 000000000..64007038d --- /dev/null +++ b/services/task_manager/include/caller_info.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef IMF_CALLER_INFO_H +#define IMF_CALLER_INFO_H + +#include + +#include + +#include "iresponse_channel.h" + +namespace OHOS { +namespace MiscServices { +static constexpr int32_t MAIN_USER_ID = 100; +struct CallerInfo { + uint32_t requestId = 0; + int32_t pid = 0; + int32_t uid = 0; + int32_t userId{ MAIN_USER_ID }; + uint32_t tokenId = 0; + uint64_t fullTokenId = 0; + std::string bundleName; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_CALLER_INFO_H diff --git a/services/task_manager/include/requester_manager.h b/services/task_manager/include/requester_manager.h new file mode 100644 index 000000000..59090ee87 --- /dev/null +++ b/services/task_manager/include/requester_manager.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_REQUESTER_MANAGER_H +#define IMF_SERVICES_REQUESTER_MANAGER_H + +#include + +#include +#include +#include + +#include "input_death_recipient.h" +#include "iremote_object.h" +#include "iresponse_channel.h" + +namespace OHOS { +namespace MiscServices { +struct RequesterInfo { + uint32_t requestCount{ 0 }; + sptr channel{ nullptr }; + sptr deathRecipient{ nullptr }; +}; + +class RequesterManager : public std::enable_shared_from_this { +private: + RequesterManager() = default; + +public: + ~RequesterManager() = default; + + RequesterManager(const RequesterManager &) = delete; + RequesterManager(RequesterManager &&) = delete; + RequesterManager &operator=(const RequesterManager &) = delete; + RequesterManager &operator=(RequesterManager &&) = delete; + + static RequesterManager &GetInstance(); + + std::shared_ptr GetRequester(int32_t pid); + int32_t Add(int32_t pid, sptr channel); + + void TaskIn(int32_t pid); + void TaskOut(int32_t pid); + +private: + void OnClientDied(int32_t pid); + std::mutex clientsMutex_; + std::unordered_map> requestClients_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // IMF_SERVICES_REQUESTER_MANAGER_H diff --git a/services/task_manager/include/sa_task_manager.h b/services/task_manager/include/sa_task_manager.h new file mode 100644 index 000000000..f3bb52ee0 --- /dev/null +++ b/services/task_manager/include/sa_task_manager.h @@ -0,0 +1,103 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_SA_TASK_MANAGER_H +#define IMF_SERVICES_SA_TASK_MANAGER_H + +#include "event_handler.h" +#include "input_method_utils.h" +#include "sa_action.h" +#include "sa_action_wait.h" +#include "sa_task.h" + +namespace OHOS { +namespace MiscServices { +using CallBack = std::function; + +using SaTaskPtr = std::shared_ptr; +using SaActionPtr = std::unique_ptr; + +class SaTaskManager final { +private: + SaTaskManager(); + +public: + ~SaTaskManager() = default; + + SaTaskManager(const SaTaskManager &) = delete; + SaTaskManager(SaTaskManager &&) = delete; + SaTaskManager &operator=(const SaTaskManager &) = delete; + SaTaskManager &operator=(SaTaskManager &&) = delete; + + static SaTaskManager &GetInstance(); + + // Post a task to work thread + uint64_t PostTask(SaTaskPtr task, uint32_t delayMs = 0); + + // Trigger task process async + void ProcessAsync(); + + // Resume paused task with seqId + void Complete(uint64_t resumeId); + + // Pend an action to current task during executing + int32_t Pend(SaActionPtr action); + int32_t Pend(const SaActionFunc &func); + + template int32_t Pend(Args &&... args); + + // Wait for task and execute + int32_t WaitExec(uint32_t timeoutMs, const PauseInfo &info, SaActionFunc execFunc); + int32_t WaitExec(std::unique_ptr waitAction, SaActionFunc execFunc = nullptr); + + void Reset(); + + void TryResume(const PauseType &pauseType, const CallerInfo &callerInfo); + +private: + friend class InputMethodSystemAbility; + friend class SaActionWait; + void SetInited(bool flag); + int32_t PendWaitResult(const SaActionFunc &func); + +private: + void OnNewTask(SaTaskPtr task); // Accept a new task + void Process(); // Process next task + + void ProcessNextCriticalTask(); + void ProcessNextSwitchImeTask(); + void ProcessNextRequestTask(); + void ProcessNextQueryTask(); + void ProcessNextInnerTask(); + void ProcessNextResumeTask(); + void ExecuteCurrentTask(); // Execute current task + +private: + bool IsWhiteListRequest(SaTaskCode taskCode); + bool inited_{ false }; + std::shared_ptr eventHandler_{ nullptr }; + + SaTaskPtr curTask_ = { nullptr }; + std::vector> tasks_; + std::list criticalTasks_; + std::list switchImeTasks_; + std::list requestTasks_; + std::list queryTasks_; + std::list innerTasks_; + std::list resumeTasks_; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_SERVICES_SA_TASK_MANAGER_H \ No newline at end of file diff --git a/services/task_manager/include/tasks/sa_task.h b/services/task_manager/include/tasks/sa_task.h new file mode 100644 index 000000000..b813a418b --- /dev/null +++ b/services/task_manager/include/tasks/sa_task.h @@ -0,0 +1,216 @@ +/* + * 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. + */ + +#ifndef IMF_SERVICES_SA_TASK_H +#define IMF_SERVICES_SA_TASK_H + +#include "caller_info.h" +#include "iresponse_channel.h" +#include "sa_action.h" +#include "sa_action_report.h" +#include "service_response_data.h" +#include "task.h" + +namespace OHOS { +namespace MiscServices { + +enum class SaTaskType : int32_t { + TYPE_CRITICAL_CHANGE = 0, + TYPE_SWITCH_IME = 1, + TYPE_IMMEDIATE_REQUEST = 2, + TYPE_NORMAL_REQUEST = 3, + TYPE_QUERY = 4, + TYPE_RESUME = 5, + TYPE_INNER = 6, + + TYPE_TOTAL_COUNT, + TYPE_INVALID = -1, +}; + +enum class SaTaskCode : uint32_t { + TASK_CRITICAL_CHANGE_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_CRITICAL_CHANGE)), + ON_OS_ACCOUNT_STARTED, + ON_USER_STARTED, + ON_USER_REMOVED, + ON_USER_STOPPED, + ON_WMS_START, + ON_WMS_CONNECTED, + ON_WMS_DISCONNECTED, + ON_BUNDLE_SCAN_FINISHED, + ON_DATA_SHARE_READY, + RESTART_CURRENT_IME, + STOP_IME_IN_BACKGROUND, + CURRENT_IME_STATUS_CHANGED, + TASK_CRITICAL_CHANGE_END, + + TASK_SWITCH_IME_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_SWITCH_IME)), + REGISTER_PROXY_IME, + UNREGISTERED_PROXY_IME, + SWITCH_INPUT_METHOD, + START_INPUT_TYPE, + EXIT_CURRENT_INPUT_TYPE, + ON_PACKAGE_REMOVED, + ON_SCREEN_UNLOCKED, + TASK_SWITCH_IME_END, + + TASK_IMMEDIATE_REQUEST_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_IMMEDIATE_REQUEST)), + ON_FOCUSED, + ON_UNFOCUSED, + ON_DISPLAY_ID_CHANGED, + ON_SYSTEM_LANGUAGE_CHANGED, + SUBSCRIBE_COMMON_EVENT, + TASK_IMMEDIATE_REQUEST_END, + + TASK_NORMAL_REQUEST_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_NORMAL_REQUEST)), + // from IPC + START_INPUT, + SHOW_CURRENT_INPUT, + HIDE_CURRENT_INPUT, + STOP_INPUT_SESSION, + SHOW_INPUT, + HIDE_INPUT, + RELEASE_INPUT, + REQUEST_SHOW_INPUT, + REQUEST_HIDE_INPUT, + CONNECT_SYSTEM_CMD, + SHOW_CURRENT_INPUT_DEPRECATED, + HIDE_CURRENT_INPUT_DEPRECATED, + HIDE_KEYBOARD_SELF, + SET_CALLING_WINDOW, + SEND_PRIVATE_DATA, + PANEL_STATUS_CHANGE, + UPDATE_LISTEN_EVENT_FLAG, + INIT_CONNECT, + TASK_NORMAL_REQUEST_END, + + TASK_QUERY_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_QUERY)), + GET_DEFAULT_INPUT_METHOD, + GET_INPUT_METHOD_CONFIG, + GET_CURRENT_INPUT_METHOD, + GET_CURRENT_INPUT_METHOD_SUBTYPE, + GET_INPUT_METHOD_STATE, + GET_INPUT_START_INFO, + GET_SECURITY_MODE, + + LIST_INPUT_METHOD, + LIST_CURRENT_INPUT_METHOD_SUBTYPE, + LIST_INPUT_METHOD_SUBTYPE, + + IS_CURRENT_IME, + IS_INPUT_TYPE_SUPPORTED, + IS_CURRENT_IME_BY_PID, + IS_PANEL_SHOWN, + IS_DEFAULT_IME, + IS_DEFAULT_IME_SET, + IS_SYSTEM_APP, + IS_DEFAULT_IME_SCREEN, + + ENABLE_IME, + UPDATE_GLOBAL_ENABLED_TABLE, + REGULAR_UPDATE_IME_INFO, + ON_DATA_SHARE_CALLBACK, + DISPLAY_OPTIONAL_INPUT_METHOD, + ON_PACKAGE_ADDED, + ON_PACKAGE_CHANGED, + ON_BOOT_COMPLETED, + TASK_QUERY_END, + + TASK_RESUME_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_RESUME)), + SET_CORE_AND_AGENT, + ON_IME_DIE, + TASK_RESUME_END, + + TASK_INNER_BEGIN = TASK_TYPE_OFFSET(static_cast(SaTaskType::TYPE_INNER)), + RESUME_WAIT, + RESUME_TIMEOUT, + TASK_INNER_END, +}; + +class SaTask { +public: + explicit SaTask(SaTaskCode code) : code_(code), seqId_(GetNextSeqId()), channel_(nullptr) + { + } + explicit SaTask(SaTaskCode code, uint64_t seqId) : code_(code), seqId_(seqId), channel_(nullptr) + { + } + SaTask(SaTaskCode code, SaActionFunc func) : code_(code), seqId_(GetNextSeqId()), channel_(nullptr) + { + actions_.emplace_back(std::make_unique(func)); + } + SaTask(SaTaskCode code, SaActionFunc func, CallerInfo info, sptr channel) + : code_(code), seqId_(GetNextSeqId()), callerInfo_(info), channel_(channel) + { + actions_.emplace_back(std::make_unique(func)); + } + ~SaTask(); + + static uint64_t GetNextSeqId(); + + void SetReportAction(std::unique_ptr action); + + RunningState Execute(); + RunningState Resume(uint64_t resumeId); + RunningState OnTask(const std::shared_ptr &task); + + // pend action to task + int32_t PendSingle(std::unique_ptr action); + int32_t PendSingle(SaActionFunc action); + template int32_t Pend(Args &&... args) + { + return (PendSingle(std::forward(args)) && ...); + } + + // get task info + SaTaskType GetType() const; + SaTaskCode GetCode() const; + uint64_t GetSeqId() const; + CallerInfo GetCallerInfo() const; + bool IsRunning() const; + bool IsPaused() const; + PauseInfo GetPauseInfo(); + + void OnResponse(); + void OnResponse(int32_t retCode); + +private: + RunningState ExecuteInner(); + void InvokeResponse(); + +protected: + static constexpr int32_t INVALID_FAIL_CODE = -1; + int32_t failCode_{ INVALID_FAIL_CODE }; + + int32_t curActionRet_{ ErrorCode::NO_ERROR }; + const SaTaskCode code_; + RunningState state_{ RUNNING_STATE_IDLE }; + const uint64_t seqId_; + std::unique_ptr curAction_{ nullptr }; + ServiceResponseData responseData_{ std::monstate{} }; + + std::list> actions_; + std::list> pendingActions_; + + std::unique_ptr resultReporter_{ nullptr }; + + bool isResponsed_{ false }; + + CallerInfo callerInfo_; + sptr channel_{ nullptr }; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // IMF_SERVICES_SA_TASK_H diff --git a/services/task_manager/src/actions/sa_action_wait.cpp b/services/task_manager/src/actions/sa_action_wait.cpp new file mode 100644 index 000000000..4e3c83bd3 --- /dev/null +++ b/services/task_manager/src/actions/sa_action_wait.cpp @@ -0,0 +1,63 @@ +/* + * 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 "sa_action_wait.h" + +#include + +#include "sa_task_manager.h" + +namespace OHOS { +namespace MiscServices { +RunningState SaActionWait::Execute(int32_t &ret, ServiceResponseData &responseData) +{ + state_ = RUNNING_STATE_PAUSED; + + auto task = std::make_shared(SaTaskCode::RESUME_TIMEOUT, timeoutId_); + SaTaskManager::GetInstance().PostTask(task, timeoutMs_); + ret = ErrorCode::NO_ERROR; +} + +RunningState SaActionWait::Resume(uint64_t resumedId) +{ + if (state_ != RUNNING_STATE_PAUSED) { + return RUNNING_STATE_ERROR; + } + + if (resumedId == completeId_) { + if (onComplete_ != nullptr) { + SaTaskManager::GetInstance().PendWaitResult(onComplete_); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + + if (resumedId == timeoutId_) { + if (onTimeout_ != nullptr) { + SaTaskManager::GetInstance().PendWaitResult(onTimeout_); + } + state_ = RUNNING_STATE_COMPLETED; + return state_; + } + + return state_; +} + +PauseInfo SaActionWait::GetPausedInfo() +{ + return pauseInfo_; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/task_manager/src/caller_info.cpp b/services/task_manager/src/caller_info.cpp new file mode 100644 index 000000000..9a2dac83a --- /dev/null +++ b/services/task_manager/src/caller_info.cpp @@ -0,0 +1,27 @@ +/* + * 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 "../include/caller_info.h" + +#include "ime_info_inquirer.h" + +namespace OHOS { +namespace MiscServices { +bool CallerInfo::IsCallerImeApp() +{ + ImeInfoInquirer::GetInstance().IsInputMethodExtension(pid); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/task_manager/src/requester_manager.cpp b/services/task_manager/src/requester_manager.cpp new file mode 100644 index 000000000..beb783026 --- /dev/null +++ b/services/task_manager/src/requester_manager.cpp @@ -0,0 +1,120 @@ +/* + * 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 "requester_manager.h" + +#include "global.h" + +namespace OHOS { +namespace MiscServices { +constexpr int32_t MAX_REQUEST_COUNT = 6; +RequesterManager &RequesterManager::GetInstance() +{ + static RequesterManager requesterManager; + return requesterManager; +} + +std::shared_ptr RequesterManager::GetRequester(int32_t pid) +{ + std::lock_guard lock(clientsMutex_); + auto iter = requestClients_.find(pid); + if (iter == requestClients_.end() || iter->second == nullptr || iter->second->channel == nullptr) { + IMSA_HILOGE("client: %{public}d not registered or nullptr", pid); + return nullptr; + } + auto requesterInfo = iter->second; + if (requesterInfo->requestCount >= MAX_REQUEST_COUNT) { + IMSA_HILOGE("requests from client: %{public}d, count: %{public}d, too much", pid, requesterInfo->requestCount); + return nullptr; + } + return requesterInfo; +} + +int32_t RequesterManager::Add(int32_t pid, sptr channel) +{ + std::lock_guard lock(clientsMutex_); + auto iter = requestClients_.find(pid); + if (iter != requestClients_.end() && iter->second != nullptr && iter->second->channel != nullptr) { + IMSA_HILOGE("client: %{public}d already registered", pid); + return ErrorCode::NO_ERROR; + } + auto info = std::make_shared(); + std::weak_ptr weakThis = shared_from_this(); + info->deathRecipient->SetDeathRecipient([pid, weakThis](const wptr &remote) { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return; + } + sharedThis->OnClientDied(pid); + }); + auto object = channel->AsObject(); + if (object == nullptr || (object->IsProxyObject() && !object->AddDeathRecipient(info->deathRecipient))) { + IMSA_HILOGE("failed to add death recipient"); + return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; + } + info->channel = channel; + requestClients_.insert_or_assign(pid, info); + IMSA_HILOGI("register success, pid: %{public}d", pid); +} + +void RequesterManager::TaskIn(int32_t pid) +{ + std::lock_guard lock(clientsMutex_); + auto iter = requestClients_.find(pid); + if (iter == requestClients_.end()) { + IMSA_HILOGE("client: %{public}d not found"); + return; + } + if (iter->second == nullptr) { + IMSA_HILOGE("pid %{public}d info nullptr", pid); + return; + } + ++iter->second->requestCount; +} + +void RequesterManager::TaskOut(int32_t pid) +{ + std::lock_guard lock(clientsMutex_); + auto iter = requestClients_.find(pid); + if (iter == requestClients_.end()) { + IMSA_HILOGE("client: %{public}d not found"); + return; + } + if (iter->second == nullptr) { + IMSA_HILOGE("pid %{public}d info nullptr", pid); + return; + } + --iter->second->requestCount; +} + +void RequesterManager::OnClientDied(int32_t pid) +{ + std::lock_guard lock(clientsMutex_); + IMSA_HILOGI("requester: %{public}d died", pid); + auto iter = requestClients_.find(pid); + if (iter == requestClients_.end()) { + IMSA_HILOGD("already removed"); + return; + } + auto info = iter->second; + if (info != nullptr && info->channel != nullptr && info->channel->AsObject() != nullptr) { + info->channel->AsObject()->RemoveDeathRecipient(info->deathRecipient); + } + requestClients_.erase(pid); + IMSA_HILOGI("requester: %{public}d removed", pid); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/task_manager/src/sa_task_manager.cpp b/services/task_manager/src/sa_task_manager.cpp new file mode 100644 index 000000000..8c8880eb5 --- /dev/null +++ b/services/task_manager/src/sa_task_manager.cpp @@ -0,0 +1,408 @@ +/* + * 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 "sa_task_manager.h" + +#include +#include + +#include "global.h" +#include "ime_info_inquirer.h" +#include "requester_manager.h" +#include "sa_action_wait.h" +#include "xcollie/watchdog.h" + +namespace OHOS { +namespace MiscServices { +using namespace AppExecFwk; +constexpr const char *THREAD_NAME = "OS_ImsaTaskHandler"; +constexpr int64_t DELAY_TIME = 0; +constexpr const uint64_t WATCHDOG_TIMEOUT = 10000; // 10S +SaTaskManager::SaTaskManager() +{ + // initialize the size of tasks_ with the value of TYPE_TOTAL_COUNT + tasks_.resize(static_cast(SaTaskType::TYPE_TOTAL_COUNT)); + + // initialized the event handler with 10s timeout watchdog + auto runner = EventRunner::Create(THREAD_NAME); + eventHandler_ = std::make_shared(runner); + auto ret = HiviewDFX::Watchdog::GetInstance().AddThread(THREAD_NAME, eventHandler_, nullptr, WATCHDOG_TIMEOUT); + if (ret != 0) { + IMSA_HILOGW("failed to add watch dog ret: %{public}d", ret); + } +} + +SaTaskManager &SaTaskManager::GetInstance() +{ + static SaTaskManager instance; + return instance; +} + +uint64_t SaTaskManager::PostTask(SaTaskPtr task, uint32_t delayMs) +{ + if (task == nullptr) { + IMSA_HILOGE("task is nullptr"); + return 0; + } + auto func = [this, task]() { OnNewTask(task); }; + eventHandler_->PostTask(func, __FUNCTION__, delayMs); + RequesterManager::GetInstance().TaskIn(task->GetCallerInfo().pid); + return task->GetSeqId(); +} + +void SaTaskManager::ProcessAsync() +{ + auto func = [=] { Process(); }; + eventHandler_->PostTask(func, __FUNCTION__); +} + +void SaTaskManager::Complete(uint64_t resumeId) +{ + PostTask(std::make_shared(SaTaskCode::RESUME_WAIT, resumeId)); +} + +int32_t SaTaskManager::Pend(SaActionPtr action) +{ + if (action == nullptr) { + IMSA_HILOGE("action is nullptr"); + return ErrorCode::ERROR_NULL_POINTER; + } + if (curTask_ == nullptr || !curTask_->IsRunning()) { + IMSA_HILOGE("curTask_ is NULL or not running, pend failed!"); + return ErrorCode::ERROR_IMSA_TASK_MANAGER_PEND_FAILED; + } + return curTask_->Pend(std::move(action)); +} + +int32_t SaTaskManager::Pend(const SaActionFunc &func) +{ + return Pend(std::make_unique(func)); +} + +template int32_t SaTaskManager::Pend(Args &&... args) +{ + if (curTask_ == nullptr || !curTask_->IsRunning()) { + IMSA_HILOGE("curTask_ is NULL or not running, pend failed!"); + return ErrorCode::ERROR_IMSA_TASK_MANAGER_PEND_FAILED; + } + return curTask_->Pend(std::forward(args)...); +} + +int32_t SaTaskManager::PendWaitResult(const SaActionFunc &func) +{ + auto action = std::make_unique(func); + if (curTask_ == nullptr || !curTask_->IsPaused()) { + IMSA_HILOGE("curTask_ is NULL or not paused, pend failed!"); + return ErrorCode::ERROR_IMSA_TASK_MANAGER_PEND_FAILED; + } + return curTask_->Pend(std::move(action)); +} + +int32_t SaTaskManager::WaitExec(uint32_t timeoutMs, const PauseInfo &info, SaActionFunc execFunc) +{ + auto wait = std::make_unique(timeoutMs, info); + int32_t ret = Pend(std::move(wait)); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Pend ActionWait failed, ret=%{public}d", ret); + return ret; + } + auto exec = std::make_unique(execFunc); + ret = Pend(std::move(execFunc)); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Pend Action failed, ret=%{public}d", ret); + return ret; + } + return ErrorCode::NO_ERROR; +} + +int32_t SaTaskManager::WaitExec(std::unique_ptr waitAction, SaActionFunc execFunc) +{ + if (waitAction == nullptr) { + IMSA_HILOGE("wait action nullptr"); + return ErrorCode::ERROR_IMSA_NULLPTR; + } + int32_t ret = Pend(std::move(waitAction)); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Pend ActionWait failed, ret: %{public}d", ret); + return ret; + } + + auto exec = std::make_unique(execFunc); + ret = Pend(std::move(execFunc)); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("Pend Action failed, ret=%{public}d", ret); + return ret; + } + return ErrorCode::NO_ERROR; +} + +void SaTaskManager::SetInited(bool flag) +{ + inited_ = flag; +} + +void SaTaskManager::OnNewTask(SaTaskPtr task) +{ + if (task == nullptr) { + IMSA_HILOGE("task is nullptr"); + return; + } + auto taskType = task->GetType(); + if (taskType <= SaTaskType::TYPE_INVALID || taskType >= SaTaskType::TYPE_TOTAL_COUNT) { + IMSA_HILOGE("task type %{public}d unknown!", taskType); + return; + } + tasks_[static_cast(taskType)].push_back(task); + Process(); +} + +void SaTaskManager::Process() +{ + ProcessNextCriticalTask(); + ProcessNextResumeTask(); + ProcessNextInnerTask(); + ProcessNextSwitchImeTask(); + ProcessNextRequestTask(); + ProcessNextQueryTask(); +} + +void SaTaskManager::ProcessNextCriticalTask() +{ + if (criticalTasks_.empty()) { + return; + } + // CRITICAL_CHANGE task has the highest priority. If curTask_ exists and is not CRITICAL_CHANGE task, drop it. + if (curTask_ != nullptr) { + if (curTask_->GetType() == SaTaskType::TYPE_CRITICAL_CHANGE && curTask_->IsPaused()) { + return; + } + curTask_.reset(); + } + + while (curTask_ == nullptr) { + if (criticalTasks_.empty()) { + return; + } + curTask_ = criticalTasks_.front(); + criticalTasks_.pop_front(); + ExecuteCurrentTask(); + } +} + +void SaTaskManager::ProcessNextSwitchImeTask() +{ + if (switchImeTasks_.empty()) { + return; + } + // SWITCH_IME task has a priority second to type CRITICAL_CHANGE. + if (curTask_ != nullptr) { + if ((curTask_->GetType() == SaTaskType::TYPE_CRITICAL_CHANGE + || curTask_->GetType() == SaTaskType::TYPE_SWITCH_IME) + && curTask_->IsPaused()) { + return; + } + curTask_.reset(); + } + + while (curTask_ == nullptr) { + if (switchImeTasks_.empty()) { + return; + } + curTask_ = switchImeTasks_.front(); + switchImeTasks_.pop_front(); + ExecuteCurrentTask(); + } +} + +void SaTaskManager::ProcessNextResumeTask() +{ + if (resumeTasks_.empty()) { + IMSA_HILOGD("resumeTasks_ empty, return"); + return; + } + // RESUME tasks can be executed when curTask_ exists. + auto pausedTask = std::move(curTask_); + while (curTask_ == nullptr && !resumeTasks_.empty()) { + curTask_ = resumeTasks_.front(); + resumeTasks_.pop_front(); + ExecuteCurrentTask(); + } + curTask_ = std::move(pausedTask); +} + +void SaTaskManager::ProcessNextInnerTask() +{ + while (curTask_ != nullptr) { + // curTask_ is not NULL, it must be paused + // Loop through innerTasks_, try resume + if (innerTasks_.empty()) { + IMSA_HILOGD("innerTasks_ empty, return"); + return; + } + + auto task = innerTasks_.front(); + innerTasks_.pop_front(); + auto state = curTask_->OnTask(task); + if (state == RUNNING_STATE_COMPLETED) { + // current task completed + curTask_.reset(); + innerTasks_.clear(); + return; + } + + if (state == RUNNING_STATE_PAUSED) { + // current task still paused, try next inner task + continue; + } + + // unreachable + IMSA_HILOGE("Unexpected OnTask result %{public}d", state); + curTask_.reset(); + innerTasks_.clear(); + } +} + +void SaTaskManager::ProcessNextRequestTask() +{ + if (!inited_) { + IMSA_HILOGW("not initialized yet"); + return; + } + if (requestTasks_.empty()) { + IMSA_HILOGD("requestTasks_ empty"); + return; + } + + // If curTask_ is NULL, execute requestTasks_ directly. + if (curTask_ == nullptr) { + while (!requestTasks_.empty() && curTask_ == nullptr) { + curTask_ = requestTasks_.front(); + requestTasks_.pop_front(); + ExecuteCurrentTask(); + } + } + + // If curTask_ not NULL, task which is from target app and in white list can be executed. + auto pausedTask = std::move(curTask_); + std::list tasks; + while (!requestTasks_.empty()) { + auto task = requestTasks_.front(); + requestTasks_.pop_front(); + // Task not from target app, keep waiting. + if (pausedTask->GetPauseInfo().target != task->GetCallerInfo().bundleName) { + tasks.push_back(task); + continue; + } + // Task from target app but not in whitelist, reject it. + if (!IsWhiteListRequest(task->GetCode())) { + task->OnResponse(ErrorCode::ERROR_IMSA_TASK_TIMEOUT); + continue; + } + // Task from waiting target app and in white list, execute it. + curTask_ = task; + ExecuteCurrentTask(); + } + // Restore curTask_ with pausedTask, restore requestTasks_ with tasks keeping waiting. + curTask_ = std::move(pausedTask); + requestTasks_ = std::move(tasks); +} + +void SaTaskManager::ProcessNextQueryTask() +{ + if (!inited_) { + IMSA_HILOGW("not initialized yet"); + return; + } + if (queryTasks_.empty()) { + IMSA_HILOGD("queryTasks_ empty"); + return; + } + // QUERY tasks can be executed when curTask_ exists. + auto pausedTask = std::move(curTask_); + while (curTask_ == nullptr && !queryTasks_.empty()) { + curTask_ = queryTasks_.front(); + queryTasks_.pop_front(); + ExecuteCurrentTask(); + } + curTask_ = std::move(pausedTask); +} + +void SaTaskManager::ExecuteCurrentTask() +{ + if (curTask_ == nullptr) { + return; + } + auto state = curTask_->Execute(); + if (state == RUNNING_STATE_COMPLETED) { + IMSA_HILOGI("curTask_ %{public}u completed", static_cast(curTask_->GetCode())); + RequesterManager::GetInstance().TaskOut(curTask_->GetCallerInfo().pid); + curTask_.reset(); + ProcessAsync(); + return; + } + if (state == RUNNING_STATE_PAUSED) { + IMSA_HILOGI("curTask_ %{public}u paused", static_cast(curTask_->GetCode())); + return; + } + IMSA_HILOGE("Unexpected execute result state: %{public}u", state); + RequesterManager::GetInstance().TaskOut(curTask_->GetCallerInfo().pid); + curTask_.reset(); +} + +void SaTaskManager::TryResume(const PauseType &pauseType, const CallerInfo &callerInfo) +{ + if (curTask_ == nullptr || !curTask_->IsPaused()) { + IMSA_HILOGD("curTask_ nullptr or not paused state"); + return; + } + PauseInfo pausedInfo = curTask_->GetPauseInfo(); + if (pausedInfo.type == PauseType::PAUSED_TYPE_INVALID) { + IMSA_HILOGE("invalid pause type"); + return; + } + if (pauseType == pausedInfo.type) { + IMSA_HILOGD("type not match, type: %{public}d, target: %{public}d", static_cast(pauseType), + static_cast(pausedInfo.type)); + return; + } + if (callerInfo.bundleName != pausedInfo.target) { + IMSA_HILOGD("bundleName not match, caller: %{public}s, target: %{public}s", callerInfo.bundleName.c_str(), + pausedInfo.target.c_str()); + return; + } + if (pauseType == PauseType::PAUSE_TYPE_START_IME) { + IMSA_HILOGI("start resume, %{public}s", pausedInfo.ToString().c_str()); + Complete(pausedInfo.resumeId); + } + if (pauseType == PauseType::PAUSE_TYPE_STOP_IME) { + if (callerInfo.pid == pausedInfo.pid) { + IMSA_HILOGI("start resume, %{public}s", pausedInfo.ToString().c_str()); + Complete(pausedInfo.resumeId); + } + } +} + +void SaTaskManager::Reset() +{ + inited_ = false; + curTask_ = nullptr; + eventHandler_ = nullptr; + innerTasks_.clear(); + criticalTasks_.clear(); + requestTasks_.clear(); + queryTasks_.clear(); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/task_manager/src/tasks/sa_task.cpp b/services/task_manager/src/tasks/sa_task.cpp new file mode 100644 index 000000000..875b59dbf --- /dev/null +++ b/services/task_manager/src/tasks/sa_task.cpp @@ -0,0 +1,203 @@ +/* + * 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 "sa_task.h" + +namespace OHOS { +namespace MiscServices { +SaTask::~SaTask() +{ + if (!isResponsed_) { + failCode_ = ErrorCode::ERROR_IMSA_TASK_TIMEOUT; + InvokeResponse(); + } +} + +RunningState SaTask::Execute() +{ + if (state_ != RUNNING_STATE_IDLE) { + IMSA_HILOGE("Task not runnable, state=%{public}u", state_); + return RUNNING_STATE_ERROR; + } + return ExecuteInner(); +} + +RunningState SaTask::Resume(uint64_t resumeId) +{ + if (curAction_ == nullptr) { + IMSA_HILOGE("curAction_ is nullptr"); + return RUNNING_STATE_ERROR; + } + + if (state_ != RUNNING_STATE_PAUSED) { + IMSA_HILOGE("state_ is %{public}u, do not need to resume", state_); + return RUNNING_STATE_ERROR; + } + + auto ret = curAction_->Resume(resumeId); + if (ret == RUNNING_STATE_PAUSED) { + return state_; + } + if (ret == RUNNING_STATE_COMPLETED) { + curAction_.reset(); + return ExecuteInner(); + } + IMSA_HILOGE("curAction_ resume return %{public}u, error!", ret); + return RUNNING_STATE_ERROR; +} + +RunningState SaTask::OnTask(const std::shared_ptr &task) +{ + if (task == nullptr) { + IMSA_HILOGE("task is nullptr"); + return state_; + } + auto type = task->GetType(); + if (type == SaTaskType::TYPE_INNER) { + return Resume(task->GetSeqId()); + } + return state_; +} + +int32_t SaTask::PendSingle(std::unique_ptr action) +{ + pendingActions_.push_back(std::move(action)); + return ErrorCode::NO_ERROR; +} + +int32_t SaTask::PendSingle(SaActionFunc action) +{ + pendingActions_.push_back(std::make_unique(action)); + return ErrorCode::NO_ERROR; +} + +SaTaskType SaTask::GetType() const +{ + auto type = static_cast(code_); + if (type >= static_cast(SaTaskCode::TASK_CRITICAL_CHANGE_BEGIN) + && type <= static_cast(SaTaskCode::TASK_CRITICAL_CHANGE_END)) { + return SaTaskType::TYPE_CRITICAL_CHANGE; + } + if (type >= static_cast(SaTaskCode::TASK_SWITCH_IME_BEGIN) + && type <= static_cast(SaTaskCode::TASK_SWITCH_IME_END)) { + return SaTaskType::TYPE_SWITCH_IME; + } + if (type >= static_cast(SaTaskCode::TASK_NORMAL_REQUEST_BEGIN) + && type <= static_cast(SaTaskCode::TASK_NORMAL_REQUEST_END)) { + return SaTaskType::TYPE_NORMAL_REQUEST; + } + if (type >= static_cast(SaTaskCode::TASK_QUERY_BEGIN) + && type <= static_cast(SaTaskCode::TASK_QUERY_END)) { + return SaTaskType::TYPE_QUERY; + } + if (type >= static_cast(SaTaskCode::TASK_RESUME_BEGIN) + && type <= static_cast(SaTaskCode::TASK_RESUME_END)) { + return SaTaskType::TYPE_RESUME; + } + if (type >= static_cast(SaTaskCode::TASK_INNER_BEGIN) + && type <= static_cast(SaTaskCode::TASK_INNER_END)) { + return SaTaskType::TYPE_INNER; + } + return SaTaskType::TYPE_INVALID; +} + +uint64_t SaTask::GetSeqId() const +{ + return seqId_; +} + +bool SaTask::IsRunning() const +{ + return state_ == RUNNING_STATE_RUNNING; +} + +uint64_t SaTask::GetNextSeqId() +{ + static std::atomic seqId{ 1 }; + return seqId.fetch_add(1, std::memory_order_seq_cst); +} + +void SaTask::SetReportAction(std::unique_ptr action) +{ + resultReporter_ = std::move(action); +} + +RunningState SaTask::ExecuteInner() +{ + state_ = RUNNING_STATE_RUNNING; + if (!pendingActions_.empty()) { + pendingActions_.splice(pendingActions_.end(), actions_); + actions_.swap(pendingActions_); + } + + while (!actions_.empty()) { + curAction_ = std::move(actions_.front()); + actions_.pop_front(); + + RunningState resultState = curAction_->Execute(curActionRet_, responseData_); + if (resultState == RUNNING_STATE_COMPLETED && curActionRet_ != ErrorCode::NO_ERROR) { + break; + } + + if (!pendingActions_.empty()) { + pendingActions_.splice(pendingActions_.end(), actions_); + actions_.swap(pendingActions_); + } + + if (resultState == RUNNING_STATE_COMPLETED) { + curAction_.reset(); + continue; + } + + state_ = RUNNING_STATE_PAUSED; + return state_; + } + InvokeResponse(); + state_ = RUNNING_STATE_COMPLETED; + return state_; +} + +void SaTask::InvokeResponse() +{ + isResponsed_ = true; + if (curActionRet_ != ErrorCode::NO_ERROR && failCode_ != INVALID_FAIL_CODE) { + curActionRet_ = failCode_; + } + + if (resultReporter_ != nullptr) { + resultReporter_->Execute(curActionRet_, responseData_); + } + + if (channel_ != nullptr) { + ServiceResponseDataInner inner; + inner.data = responseData_; + channel_->OnResponse(callerInfo_.requestId, curActionRet_, inner); + } + + curAction_ = nullptr; + actions_.clear(); + pendingActions_.clear(); +} + +PauseInfo SaTask::GetPauseInfo() +{ + if (curAction_ == nullptr || curAction_->GetState() != RUNNING_STATE_PAUSED) { + IMSA_HILOGE("curAction_ nullptr or not paused"); + return {}; + } + return curAction_->GetPausedInfo(); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/test/unittest/cpp_test/src/response_data_test.cpp b/test/unittest/cpp_test/src/response_data_test.cpp new file mode 100644 index 000000000..54fe068a0 --- /dev/null +++ b/test/unittest/cpp_test/src/response_data_test.cpp @@ -0,0 +1,84 @@ +/* + * 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. + */ + +#define private public +#define protected public +#include "response_data_util.h" +#include "service_response_data.h" +#undef private + +#include +#include + +using namespace testing; +using namespace testing::ext; +namespace OHOS { +namespace MiscServices { +class ResponseDataTest : public testing::Test { +public: + static void SetUpTestCase() + { + } + static void TearDownTestCase() + { + } + void SetUp() + { + } + void TearDown() + { + } + + template static ServiceValueType GetServiceDataTypeIndex() + { + auto index = std::variant_alternative_t<0, ServiceResponseData> == std::monostate + ? std::variant::template index_of - 1 + : std::variant::template index_of; + return static_cast(index); + } +}; + +/** + * @tc.name: ServiceResponseDataTypeValueTest + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: + */ +HWTEST_F(ResponseDataTest, ServiceResponseDataTypeTest, TestSize.Level0) +{ + // test basic type + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_BOOL); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_INT32); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_UINT32); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_INT64); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_UINT64); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex>(), ServiceValueType::TYPE_REMOTE_OBJECT); + + // test inner type + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_PROPERTY); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex>(), ServiceValueType::TYPE_PROPERTIES); + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_SUB_PROPERTY); + EXPECT_EQ( + ResponseDataTest::GetServiceDataTypeIndex>(), ServiceValueType::TYPE_SUB_PROPERTIES); + EXPECT_EQ( + ResponseDataTest::GetServiceDataTypeIndex(), ServiceValueType::TYPE_START_INPUT_RESPONSE); + + // test external type + EXPECT_EQ(ResponseDataTest::GetServiceDataTypeIndex>(), + ServiceValueType::TYPE_AMS_ELEMENT_NAME); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file -- Gitee From 61489fb41ec7d4230d3943db85c9587863faf537 Mon Sep 17 00:00:00 2001 From: zhaolinglan Date: Thu, 26 Jun 2025 22:34:26 +0800 Subject: [PATCH 2/2] fix conflict Signed-off-by: zhaolinglan --- common/include/inputmethod_message_handler.h | 99 -------- common/src/message.cpp | 86 ------- common/src/message_handler.cpp | 77 ------ .../include/response_data_util.h | 15 +- .../include/service_response_data.h | 25 +- .../src/service_response_data.cpp | 4 +- .../IImaResponseChannel.idl} | 2 +- .../include/ima_response_channel_impl.h} | 20 +- .../include/ima_service_proxy.h | 57 ++++- .../src/ima_response_channel_impl.cpp} | 17 +- .../src/ima_service_proxy.cpp | 198 ++++++++++++++- .../src/input_method_ability.cpp | 8 +- .../IImcResponseChannel.idl | 20 ++ .../IInputMethodSystemAbility.idl | 6 +- .../include/imc_response_channel_impl.h | 38 +++ .../include/imc_service_proxy.h | 57 ++++- .../src/imc_response_channel_impl.cpp | 41 ++- .../src/imc_service_proxy.cpp | 192 ++++++++++++++ frameworks/native/service_proxy/BUILD.gn | 145 ----------- .../service_proxy/include/i_service_proxy.h | 80 ------ .../service_proxy/src/i_service_proxy.cpp | 235 ------------------ .../inner_api/inputmethod_ability/BUILD.gn | 86 ++++++- .../inner_api/inputmethod_controller/BUILD.gn | 65 ++++- services/include/im_common_event_manager.h | 13 - .../include/input_method_system_ability.h | 8 +- services/src/im_common_event_manager.cpp | 79 +----- services/src/input_method_system_ability.cpp | 211 +++++++++------- .../task_manager/include/requester_manager.h | 10 +- services/task_manager/include/tasks/sa_task.h | 26 +- .../task_manager/src/requester_manager.cpp | 101 ++++++-- services/task_manager/src/tasks/sa_task.cpp | 9 +- 31 files changed, 993 insertions(+), 1037 deletions(-) delete mode 100644 common/include/inputmethod_message_handler.h delete mode 100644 common/src/message.cpp delete mode 100644 common/src/message_handler.cpp rename frameworks/native/{service_proxy => common}/include/response_data_util.h (83%) rename frameworks/native/{service_proxy => common}/include/service_response_data.h (84%) rename frameworks/native/{service_proxy => common}/src/service_response_data.cpp (98%) rename frameworks/native/{service_proxy/IResponseChannel.idl => inputmethod_ability/IImaResponseChannel.idl} (94%) rename frameworks/native/{service_proxy/include/response_channel_impl.h => inputmethod_ability/include/ima_response_channel_impl.h} (69%) rename frameworks/native/{service_proxy/src/response_channel_impl.cpp => inputmethod_ability/src/ima_response_channel_impl.cpp} (66%) create mode 100644 frameworks/native/inputmethod_controller/IImcResponseChannel.idl create mode 100644 frameworks/native/inputmethod_controller/include/imc_response_channel_impl.h rename common/include/message.h => frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp (50%) delete mode 100644 frameworks/native/service_proxy/BUILD.gn delete mode 100644 frameworks/native/service_proxy/include/i_service_proxy.h delete mode 100644 frameworks/native/service_proxy/src/i_service_proxy.cpp diff --git a/common/include/inputmethod_message_handler.h b/common/include/inputmethod_message_handler.h deleted file mode 100644 index f462bbeaf..000000000 --- a/common/include/inputmethod_message_handler.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2021-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. - */ - -#ifndef INPUTMETHOD_MESSAGE_HANDLER_H -#define INPUTMETHOD_MESSAGE_HANDLER_H - -#include -#include -#include - -#include "global.h" -#include "message.h" -#include "message_parcel.h" - -namespace OHOS { -namespace MiscServices { -namespace MessageID { -enum { - MSG_ID_USER_START = 0, // a user started - MSG_ID_USER_REMOVED, // a user removed - MSG_ID_PACKAGE_REMOVED, // a package is removed - MSG_ID_BUNDLE_SCAN_FINISHED, // bundle scan finished - MSG_ID_DATA_SHARE_READY, // datashare ready, ready to create data share helper - MSG_ID_PACKAGE_ADDED, - MSG_ID_PACKAGE_CHANGED, - MSG_ID_SYS_LANGUAGE_CHANGED, - MSG_ID_OS_ACCOUNT_STARTED, - MSG_ID_BOOT_COMPLETED, - MSG_ID_SCREEN_UNLOCK, - MSG_ID_SELECT_BY_RANGE, - MSG_ID_SELECT_BY_MOVEMENT, - MSG_ID_HANDLE_EXTEND_ACTION, - MSG_ID_USER_STOP, - MSG_ID_REGULAR_UPDATE_IME_INFO, - - MSG_ID_HIDE_KEYBOARD_SELF, // hide the current keyboard - - // the request from IMSA to IMC - MSG_ID_INSERT_CHAR, - MSG_ID_DELETE_FORWARD, - MSG_ID_DELETE_BACKWARD, - MSG_ID_ON_INPUT_STOP, - MSG_ID_SEND_KEYBOARD_STATUS, - MSG_ID_SEND_FUNCTION_KEY, - MSG_ID_MOVE_CURSOR, - MSG_ID_ON_SWITCH_INPUT, - MSG_ID_GET_TEXT_INDEX_AT_CURSOR, - MSG_ID_GET_TEXT_BEFORE_CURSOR, - MSG_ID_GET_TEXT_AFTER_CURSOR, - MSG_ID_ON_PANEL_STATUS_CHANGE, - - // the request from IMSA to IMA - MSG_ID_INIT_INPUT_CONTROL_CHANNEL, - MSG_ID_SET_SUBTYPE, - - // the request from IMC to IMA - MSG_ID_ON_CURSOR_UPDATE, - MSG_ID_ON_SELECTION_CHANGE, - MSG_ID_ON_CONFIGURATION_CHANGE, - MSG_ID_ON_ATTRIBUTE_CHANGE, - MSG_ID_QUIT_WORKER_THREAD, - MSG_ID_SET_COREANDANGENT, -}; -} - -class MessageHandler { -public: - MessageHandler(); - ~MessageHandler(); - void SendMessage(Message *msg); - Message *GetMessage(); - static MessageHandler *Instance(); - static std::mutex handlerMutex_; - -private: - std::mutex mMutex; // a mutex to guard message queue - std::condition_variable mCV; // condition variable to work with mMutex - std::queue mQueue; // Message queue, guarded by mMutex; - - MessageHandler(const MessageHandler &); - MessageHandler &operator=(const MessageHandler &); - MessageHandler(const MessageHandler &&); - MessageHandler &operator=(const MessageHandler &&); -}; -} // namespace MiscServices -} // namespace OHOS -#endif // INPUTMETHOD_MESSAGE_HANDLER_H diff --git a/common/src/message.cpp b/common/src/message.cpp deleted file mode 100644 index 45034cd39..000000000 --- a/common/src/message.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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 "message.h" - -#include "global.h" - -namespace OHOS { -namespace MiscServices { -/*! Constructor - * @param msgId a message Id - * @param msgContent the content of a message - */ -Message::Message(int32_t msgId, MessageParcel *msgContent) -{ - msgId_ = msgId; - msgContent_ = msgContent; - if (msgContent_ != nullptr) { - msgContent_->RewindRead(0); - } -} - -/*!Constructor - * @param msg a source message - */ -Message::Message(const Message &msg) -{ - msgId_ = msg.msgId_; - if (msgContent_ != nullptr) { - delete msgContent_; - msgContent_ = nullptr; - } - MessageParcel *src = msg.msgContent_; - if (src != nullptr) { - msgContent_ = new (std::nothrow) MessageParcel(); - if (msgContent_ == nullptr) { - IMSA_HILOGE("new MessageParcel failed"); - return; - } - msgContent_->ParseFrom(src->GetData(), src->GetDataSize()); - } -} - -Message &Message::operator=(const Message &msg) -{ - if (this == &msg) { - return *this; - } - msgId_ = msg.msgId_; - if (msgContent_ != nullptr) { - delete msgContent_; - msgContent_ = nullptr; - } - if (msg.msgContent_ != nullptr) { - msgContent_ = new (std::nothrow) MessageParcel(); - if (msgContent_ == nullptr) { - IMSA_HILOGE("new MessageParcel failed"); - return *this; - } - msgContent_->ParseFrom(msg.msgContent_->GetData(), msg.msgContent_->GetDataSize()); - msgContent_->RewindRead(0); - } - return *this; -} - -Message::~Message() -{ - if (msgContent_ != nullptr) { - delete msgContent_; - msgContent_ = nullptr; - } -} -} // namespace MiscServices -} // namespace OHOS diff --git a/common/src/message_handler.cpp b/common/src/message_handler.cpp deleted file mode 100644 index 11f3eac66..000000000 --- a/common/src/message_handler.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 "inputmethod_message_handler.h" - -namespace OHOS { -namespace MiscServices { -std::mutex MessageHandler::handlerMutex_; - -MessageHandler::MessageHandler() -{ -} - -MessageHandler::~MessageHandler() -{ - std::unique_lock lock(mMutex); - while (!mQueue.empty()) { - Message *msg = mQueue.front(); - mQueue.pop(); - delete msg; - msg = nullptr; - } -} - -/*! Send a message - * @param msg a message to be sent - * @note the msg pointer should not be freed by the caller - */ -void MessageHandler::SendMessage(Message *msg) -{ - std::unique_lock lock(mMutex); - mQueue.push(msg); - mCV.notify_one(); -} - -/*! Get a message - * @return a pointer referred to an object of message - * @note the returned pointer should be freed by the caller. - */ -Message *MessageHandler::GetMessage() -{ - std::unique_lock lock(mMutex); - mCV.wait(lock, [this] { return !this->mQueue.empty(); }); - Message *msg = reinterpret_cast(mQueue.front()); - mQueue.pop(); - return msg; -} - -/*! The single instance of MessageHandler in the service - * @return the pointer referred to an object. - */ -MessageHandler *MessageHandler::Instance() -{ - static MessageHandler *handler = nullptr; - if (handler == nullptr) { - std::unique_lock lock(handlerMutex_); - if (handler == nullptr) { - handler = new (std::nothrow) MessageHandler(); - return handler; - } - } - return handler; -} -} // namespace MiscServices -} // namespace OHOS diff --git a/frameworks/native/service_proxy/include/response_data_util.h b/frameworks/native/common/include/response_data_util.h similarity index 83% rename from frameworks/native/service_proxy/include/response_data_util.h rename to frameworks/native/common/include/response_data_util.h index 081c0f15f..54bda9e5b 100644 --- a/frameworks/native/service_proxy/include/response_data_util.h +++ b/frameworks/native/common/include/response_data_util.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef RESPONSE_DATA_UTIL_H -#define RESPONSE_DATA_UTIL_H +#ifndef IMF_FRAMEWORKS_RESPONSE_DATA_UTIL_H +#define IMF_FRAMEWORKS_RESPONSE_DATA_UTIL_H #include #include @@ -25,13 +25,6 @@ namespace OHOS { namespace MiscServices { const int VECTOR_MAX_SIZE = 102400; -using ServiceResponseData = std::variant, Property, std::vector, SubProperty, std::vector, StartInputResponse, - InputStartInfo, AppExecFwk::ElementName>; -struct ServiceResponse { - int32_t result{ 0 }; - ServiceResponseData responseData{ std::monostate{} }; -}; class ResponseDataUtil { public: template static bool Unmarshall(Parcel &in, std::vector &out) @@ -61,7 +54,7 @@ struct ResponseReader { Parcel ∈ bool result = true; - ResponseReader(Parcel &parcel) : in(parcel) + explicit ResponseReader(Parcel &parcel) : in(parcel) { } @@ -91,4 +84,4 @@ struct ResponseReader { } // namespace MiscServices } // namespace OHOS -#endif // RESPONSE_DATA_UTIL_H +#endif // IMF_FRAMEWORKS_RESPONSE_DATA_UTIL_H diff --git a/frameworks/native/service_proxy/include/service_response_data.h b/frameworks/native/common/include/service_response_data.h similarity index 84% rename from frameworks/native/service_proxy/include/service_response_data.h rename to frameworks/native/common/include/service_response_data.h index f3084e183..e502c4434 100644 --- a/frameworks/native/service_proxy/include/service_response_data.h +++ b/frameworks/native/common/include/service_response_data.h @@ -13,10 +13,11 @@ * limitations under the License. */ -#ifndef IMF_SERVICE_RESPONSE_DATA_H -#define IMF_SERVICE_RESPONSE_DATA_H +#ifndef IMF_FRAMEWORKS_SERVICE_RESPONSE_DATA_H +#define IMF_FRAMEWORKS_SERVICE_RESPONSE_DATA_H #include +#include #include #include "element_name.h" @@ -26,6 +27,21 @@ namespace OHOS { namespace MiscServices { +using RequestId = uint32_t; +using RequestFunc = std::function; + +using ServiceResponseData = std::variant, Property, std::vector, SubProperty, std::vector, StartInputResponse, + InputStartInfo, AppExecFwk::ElementName>; + +struct ServiceResponse { + int32_t result{ 0 }; + ServiceResponseData responseData{ std::monostate{} }; +}; + +struct PendingRequest { + std::promise promise; +}; struct StartInputResponse : public Parcelable { sptr agent{ nullptr }; int64_t pid{ 0 }; @@ -84,7 +100,6 @@ private: template void operator()(T &value) { ResponseReader::operator()(value); - if constexpr (std::is_same_v> || std::is_same_v>) { result = ResponseDataUtil::Unmarshall(in, value); } @@ -96,7 +111,7 @@ struct ServiceResponseWriter { Parcel &out; bool result = true; - ServiceResponseWriter(Parcel &parcel) : out(parcel) + explicit ServiceResponseWriter(Parcel &parcel) : out(parcel) { } @@ -161,4 +176,4 @@ struct ServiceResponseWriter { } // namespace MiscServices } // namespace OHOS -#endif // IMF_SERVICE_RESPONSE_DATA_H +#endif // IMF_FRAMEWORKS_SERVICE_RESPONSE_DATA_H diff --git a/frameworks/native/service_proxy/src/service_response_data.cpp b/frameworks/native/common/src/service_response_data.cpp similarity index 98% rename from frameworks/native/service_proxy/src/service_response_data.cpp rename to frameworks/native/common/src/service_response_data.cpp index 7b9b0f5f1..52c0ecebb 100644 --- a/frameworks/native/service_proxy/src/service_response_data.cpp +++ b/frameworks/native/common/src/service_response_data.cpp @@ -23,8 +23,8 @@ bool ServiceResponseDataInner::ReadFromParcel(Parcel &in) if (!in.ReadInt32(valueType)) { return false; } - if (valueType < static_cast(ServiceDataType::TYPE_MONOSTATE) || - valueType >= static_cast(ServiceDataType::TYPE_END)) { + if (valueType < static_cast(ServiceDataType::TYPE_MONOSTATE) + || valueType >= static_cast(ServiceDataType::TYPE_END)) { IMSA_HILOGE("invalid value type"); return false; } diff --git a/frameworks/native/service_proxy/IResponseChannel.idl b/frameworks/native/inputmethod_ability/IImaResponseChannel.idl similarity index 94% rename from frameworks/native/service_proxy/IResponseChannel.idl rename to frameworks/native/inputmethod_ability/IImaResponseChannel.idl index cc191556f..475fcd212 100644 --- a/frameworks/native/service_proxy/IResponseChannel.idl +++ b/frameworks/native/inputmethod_ability/IImaResponseChannel.idl @@ -14,7 +14,7 @@ */ sequenceable service_response_data..OHOS.MiscServices.ServiceResponseDataInner; -interface OHOS.MiscServices.IResponseChannel { +interface OHOS.MiscServices.IImaResponseChannel { [oneway] void OnResponse( [in] unsigned int requestId, [in] int resultErrCode, [in] ServiceResponseDataInner response); } diff --git a/frameworks/native/service_proxy/include/response_channel_impl.h b/frameworks/native/inputmethod_ability/include/ima_response_channel_impl.h similarity index 69% rename from frameworks/native/service_proxy/include/response_channel_impl.h rename to frameworks/native/inputmethod_ability/include/ima_response_channel_impl.h index 1b0a2662d..5d52d577c 100644 --- a/frameworks/native/service_proxy/include/response_channel_impl.h +++ b/frameworks/native/inputmethod_ability/include/ima_response_channel_impl.h @@ -13,26 +13,26 @@ * limitations under the License. */ -#ifndef IMF_RESPONSE_CHANNEL_IMPL_H -#define IMF_RESPONSE_CHANNEL_IMPL_H +#ifndef IMF_IMA_RESPONSE_CHANNEL_IMPL_H +#define IMF_IMA_RESPONSE_CHANNEL_IMPL_H +#include "iima_response_channel.h" +#include "ima_response_channel_stub.h" #include "iremote_object.h" -#include "iresponse_channel.h" -#include "response_channel_stub" #include "service_response_data.h" namespace OHOS { namespace MiscServices { -class ResponseChannelImpl final +class ImaResponseChannelImpl final : public ResponseChannelStub - , public std::enable_shared_from_this { - DISALLOW_COPY_AND_MOVE(ResponseChannelImpl); + , public std::enable_shared_from_this { + DISALLOW_COPY_AND_MOVE(ImaResponseChannelImpl); public: - ResponseChannelImpl(); - ~ResponseChannelImpl(); + ImaResponseChannelImpl(); + ~ImaResponseChannelImpl(); ErrCode OnResponse(uint32_t requestId, int32_t resultErrCode, const ServiceResponseDataInner &response) override; }; } // namespace MiscServices } // namespace OHOS -#endif // IMF_RESPONSE_CHANNEL_IMPL_H +#endif // IMF_IMA_RESPONSE_CHANNEL_IMPL_H diff --git a/frameworks/native/inputmethod_ability/include/ima_service_proxy.h b/frameworks/native/inputmethod_ability/include/ima_service_proxy.h index 19e8cc87e..561d12694 100644 --- a/frameworks/native/inputmethod_ability/include/ima_service_proxy.h +++ b/frameworks/native/inputmethod_ability/include/ima_service_proxy.h @@ -16,29 +16,38 @@ #ifndef IMF_IMA_SERVICE_PROXY_H #define IMF_IMA_SERVICE_PROXY_H -#include "i_service_proxy.h" +#include +#include +#include +#include + +#include "iima_response_channel.h" +#include "iinput_method_system_ability.h" +#include "input_death_recipient.h" +#include "service_response_data.h" namespace OHOS { namespace MiscServices { -class ImaServiceProxy : public IServiceProxy { +class ImaServiceProxy { private: - ImaServiceProxy() = default; + ImaServiceProxy(); public: static ImaServiceProxy &GetInstance(); - using IServiceProxy::SendRequest; - template - int32_t SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout); - - ~ImaServiceProxy() override = default; + ~ImaServiceProxy() = default; ImaServiceProxy(const ImaServiceProxy &) = delete; ImaServiceProxy(ImaServiceProxy &&) = delete; ImaServiceProxy &operator=(const ImaServiceProxy &) = delete; ImaServiceProxy &operator=(ImaServiceProxy &&) = delete; -private: - void OnRemoteSaDied(const wptr &remote) override; + int32_t SendRequest(const RequestFunc &request, int64_t timeout); + template + int32_t SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout); + + void OnResponse(RequestId id, const ServiceResponse &responseData); + + void RemoveDeathRecipient(); public: int32_t SetCoreAndAgent(const sptr &core, const sptr &agent); @@ -53,7 +62,33 @@ public: int32_t IsCapacitySupport(int32_t capacity, bool &isSupport); int32_t IsCurrentIme(bool &resultValue); int32_t IsDefaultIme(bool &resultValue); - int32_t IsSystemApp(bool &resultValue); + int32_t IsSystemImeApp(bool &resultValue); + +private: + void Init(); + RequestId GetNextRequestId(); + int32_t RegisterResponseChannel(); + int32_t SendRequestInner(const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout); + + void OnRemoteSaDied(const wptr &remote); + sptr GetSystemAbilityProxy(bool ifRetry = true); + + void AddRequest(RequestId id, PendingRequest pendingRequest); + void RemoveRequest(RequestId requestId); + + std::atomic hasRegistered_{ false }; + std::mutex abilityLock_{}; + sptr abilityManager_ = nullptr; + sptr deathRecipient_; + + std::atomic currentRequestId_{ 0 }; + std::atomic isInterrupted_{ false }; + + std::mutex requestsMutex_{}; + std::unordered_map pendingRequests_; + std::atomic lastId_{ 0 }; + + sptr responseChannelStub_{ nullptr }; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/service_proxy/src/response_channel_impl.cpp b/frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp similarity index 66% rename from frameworks/native/service_proxy/src/response_channel_impl.cpp rename to frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp index b4ec9ab08..87ac7e439 100644 --- a/frameworks/native/service_proxy/src/response_channel_impl.cpp +++ b/frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp @@ -13,31 +13,26 @@ * limitations under the License. */ -#include "response_channel_impl.h" +#include "ima_response_channel_impl.h" -#include "input_method_ability.h" -#include "input_method_controller.h" +#include "ima_service_proxy.h" namespace OHOS { namespace MiscServices { -ResponseChannelImpl::ResponseChannelImpl() +ImaResponseChannelImpl::ImaResponseChannelImpl() { } -ResponseChannelImpl::~ResponseChannelImpl() +ImaResponseChannelImpl::~ImaResponseChannelImpl() { } -ErrCode ResponseChannelImpl::OnResponse( +ErrCode ImaResponseChannelImpl::OnResponse( uint32_t requestId, int32_t resultErrCode, const ServiceResponseDataInner &response) { ServiceResponse serviceResponse = { .result = resultErrCode, .responseData = response.data }; - auto instance = InputMethodController::GetInstance(); - if (instance != nullptr) { - instance->OnResponse(requestId, serviceResponse); - } - InputMethodAbility::GetInstance().OnResponse(requestId, serviceResponse); + ImaServiceProxy::GetInstance().OnResponse(requestId, serviceResponse); return ERR_OK; } } // namespace MiscServices diff --git a/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp b/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp index cff3f12a1..32ee1ea02 100644 --- a/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp +++ b/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp @@ -15,7 +15,9 @@ #include "ima_service_proxy.h" +#include "ima_response_channel_impl.h" #include "input_method_ability.h" +#include "on_demand_start_stop_sa.h" #include "variant_util.h" namespace OHOS { @@ -38,6 +40,171 @@ ImaServiceProxy &ImaServiceProxy::GetInstance() return ImaServiceProxy; } +ImaServiceProxy::ImaServiceProxy() +{ + Init(); +} + +void ImaServiceProxy::Init() +{ + IMSA_HILOGD("start"); + sptr channel = new (std::nothrow) ImaResponseChannelImpl(); + if (channel == nullptr) { + IMSA_HILOGE("failed to create channel!"); + return; + } + responseChannelStub_ = channel; +} + +RequestId ImaServiceProxy::GetNextRequestId() +{ + static std::atomic seqId{ 1 }; + return seqId.fetch_add(1, std::memory_order_seq_cst); +} + +void ImaServiceProxy::OnResponse(RequestId id, const ServiceResponse &responseData) +{ + std::lock_guard lock(requestsMutex_); + auto iter = pendingRequests_.find(id); + if (iter == pendingRequests_.end()) { + IMSA_HILOGE("failed to find pending request, id: %{public}d", id); + return; + } + IMSA_HILOGD("id: %{public}d", id); + iter->second.promise.set_value(responseData); +} + +sptr ImaServiceProxy::GetSystemAbilityProxy(bool ifRetry) +{ + std::lock_guard lock(abilityLock_); + if (abilityManager_ != nullptr) { + return abilityManager_; + } + IMSA_HILOGD("get input method service proxy."); + auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(ifRetry); + if (systemAbility == nullptr) { + IMSA_HILOGE("systemAbility is nullptr!"); + return nullptr; + } + + if (deathRecipient_ == nullptr) { + deathRecipient_ = new (std::nothrow) InputDeathRecipient(); + if (deathRecipient_ == nullptr) { + IMSA_HILOGE("create death recipient failed!"); + return nullptr; + } + } + deathRecipient_->SetDeathRecipient([this](const wptr &remote) { OnRemoteSaDied(remote); }); + if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { + IMSA_HILOGE("failed to add death recipient!"); + return nullptr; + } + abilityManager_ = iface_cast(systemAbility); + return abilityManager_; +} + +void ImaServiceProxy::RemoveDeathRecipient() +{ + std::lock_guard lock(abilityLock_); + if (abilityManager_ != nullptr && abilityManager_->AsObject() != nullptr && deathRecipient_ != nullptr) { + abilityManager_->AsObject()->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; + abilityManager_ = nullptr; +} + +int32_t ImaServiceProxy::SendRequest(const RequestFunc &request, int64_t timeout) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + // wait till timeout + if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + return ErrorCode::NO_ERROR; +} + +int32_t ImaServiceProxy::SendRequestInner( + const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + // wait till timeout + if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + RemoveRequest(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + responseData = response.responseData; + return ErrorCode::NO_ERROR; +} + template int32_t ImaServiceProxy::SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout) { @@ -65,6 +232,33 @@ void ImaServiceProxy::OnRemoteSaDied(const wptr &remote) InputMethodAbility::GetInstance().OnRemoteSaDied(remote); } +int32_t ImaServiceProxy::RegisterResponseChannel() +{ + if (hasRegistered_.load()) { + return ErrorCode::NO_ERROR; + } + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get sa proxy"); + return ErrorCode::ERROR_IPC_REMOTE_NULLPTR; + } + return proxy->RegisterImaResponseChannel(responseChannelStub_); +} + +void ImaServiceProxy::AddRequest(RequestId id, PendingRequest pendingRequest) +{ + std::lock_guard lock(requestsMutex_); + pendingRequests_[id] = std::move(pendingRequest); + currentRequestId_.store(id); +} + +void ImaServiceProxy::RemoveRequest(RequestId requestId) +{ + std::lock_guard lock(requestsMutex_); + pendingRequests_.erase(requestId); + currentRequestId_.store(0); +} + int32_t ImaServiceProxy::SetCoreAndAgent(const sptr &core, const sptr &agent) { RequestFunc requestFunc = [this, core, agent](RequestId requestId) -> int32_t { @@ -234,7 +428,7 @@ int32_t ImaServiceProxy::IsDefaultIme(bool &resultValue) return SendRequest(requestFunc, resultValue, QUERY_TIMEOUT); } -int32_t ImaServiceProxy::IsSystemApp(bool &resultValue) +int32_t ImaServiceProxy::IsSystemImeApp(bool &resultValue) { RequestFunc requestFunc = [this](RequestId requestId) -> int32_t { CHECK_RESPONSE_CHANNEL(ErrorCode::ERROR_IMC_NULLPTR); @@ -243,7 +437,7 @@ int32_t ImaServiceProxy::IsSystemApp(bool &resultValue) IMSA_HILOGE("failed to get proxy"); return ErrorCode::ERROR_SERVICE_START_FAILED; } - return proxy->IsSystemApp(requestId); + return proxy->IsSystemImeApp(requestId); }; return SendRequest(requestFunc, resultValue, QUERY_TIMEOUT); } diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 3d0715234..a496f9748 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -117,9 +117,9 @@ int32_t InputMethodAbility::RegisterProxyIme(uint64_t displayId) IMSA_HILOGE("agent nullptr"); return ErrorCode::ERROR_NULL_POINTER; } - int32_t ret = displayId == DEFAULT_DISPLAY_ID - ? ImaServiceProxy::GetInstance().SetCoreAndAgent(coreStub_, agentStub_->AsObject()) - : ImaServiceProxy::GetInstance().RegisterProxyIme(displayId, coreStub_, agentStub_->AsObject()); + int32_t ret = displayId == DEFAULT_DISPLAY_ID ? + ImaServiceProxy::GetInstance().SetCoreAndAgent(coreStub_, agentStub_->AsObject()) : + ImaServiceProxy::GetInstance().RegisterProxyIme(displayId, coreStub_, agentStub_->AsObject()); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed, displayId: %{public}" PRIu64 ", ret: %{public}d!", displayId, ret); return ret; @@ -1237,7 +1237,7 @@ bool InputMethodAbility::IsSystemApp() return true; } bool ret = false; - ImaServiceProxy::GetInstance().IsSystemApp(ret); + ImaServiceProxy::GetInstance().IsSystemImeApp(ret); if (ret) { isSystemApp_ = true; } diff --git a/frameworks/native/inputmethod_controller/IImcResponseChannel.idl b/frameworks/native/inputmethod_controller/IImcResponseChannel.idl new file mode 100644 index 000000000..497fb83cb --- /dev/null +++ b/frameworks/native/inputmethod_controller/IImcResponseChannel.idl @@ -0,0 +1,20 @@ +/* + * 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. + */ + +sequenceable service_response_data..OHOS.MiscServices.ServiceResponseDataInner; +interface OHOS.MiscServices.IImcResponseChannel { + [oneway] void OnResponse( + [in] unsigned int requestId, [in] int resultErrCode, [in] ServiceResponseDataInner response); +} diff --git a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl index 3e1540580..061e11bd9 100644 --- a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl +++ b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl @@ -23,9 +23,11 @@ sequenceable element_name..OHOS.AppExecFwk.ElementName; sequenceable OHOS.IRemoteObject; interface OHOS.MiscServices.IInputClient; interface OHOS.MiscServices.IInputMethodCore; -interface OHOS.MiscServices.IResponseChannel; +interface OHOS.MiscServices.IImaResponseChannel; +interface OHOS.MiscServices.IImcResponseChannel; interface OHOS.MiscServices.IInputMethodSystemAbility { - void RegisterResponseChannel([in] IResponseChannel channel); + void RegisterImaResponseChannel([in] IImaResponseChannel channel); + void RegisterImcResponseChannel([in] IImcResponseChannel channel); void StartInput([in] unsigned int requestId, [in] InputClientInfoInner inputClientInfoInner); void ShowCurrentInput([in] unsigned int requestId, [in] unsigned int type); void HideCurrentInput([in] unsigned int requestId); diff --git a/frameworks/native/inputmethod_controller/include/imc_response_channel_impl.h b/frameworks/native/inputmethod_controller/include/imc_response_channel_impl.h new file mode 100644 index 000000000..d46ca3661 --- /dev/null +++ b/frameworks/native/inputmethod_controller/include/imc_response_channel_impl.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#ifndef IMF_IMC_RESPONSE_CHANNEL_IMPL_H +#define IMF_IMC_RESPONSE_CHANNEL_IMPL_H + +#include "iimc_response_channel.h" +#include "imc_response_channel_stub.h" +#include "iremote_object.h" +#include "service_response_data.h" + +namespace OHOS { +namespace MiscServices { +class ImcResponseChannelImpl final + : public ResponseChannelStub + , public std::enable_shared_from_this { + DISALLOW_COPY_AND_MOVE(ImcResponseChannelImpl); + +public: + ImcResponseChannelImpl(); + ~ImcResponseChannelImpl(); + ErrCode OnResponse(uint32_t requestId, int32_t resultErrCode, const ServiceResponseDataInner &response) override; +}; +} // namespace MiscServices +} // namespace OHOS +#endif // IMF_IMC_RESPONSE_CHANNEL_IMPL_H diff --git a/frameworks/native/inputmethod_controller/include/imc_service_proxy.h b/frameworks/native/inputmethod_controller/include/imc_service_proxy.h index 0a68a3782..9daedf56b 100644 --- a/frameworks/native/inputmethod_controller/include/imc_service_proxy.h +++ b/frameworks/native/inputmethod_controller/include/imc_service_proxy.h @@ -16,34 +16,52 @@ #ifndef IMF_IMC_SERVICE_PROXY_H #define IMF_IMC_SERVICE_PROXY_H -#include "i_service_proxy.h" +#include +#include +#include +#include + +#include "iimc_response_channel.h" +#include "iinput_method_system_ability.h" #include "input_client_info.h" +#include "input_death_recipient.h" #include "input_method_utils.h" +#include "service_response_data.h" namespace OHOS { namespace MiscServices { -class ImcServiceProxy : public IServiceProxy { +class ImcServiceProxy { private: - ImcServiceProxy() = default; + ImcServiceProxy(); public: static ImcServiceProxy &GetInstance(); - using IServiceProxy::SendRequest; - template - int32_t SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout); - - ~ImcServiceProxy() override = default; + ~ImcServiceProxy() = default; ImcServiceProxy(const ImcServiceProxy &) = delete; ImcServiceProxy(ImcServiceProxy &&) = delete; ImcServiceProxy &operator=(const ImcServiceProxy &) = delete; ImcServiceProxy &operator=(ImcServiceProxy &&) = delete; - void Interrupt() override; - void Resume() override; + int32_t SendRequest(const RequestFunc &request, int64_t timeout); + template + int32_t SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout); + + void OnResponse(RequestId id, const ServiceResponse &responseData); + + void RemoveDeathRecipient(); + + void Interrupt(); + void Resume(); private: - void OnRemoteSaDied(const wptr &remote) override; + sptr TryGetSystemAbilityProxy(); + sptr GetSystemAbilityProxy(bool ifRetry = true); + void OnRemoteSaDied(const wptr &remote); + std::atomic hasRegistered_{ false }; + std::mutex abilityLock_{}; + sptr abilityManager_ = nullptr; + sptr deathRecipient_; public: int32_t StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response); @@ -82,6 +100,23 @@ public: int32_t StartInputType(int32_t type); int32_t ConnectSystemCmd(const sptr &channel, sptr &agent); + +private: + void Init(); + RequestId GetNextRequestId(); + int32_t RegisterResponseChannel(); + int32_t SendRequestInner(const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout); + + void AddRequest(RequestId id, PendingRequest pendingRequest); + void RemoveRequest(RequestId requestId); + + std::mutex requestsMutex_{}; + std::unordered_map pendingRequests_; + std::atomic lastId_{ 0 }; + + sptr responseChannelStub_{ nullptr }; + std::atomic currentRequestId_{ 0 }; + std::atomic isInterrupted_{ false }; }; } // namespace MiscServices } // namespace OHOS diff --git a/common/include/message.h b/frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp similarity index 50% rename from common/include/message.h rename to frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp index 9962415e9..e9c385b24 100644 --- a/common/include/message.h +++ b/frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Huawei Device Co., Ltd. + * 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 @@ -13,30 +13,27 @@ * limitations under the License. */ -/*! \file MessageHandler.h */ -#ifndef SERVICES_INCLUDE_MESSAGE_H -#define SERVICES_INCLUDE_MESSAGE_H +#include "imc_response_channel_impl.h" -#include - -#include "message_parcel.h" +#include "imc_service_proxy.h" namespace OHOS { namespace MiscServices { -class Message { -public: - int32_t msgId_{ 0 }; // message id - MessageParcel *msgContent_ = nullptr; // message content - Message(int32_t msgId, MessageParcel *msgContent); - explicit Message(const Message &msg); - Message &operator=(const Message &msg); - ~Message(); -private: - Message(const Message &&); - Message &operator=(const Message &&); -}; -} // namespace MiscServices -} // namespace OHOS +ImcResponseChannelImpl::ImcResponseChannelImpl() +{ +} -#endif // SERVICES_INCLUDE_MESSAGE_H +ImcResponseChannelImpl::~ImcResponseChannelImpl() +{ +} + +ErrCode ImcResponseChannelImpl::OnResponse( + uint32_t requestId, int32_t resultErrCode, const ServiceResponseDataInner &response) +{ + ServiceResponse serviceResponse = { .result = resultErrCode, .responseData = response.data }; + ImcServiceProxy::GetInstance().OnResponse(requestId, serviceResponse); + return ERR_OK; +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp b/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp index cbc551b6c..771a9cb62 100644 --- a/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp +++ b/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp @@ -15,11 +15,13 @@ #include "imc_service_proxy.h" +#include "imc_response_channel_impl.h" #include "ime_system_channel.h" #include "input_client_info.h" #include "input_method_controller.h" #include "input_method_tools.h" #include "input_method_utils.h" +#include "on_demand_start_stop_sa.h" #include "variant_util.h" namespace OHOS { @@ -42,6 +44,121 @@ ImcServiceProxy &ImcServiceProxy::GetInstance() return imcServiceProxy; } +ImcServiceProxy::ImcServiceProxy() +{ + Init(); + +} + +void ImcServiceProxy::Init() +{ + IMSA_HILOGD("start"); + sptr channel = new (std::nothrow) ImcResponseChannelImpl(); + if (channel == nullptr) { + IMSA_HILOGE("failed to create channel!"); + return; + } + responseChannelStub_ = channel; +} + +RequestId ImcServiceProxy::GetNextRequestId() +{ + static std::atomic seqId{ 1 }; + return seqId.fetch_add(1, std::memory_order_seq_cst); +} + +int32_t ImcServiceProxy::SendRequest(const RequestFunc &request, int64_t timeout) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + // wait till timeout + if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + return ErrorCode::NO_ERROR; +} + +int32_t ImcServiceProxy::SendRequestInner( + const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout) +{ + if (request == nullptr) { + IMSA_HILOGE("request is nullptr"); + return ErrorCode::ERROR_IMC_NULLPTR; + } + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + + PendingRequest pendingRequest; + RequestId id = GetNextRequestId(); + auto future = pendingRequest.promise.get_future(); + AddRequest(id, std::move(pendingRequest)); + + // send request + int32_t ret = request(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("request failed, ret: %{public}d", ret); + RemoveRequest(id); + return ret; + } + + if (isInterrupted_.load()) { + IMSA_HILOGW("request is interrupted"); + return ErrorCode::ERROR_REQUEST_INTERRUPTED; + } + // wait till timeout + if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { + IMSA_HILOGE("service handle timeout"); + RemoveRequest(id); + return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; + } + + // handle response + ServiceResponse response = future.get(); + ret = response.result; + RemoveRequest(id); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("task failed"); + return ret; + } + responseData = response.responseData; + return ErrorCode::NO_ERROR; +} + template int32_t ImcServiceProxy::SendRequest(const RequestFunc &request, ResultType &resultValue, int64_t timeout) { @@ -95,6 +212,81 @@ void ImcServiceProxy::Resume() isInterrupted_.store(false); } +sptr ImcServiceProxy::TryGetSystemAbilityProxy() +{ +#ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE + return GetSystemAbilityProxy(false); +#else + return GetSystemAbilityProxy(true); +#endif +} + +sptr ImcServiceProxy::GetSystemAbilityProxy(bool ifRetry) +{ + std::lock_guard lock(abilityLock_); + if (abilityManager_ != nullptr) { + return abilityManager_; + } + IMSA_HILOGD("get input method service proxy."); + auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(ifRetry); + if (systemAbility == nullptr) { + IMSA_HILOGE("systemAbility is nullptr!"); + return nullptr; + } + + if (deathRecipient_ == nullptr) { + deathRecipient_ = new (std::nothrow) InputDeathRecipient(); + if (deathRecipient_ == nullptr) { + IMSA_HILOGE("create death recipient failed!"); + return nullptr; + } + } + deathRecipient_->SetDeathRecipient([this](const wptr &remote) { OnRemoteSaDied(remote); }); + if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { + IMSA_HILOGE("failed to add death recipient!"); + return nullptr; + } + abilityManager_ = iface_cast(systemAbility); + return abilityManager_; +} + +void ImcServiceProxy::RemoveDeathRecipient() +{ + std::lock_guard lock(abilityLock_); + if (abilityManager_ != nullptr && abilityManager_->AsObject() != nullptr && deathRecipient_ != nullptr) { + abilityManager_->AsObject()->RemoveDeathRecipient(deathRecipient_); + } + deathRecipient_ = nullptr; + abilityManager_ = nullptr; +} + +void ImcServiceProxy::AddRequest(RequestId id, PendingRequest pendingRequest) +{ + std::lock_guard lock(requestsMutex_); + pendingRequests_[id] = std::move(pendingRequest); + currentRequestId_.store(id); +} + +void ImcServiceProxy::RemoveRequest(RequestId requestId) +{ + std::lock_guard lock(requestsMutex_); + pendingRequests_.erase(requestId); + currentRequestId_.store(0); +} + +int32_t ImcServiceProxy::RegisterResponseChannel() +{ + if (hasRegistered_.load()) { + return ErrorCode::NO_ERROR; + } + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("failed to get sa proxy"); + return ErrorCode::ERROR_IPC_REMOTE_NULLPTR; + } + return proxy->RegisterImcResponseChannel(responseChannelStub_); +} + int32_t ImcServiceProxy::StartInput(InputClientInfo &inputClientInfo, StartInputResponse &response) { RequestFunc request = [&inputClientInfo, this](RequestId requestId) -> int32_t { diff --git a/frameworks/native/service_proxy/BUILD.gn b/frameworks/native/service_proxy/BUILD.gn deleted file mode 100644 index 5016e7dfd..000000000 --- a/frameworks/native/service_proxy/BUILD.gn +++ /dev/null @@ -1,145 +0,0 @@ -# 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. - -import("//base/inputmethod/imf/inputmethod.gni") -import("//build/config/components/idl_tool/idl.gni") -import("//build/ohos.gni") - -idl_gen_interface("response_channel_interface") { - src_idl = rebase_path( - "${inputmethod_path}/frameworks/native/service_proxy/IResponseChannel.idl") -} - -config("response_channel_native_public_config") { - include_dirs = [ - "include", - "${inputmethod_path}/frameworks/native/service_proxy", - "${target_gen_dir}", - ] -} - -config("service_proxy_native_public_config") { - visibility = [ ":*" ] - include_dirs = [ - "include", - "${inputmethod_path}/common/include", - "${inputmethod_path}/frameworks/native/inputmethod_ability/include", - "${inputmethod_path}/frameworks/native/inputmethod_controller/include", - "${inputmethod_path}/interfaces/inner_api/inputmethod_ability/include", - "${inputmethod_path}/interfaces/inner_api/inputmethod_controller/include", - "${target_gen_dir}", - ] -} - -ohos_source_set("response_channel_proxy") { - sanitize = { - cfi = true - cfi_cross_dso = true - debug = false - } - public_configs = [ ":response_channel_native_public_config" ] - output_values = get_target_outputs(":response_channel_interface") - sources = filter_include(output_values, [ "*_proxy.cpp" ]) - deps = [ ":response_channel_interface" ] - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - "input:libmmi-client", - "ipc:ipc_single", - "samgr:samgr_proxy", - ] - subsystem_name = "inputmethod" - part_name = "imf" -} - -ohos_source_set("response_channel_stub") { - sanitize = { - cfi = true - cfi_cross_dso = true - debug = false - } - public_configs = [ ":response_channel_native_public_config" ] - output_values = get_target_outputs(":response_channel_interface") - sources = filter_include(output_values, [ "*_stub.cpp" ]) - deps = [ ":response_channel_interface" ] - external_deps = [ - "c_utils:utils", - "hilog:libhilog", - "input:libmmi-client", - "ipc:ipc_single", - "samgr:samgr_proxy", - ] - subsystem_name = "inputmethod" - part_name = "imf" -} - -ohos_shared_library("service_proxy") { - branch_protector_ret = "pac_ret" - sanitize = { - boundary_sanitize = true - cfi = true - cfi_cross_dso = true - debug = false - integer_overflow = true - ubsan = true - } - cflags_cc = [ - "-fdata-sections", - "-ffunction-sections", - "-Os", - "-Wno-c99-designator", - ] - - sources = [ - "${inputmethod_path}/frameworks/native/service_proxy/src/i_service_proxy.cpp", - "${inputmethod_path}/frameworks/native/service_proxy/src/response_channel_impl.cpp", - "${inputmethod_path}/frameworks/native/service_proxy/src/service_response_data.cpp", - ] - - configs = [ - ":service_proxy_native_public_config", - "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_native_public_config", - "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:inputmethod_ability_native_public_config", - ] - - deps = [ - ":response_channel_interface", - "${inputmethod_path}/common:inputmethod_common", - "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:inputmethod_ability", - "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client", - ] - - response_channel_output_values = get_target_outputs(":response_channel_interface") - sources += filter_include(response_channel_output_values, - [ - "*_proxy.cpp", - "*_stub.cpp", - ]) - - external_deps = [ - "ability_base:want", - "ability_runtime:runtime", - "bundle_framework:appexecfwk_base", - "cJSON:cjson", - "hilog:libhilog", - "input:libmmi-client", - "ipc:ipc_single", - "safwk:system_ability_fwk", - "samgr:samgr_proxy", - ] - - public_configs = [ ":service_proxy_native_public_config" ] - - subsystem_name = "inputmethod" - part_name = "imf" -} diff --git a/frameworks/native/service_proxy/include/i_service_proxy.h b/frameworks/native/service_proxy/include/i_service_proxy.h deleted file mode 100644 index d3a1c1fbb..000000000 --- a/frameworks/native/service_proxy/include/i_service_proxy.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - */ - -#ifndef IMF_I_SERVICE_PROXY_H -#define IMF_I_SERVICE_PROXY_H - -#include -#include -#include -#include - -#include "input_death_recipient.h" -#include "service_response_data.h" - -namespace OHOS { -namespace MiscServices { -constexpr int64_t SERVICE_PROXY_TIMEOUT = 1000; // 1s -using RequestId = uint32_t; -using RequestFunc = std::function; -struct PendingRequest { - std::promise promise; -}; -class IServiceProxy { -public: - IServiceProxy(); - virtual ~IServiceProxy() = default; - - virtual int32_t SendRequest(const RequestFunc &request, int64_t timeout); - virtual void OnResponse(RequestId id, const ServiceResponse &responseData); - virtual void RemoveDeathRecipient(); - - virtual void Interrupt(); - virtual void Resume(); - -protected: - virtual int32_t SendRequestInner(const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout); - virtual void OnRemoteSaDied(const wptr &remote) = 0; - - uint32_t GetNextRequestId(); - - int32_t RegisterResponseChannel(); - void AddRequest(RequestId id, PendingRequest pendingRequest); - void RemoveRequest(RequestId requestId); - - sptr TryGetSystemAbilityProxy(); - sptr GetSystemAbilityProxy(bool ifRetry = true); - - std::atomic hasRegistered_{ false }; - std::mutex abilityLock_{}; - sptr abilityManager_ = nullptr; - sptr deathRecipient_; - - std::atomic currentRequestId_{ 0 }; - std::atomic isInterrupted_{ false }; - -private: - void Init(); - - std::mutex requestsMutex_{}; - std::unordered_map pendingRequests_; - std::atomic lastId_{ 0 }; - - sptr responseChannelStub_{ nullptr }; -}; -} // namespace MiscServices -} // namespace OHOS - -#endif //IMF_I_SERVICE_PROXY_H diff --git a/frameworks/native/service_proxy/src/i_service_proxy.cpp b/frameworks/native/service_proxy/src/i_service_proxy.cpp deleted file mode 100644 index 5593438f5..000000000 --- a/frameworks/native/service_proxy/src/i_service_proxy.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * 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 "i_service_proxy.h" - -#include "iinput_method_system_ability.h" -#include "input_method_system_ability_proxy.h" -#include "on_demand_start_stop_sa.h" -#include "response_channel_impl.h" -#include "system_ability_definition.h" -#include "variant_util.h" - -namespace OHOS { -namespace MiscServices { -IServiceProxy::IServiceProxy() -{ - Init(); -} - -void IServiceProxy::Init() -{ - IMSA_HILOGD("start"); - sptr channel = new (std::nothrow) ResponseChannelImpl(); - if (channel == nullptr) { - IMSA_HILOGE("failed to create channel!"); - return; - } - responseChannelStub_ = channel; -} - -uint32_t IServiceProxy::GetNextRequestId() -{ - uint32_t id = lastId_.fetch_add(1, std::memory_order_seq_cst); - return id; -} - -void IServiceProxy::OnResponse(RequestId id, const ServiceResponse &responseData) -{ - std::lock_guard lock(requestsMutex_); - auto iter = pendingRequests_.find(id); - if (iter == pendingRequests_.end()) { - IMSA_HILOGE("failed to find pending request, id: %{public}d", id); - return; - } - IMSA_HILOGD("id: %{public}d", id); - iter->second.promise.set_value(responseData); -} - -void IServiceProxy::Interrupt() -{ -} - -void IServiceProxy::Resume() -{ -} - -sptr IServiceProxy::TryGetSystemAbilityProxy() -{ -#ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE - return GetSystemAbilityProxy(false); -#else - return GetSystemAbilityProxy(true); -#endif -} - -sptr IServiceProxy::GetSystemAbilityProxy(bool ifRetry) -{ - std::lock_guard lock(abilityLock_); - if (abilityManager_ != nullptr) { - return abilityManager_; - } - IMSA_HILOGD("get input method service proxy."); - auto systemAbility = OnDemandStartStopSa::GetInputMethodSystemAbility(ifRetry); - if (systemAbility == nullptr) { - IMSA_HILOGE("systemAbility is nullptr!"); - return nullptr; - } - - if (deathRecipient_ == nullptr) { - deathRecipient_ = new (std::nothrow) InputDeathRecipient(); - if (deathRecipient_ == nullptr) { - IMSA_HILOGE("create death recipient failed!"); - return nullptr; - } - } - deathRecipient_->SetDeathRecipient([this](const wptr &remote) { OnRemoteSaDied(remote); }); - if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) { - IMSA_HILOGE("failed to add death recipient!"); - return nullptr; - } - abilityManager_ = iface_cast(systemAbility); - return abilityManager_; -} - -void IServiceProxy::RemoveDeathRecipient() -{ - std::lock_guard lock(abilityLock_); - if (abilityManager_ != nullptr && abilityManager_->AsObject() != nullptr && deathRecipient_ != nullptr) { - abilityManager_->AsObject()->RemoveDeathRecipient(deathRecipient_); - } - deathRecipient_ = nullptr; - abilityManager_ = nullptr; -} - -int32_t IServiceProxy::SendRequest(const RequestFunc &request, int64_t timeout) -{ - if (request == nullptr) { - IMSA_HILOGE("request is nullptr"); - return ErrorCode::ERROR_IMC_NULLPTR; - } - if (isInterrupted_.load()) { - IMSA_HILOGW("request is interrupted"); - return ErrorCode::ERROR_REQUEST_INTERRUPTED; - } - PendingRequest pendingRequest; - RequestId id = GetNextRequestId(); - auto future = pendingRequest.promise.get_future(); - AddRequest(id, std::move(pendingRequest)); - - // send request - int32_t ret = request(id); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("request failed, ret: %{public}d", ret); - RemoveRequest(id); - return ret; - } - - if (isInterrupted_.load()) { - IMSA_HILOGW("request is interrupted"); - return ErrorCode::ERROR_REQUEST_INTERRUPTED; - } - // wait till timeout - if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { - IMSA_HILOGE("service handle timeout"); - RemoveRequest(id); - return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; - } - - // handle response - ServiceResponse response = future.get(); - ret = response.result; - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("task failed"); - return ret; - } - return ErrorCode::NO_ERROR; -} - -int32_t IServiceProxy::SendRequestInner(const RequestFunc &request, ServiceResponseData &responseData, int64_t timeout) -{ - if (request == nullptr) { - IMSA_HILOGE("request is nullptr"); - return ErrorCode::ERROR_IMC_NULLPTR; - } - if (isInterrupted_.load()) { - IMSA_HILOGW("request is interrupted"); - return ErrorCode::ERROR_REQUEST_INTERRUPTED; - } - - PendingRequest pendingRequest; - RequestId id = GetNextRequestId(); - auto future = pendingRequest.promise.get_future(); - AddRequest(id, std::move(pendingRequest)); - - // send request - int32_t ret = request(id); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("request failed, ret: %{public}d", ret); - RemoveRequest(id); - return ret; - } - - if (isInterrupted_.load()) { - IMSA_HILOGW("request is interrupted"); - return ErrorCode::ERROR_REQUEST_INTERRUPTED; - } - // wait till timeout - if (future.wait_for(std::chrono::milliseconds(timeout)) != std::future_status::ready) { - IMSA_HILOGE("service handle timeout"); - RemoveRequest(id); - return ErrorCode::ERROR_IMC_SERVICE_RESPONSE_TIMEOUT; - } - - // handle response - ServiceResponse response = future.get(); - ret = response.result; - RemoveRequest(id); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("task failed"); - return ret; - } - responseData = response.responseData; - return ErrorCode::NO_ERROR; -} - -int32_t IServiceProxy::RegisterResponseChannel() -{ - if (hasRegistered_.load()) { - return ErrorCode::NO_ERROR; - } - auto proxy = GetSystemAbilityProxy(); - if (proxy == nullptr) { - IMSA_HILOGE("failed to get sa proxy"); - return ErrorCode::ERROR_IPC_REMOTE_NULLPTR; - } - return proxy->RegisterResponseChannel(responseChannelStub_); -} - -void IServiceProxy::AddRequest(RequestId id, PendingRequest pendingRequest) -{ - std::lock_guard lock(requestsMutex_); - pendingRequests_[id] = std::move(pendingRequest); - currentRequestId_.store(id); -} - -void IServiceProxy::RemoveRequest(RequestId requestId) -{ - std::lock_guard lock(requestsMutex_); - pendingRequests_.erase(requestId); - currentRequestId_.store(0); -} -} // namespace MiscServices -} // namespace OHOS \ No newline at end of file diff --git a/interfaces/inner_api/inputmethod_ability/BUILD.gn b/interfaces/inner_api/inputmethod_ability/BUILD.gn index 2560aa7ce..df2a78467 100644 --- a/interfaces/inner_api/inputmethod_ability/BUILD.gn +++ b/interfaces/inner_api/inputmethod_ability/BUILD.gn @@ -50,10 +50,16 @@ idl_gen_interface("keyevent_consumer_interface") { "${inputmethod_path}/frameworks/native/inputmethod_controller/IKeyEventConsumer.idl") } +idl_gen_interface("ima_response_channel_interface") { + src_idl = rebase_path( + "${inputmethod_path}/frameworks/native/inputmethod_ability/IImaResponseChannel.idl") +} + config("inputmethod_ability_native_config") { visibility = [ ":*" ] include_dirs = [ "include", + "${inputmethod_path}/frameworks/native/common/include", "${inputmethod_path}/frameworks/native/inputmethod_ability/include", "${inputmethod_path}/frameworks/native/inputmethod_controller/include", "${inputmethod_path}/frameworks/common", @@ -75,6 +81,7 @@ config("inputmethod_ability_native_public_config") { include_dirs = [ "include", "${inputmethod_path}/common/include", + "${inputmethod_path}/frameworks/native/common/include", "${inputmethod_path}/frameworks/native/inputmethod_ability/include", "${inputmethod_path}/frameworks/native/inputmethod_controller/include", "${inputmethod_path}/frameworks/common", @@ -265,7 +272,6 @@ ohos_source_set("input_method_system_ability_stub") { } public_configs = [ ":inputmethod_ability_native_public_config", - "${inputmethod_path}/frameworks/native/service_proxy:response_channel_native_public_config", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_native_public_config", ] output_values = get_target_outputs(":input_method_system_ability_interface") @@ -303,6 +309,48 @@ ohos_source_set("keyevent_consumer_stub") { part_name = "imf" } +ohos_source_set("ima_response_channel_proxy") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + public_configs = [ ":inputmethod_ability_native_public_config" ] + output_values = get_target_outputs(":ima_response_channel_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":response_channel_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + subsystem_name = "inputmethod" + part_name = "imf" +} + +ohos_source_set("ima_response_channel_stub") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + public_configs = [ ":inputmethod_ability_native_public_config" ] + output_values = get_target_outputs(":ima_response_channel_interface") + sources = filter_include(output_values, [ "*_stub.cpp" ]) + deps = [ ":response_channel_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + subsystem_name = "inputmethod" + part_name = "imf" +} + ohos_shared_library("inputmethod_ability") { branch_protector_ret = "pac_ret" sanitize = { @@ -314,6 +362,8 @@ ohos_shared_library("inputmethod_ability") { ubsan = true } sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_method_ability.cpp", @@ -366,6 +416,7 @@ ohos_shared_library("inputmethod_ability") { public_external_deps = [ "window_manager:libwm" ] deps = [ + ":ima_response_channel_interface", ":input_control_channel_interface", ":input_data_channel_interface", ":input_method_core_interface", @@ -375,8 +426,6 @@ ohos_shared_library("inputmethod_ability") { ":system_cmd_channel_interface", "${inputmethod_path}/common:inputmethod_common", "${inputmethod_path}/common/imf_hisysevent:imf_hisysevent", - "${inputmethod_path}/frameworks/native/service_proxy:response_channel_proxy", - "${inputmethod_path}/frameworks/native/service_proxy:service_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_stub", "${inputmethod_path}/services/file:imf_file_static", "${inputmethod_path}/services/json:imf_json_static", @@ -437,6 +486,13 @@ ohos_shared_library("inputmethod_ability") { "*_stub.cpp", ]) + ima_response_channel_output_values = get_target_outputs(":ima_response_channel_interface") + sources += filter_include(ima_response_channel_output_values, + [ + "*_proxy.cpp", + "*_stub.cpp", + ]) + public_configs = [ ":inputmethod_ability_native_public_config" ] subsystem_name = "inputmethod" @@ -452,6 +508,8 @@ ohos_static_library("inputmethod_ability_static") { debug = false } sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_data_channel_proxy_wrap.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_method_ability.cpp", @@ -495,6 +553,7 @@ ohos_static_library("inputmethod_ability_static") { public_external_deps = [ "window_manager:libwm" ] deps = [ + ":ima_response_channel_interface", ":input_control_channel_interface", ":input_data_channel_interface", ":input_method_core_interface", @@ -503,8 +562,6 @@ ohos_static_library("inputmethod_ability_static") { ":system_cmd_channel_interface", "${inputmethod_path}/common:inputmethod_common", "${inputmethod_path}/common/imf_hisysevent:imf_hisysevent", - "${inputmethod_path}/frameworks/native/service_proxy:response_channel_proxy", - "${inputmethod_path}/frameworks/native/service_proxy:service_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_stub", "${inputmethod_path}/services/file:imf_file_static", @@ -558,6 +615,13 @@ ohos_static_library("inputmethod_ability_static") { "*_stub.cpp", ]) + ima_response_channel_output_values = get_target_outputs(":ima_response_channel_interface") + sources += filter_include(ima_response_channel_output_values, + [ + "*_proxy.cpp", + "*_stub.cpp", + ]) + public_configs = [ ":inputmethod_ability_native_public_config" ] subsystem_name = "inputmethod" @@ -568,6 +632,8 @@ ohos_static_library("inputmethod_ability_fuzz_static") { branch_protector_ret = "pac_ret" sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/ima_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_method_ability.cpp", "${inputmethod_path}/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp", @@ -607,6 +673,7 @@ ohos_static_library("inputmethod_ability_fuzz_static") { public_external_deps = [ "window_manager:libwm" ] deps = [ + ":ima_response_channel_interface", ":input_control_channel_interface", ":input_data_channel_interface", ":input_method_core_interface", @@ -615,8 +682,6 @@ ohos_static_library("inputmethod_ability_fuzz_static") { ":system_cmd_channel_interface", "${inputmethod_path}/common:inputmethod_common", "${inputmethod_path}/common/imf_hisysevent:imf_hisysevent", - "${inputmethod_path}/frameworks/native/service_proxy:response_channel_proxy", - "${inputmethod_path}/frameworks/native/service_proxy:service_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_stub", "${inputmethod_path}/services/file:imf_file_static", @@ -670,6 +735,13 @@ ohos_static_library("inputmethod_ability_fuzz_static") { "*_stub.cpp", ]) + ima_response_channel_output_values = get_target_outputs(":ima_response_channel_interface") + sources += filter_include(ima_response_channel_output_values, + [ + "*_proxy.cpp", + "*_stub.cpp", + ]) + public_configs = [ ":inputmethod_ability_native_public_config" ] subsystem_name = "inputmethod" diff --git a/interfaces/inner_api/inputmethod_controller/BUILD.gn b/interfaces/inner_api/inputmethod_controller/BUILD.gn index f61e4a23a..151418f96 100644 --- a/interfaces/inner_api/inputmethod_controller/BUILD.gn +++ b/interfaces/inner_api/inputmethod_controller/BUILD.gn @@ -25,12 +25,18 @@ idl_gen_interface("input_method_agent_interface") { "${inputmethod_path}/frameworks/native/inputmethod_ability/IInputMethodAgent.idl") } +idl_gen_interface("imc_response_channel_interface") { + src_idl = rebase_path( + "${inputmethod_path}/frameworks/native/inputmethod_controller/IImcResponseChannel.idl") +} + config("inputmethod_client_native_config") { visibility = [ ":*" ] include_dirs = [ "include", "${inputmethod_path}/common/include", "${inputmethod_path}/frameworks/common", + "${inputmethod_path}/frameworks/native/common", "${inputmethod_path}/frameworks/native/inputmethod_controller/include", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller/include", "${inputmethod_path}/services/include", @@ -50,6 +56,7 @@ config("inputmethod_client_native_public_config") { "include", "${inputmethod_path}/common/include", "${inputmethod_path}/frameworks/common", + "${inputmethod_path}/frameworks/native/common", "${inputmethod_path}/frameworks/native/inputmethod_controller/include", "${inputmethod_path}/frameworks/native/inputmethod_ability/include", "${inputmethod_path}/interfaces/inner_api/inputmethod_ability/include", @@ -147,6 +154,48 @@ ohos_source_set("input_method_agent_proxy") { part_name = "imf" } +ohos_source_set("imc_response_channel_proxy") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + public_configs = [ ":inputmethod_client_native_public_config" ] + output_values = get_target_outputs(":imc_response_channel_interface") + sources = filter_include(output_values, [ "*_proxy.cpp" ]) + deps = [ ":response_channel_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + subsystem_name = "inputmethod" + part_name = "imf" +} + +ohos_source_set("imc_response_channel_stub") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + public_configs = [ ":inputmethod_client_native_public_config" ] + output_values = get_target_outputs(":imc_response_channel_interface") + sources = filter_include(output_values, [ "*_stub.cpp" ]) + deps = [ ":response_channel_interface" ] + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + "samgr:samgr_proxy", + ] + subsystem_name = "inputmethod" + part_name = "imf" +} + ohos_shared_library("inputmethod_client") { branch_protector_ret = "pac_ret" @@ -159,6 +208,8 @@ ohos_shared_library("inputmethod_client") { ubsan = true } sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager_impl.cpp", @@ -187,12 +238,11 @@ ohos_shared_library("inputmethod_client") { innerapi_tags = [ "platformsdk" ] deps = [ + ":imc_response_channel_interface", ":input_client_interface", ":input_method_agent_interface", "${inputmethod_path}/common:inputmethod_common", "${inputmethod_path}/common/imf_hisysevent:imf_hisysevent", - "${inputmethod_path}/frameworks/native/service_proxy:response_channel_proxy", - "${inputmethod_path}/frameworks/native/service_proxy:service_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:input_control_channel_stub", "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:input_data_channel_stub", "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:input_method_core_proxy", @@ -215,6 +265,13 @@ ohos_shared_library("inputmethod_client") { "*_stub.cpp", ]) + imc_response_channel_output_values = get_target_outputs(":imc_response_channel_interface") + sources += filter_include(imc_response_channel_output_values, + [ + "*_proxy.cpp", + "*_stub.cpp", + ]) + external_deps = [ "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", @@ -260,6 +317,8 @@ ohos_static_library("inputmethod_client_static") { ubsan = true } sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager_impl.cpp", @@ -331,6 +390,8 @@ ohos_static_library("inputmethod_client_fuzz_static") { ubsan = true } sources = [ + "${inputmethod_path}/frameworks/native/common/src/service_response_data.cpp", + "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_response_channel_impl.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/imc_service_proxy.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/ime_event_monitor_manager_impl.cpp", diff --git a/services/include/im_common_event_manager.h b/services/include/im_common_event_manager.h index 374604c72..4f3aef3fb 100644 --- a/services/include/im_common_event_manager.h +++ b/services/include/im_common_event_manager.h @@ -31,7 +31,6 @@ private: ImCommonEventManager() = default; public: - master static ImCommonEventManager &GetInstance(); ~ImCommonEventManager() = default; @@ -45,18 +44,6 @@ public: void RegisterEventHandler(const std::string &eventName, const CommonEventHandler &handler); void RegisterSaHandler(int32_t saId, const Handler &handler); -======= - ImCommonEventManager(); - ~ImCommonEventManager(); - static sptr GetInstance(); - bool SubscribeEvent(); - bool SubscribeKeyboardEvent(const Handler &handler); - bool SubscribeWindowManagerService(const Handler &handler); - bool SubscribeMemMgrService(const Handler &handler); - bool SubscribeAccountManagerService(Handler handle); - bool SubscribePasteboardService(const Handler &handler); - bool UnsubscribeEvent(); ->>>>>>> master // only public the status change of softKeyboard in FLG_FIXED or FLG_FLOATING int32_t PublishPanelStatusChangeEvent(int32_t userId, const InputWindowStatus &status, const ImeWindowInfo &info); diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 5c5ded294..71c9b8b6d 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -44,7 +44,8 @@ public: ~InputMethodSystemAbility(); int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; - ErrCode RegisterResponseChannel(sptr channel) override; + ErrCode RegisterImaResponseChannel(sptr channel) override; + ErrCode RegisterImcResponseChannel(sptr channel) override; ErrCode StartInput(uint32_t requestId, const InputClientInfoInner &inputClientInfoInner) override; ErrCode ShowCurrentInput(uint32_t requestId, uint32_t type = static_cast(ClientType::INNER_KIT)) override; ErrCode HideCurrentInput(uint32_t requestId) override; @@ -93,6 +94,7 @@ public: uint32_t requestId, const std::string &bundleName, const std::string &extensionName, int32_t status) override; ErrCode GetInputMethodState(uint32_t requestId) override; ErrCode IsSystemApp(uint32_t requestId) override; + ErrCode IsSystemImeApp(uint32_t requestId) override; ErrCode RegisterProxyIme(uint32_t requestId, uint64_t displayId, const sptr &core, const sptr &agent) override; ErrCode UnregisterProxyIme(uint32_t requestId, uint64_t displayId) override; @@ -160,11 +162,8 @@ private: void HandleMMIStarted(); void HandleFocusChanged(bool isFocused, uint64_t displayId, int32_t pid, int32_t uid); void HandleImeCfgCapsState(); - master void HandleDisplayChanged(const Rosen::CallingWindowInfo &callingWindowInfo); -======= void HandlePasteboardStarted(); ->>>>>>> master void StopImeInBackground(); static std::shared_ptr serviceHandler_; int32_t userId_; @@ -176,7 +175,6 @@ private: void InitWmsConnectionMonitor(); void InitFocusChangedMonitor(); void InitWindowDisplayChangedMonitor(); - bool InitPasteboardMonitor(); int32_t SwitchByCombinationKey(uint32_t state); int32_t SwitchMode(); int32_t SwitchLanguage(); diff --git a/services/src/im_common_event_manager.cpp b/services/src/im_common_event_manager.cpp index 9fd5cba0d..1f8f64468 100644 --- a/services/src/im_common_event_manager.cpp +++ b/services/src/im_common_event_manager.cpp @@ -51,6 +51,7 @@ const std::unordered_map SA_EVENT_TASK_CODE{ { WINDOW_MANAGER_SERVICE_ID, SaTaskCode::ON_WMS_SA_STARTED }, { COMMON_EVENT_SERVICE_ID, SaTaskCode::ON_COMMON_EVENT_SA_STARTED }, }; + ImCommonEventManager &ImCommonEventManager::GetInstance() { static ImCommonEventManager imCommonEventManager; @@ -91,80 +92,10 @@ bool ImCommonEventManager::SubscribeEvents() void ImCommonEventManager::SubscribeSaStatus() { - master - for (const auto iter : serviceHandlers_) { + for (const auto &iter : serviceHandlers_) { auto ret = SubscribeManagerServiceCommon(iter.second, iter.first); IMSA_HILOGI("subscribe sa: %{public}d, result: %{public}d", iter.first, ret); } -======= - IMSA_HILOGI("start."); - return SubscribeManagerServiceCommon(handler, WINDOW_MANAGER_SERVICE_ID); -} - -bool ImCommonEventManager::SubscribeMemMgrService(const Handler &handler) -{ - return SubscribeManagerServiceCommon(handler, MEMORY_MANAGER_SA_ID); -} - -bool ImCommonEventManager::SubscribeAccountManagerService(Handler handler) -{ - return SubscribeManagerServiceCommon(handler, SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN); -} - -bool ImCommonEventManager::SubscribePasteboardService(const Handler &handler) -{ - return SubscribeManagerServiceCommon(handler, PASTEBOARD_SERVICE_ID); -} - -bool ImCommonEventManager::UnsubscribeEvent() -{ - return true; -} - -ImCommonEventManager::EventSubscriber::EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscribeInfo) - : EventFwk::CommonEventSubscriber(subscribeInfo) -{ - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_SWITCHED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->StartUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_STOPPED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->StopUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_USER_REMOVED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->RemoveUser(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->RemovePackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnBundleScanFinished(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_DATA_SHARE_READY] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnDataShareReady(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->AddPackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->ChangePackage(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->HandleBootCompleted(data); - }; - EventManagerFunc_[CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED] = - [] (EventSubscriber *that, const EventFwk::CommonEventData &data) { - return that->OnScreenUnlock(data); - }; ->>>>>>> master } void ImCommonEventManager::EventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data) @@ -214,14 +145,8 @@ void ImCommonEventManager::SystemAbilityStatusChangeListener::OnAddSystemAbility int32_t systemAbilityId, const std::string &deviceId) { IMSA_HILOGD("systemAbilityId: %{public}d.", systemAbilityId); - master auto iter = SA_EVENT_TASK_CODE.find(systemAbilityId); if (iter == SA_EVENT_TASK_CODE.end()) { -======= - if (systemAbilityId != COMMON_EVENT_SERVICE_ID && systemAbilityId != MULTIMODAL_INPUT_SERVICE_ID && - systemAbilityId != WINDOW_MANAGER_SERVICE_ID && systemAbilityId != SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN && - systemAbilityId != MEMORY_MANAGER_SA_ID && systemAbilityId != PASTEBOARD_SERVICE_ID) { ->>>>>>> master return; } if (func_ == nullptr) { diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index dc738d1ec..670ed4c5f 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -573,18 +573,25 @@ ErrCode InputMethodSystemAbility::ReleaseInput(uint32_t requestId, const sptrimcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + SaActionFunc action = [callerInfo, sessionId](ServiceResponseData &, ActionInnerData &) -> int32_t { std::shared_ptr session = nullptr; GET_USER_SESSION(callerInfo.userId, session, ErrorCode::ERROR_NULL_POINTER); return session->OnReleaseInput(client, sessionId); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::RELEASE_INPUT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::RELEASE_INPUT, action, callerInfo, requester->imcResponseChannel)); +} + +ErrCode InputMethodSystemAbility::RegisterImaResponseChannel(sptr channel) +{ + return RequesterManager::GetInstance().AddImaChannel(IPCSkeleton::GetCallingPid(), channel); } -ErrCode InputMethodSystemAbility::RegisterResponseChannel(sptr channel) +ErrCode InputMethodSystemAbility::RegisterImcResponseChannel(sptr channel) { - return RequesterManager::GetInstance().Add(IPCSkeleton::GetCallingPid(), channel); + return RequesterManager::GetInstance().AddImcChannel(IPCSkeleton::GetCallingPid(), channel); } ErrCode InputMethodSystemAbility::StartInput(uint32_t requestId, const InputClientInfoInner &inputClientInfoInner) @@ -592,6 +599,7 @@ ErrCode InputMethodSystemAbility::StartInput(uint32_t requestId, const InputClie CallerInfo callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); auto clientInfo = InputMethodTools::GetInstance().InnerToInputClientInfo(inputClientInfoInner); // 1 - generate StartInput task @@ -611,7 +619,7 @@ ErrCode InputMethodSystemAbility::StartInput(uint32_t requestId, const InputClie GET_VARIANT_DATA_VALUE(data, response, ErrorCode::ERROR_IMSA_NULLPTR); sharedThis->ReportStartInput(callerInfo, clientInfo, response, ret); }; - auto task = std::make_shared(SaTaskCode::START_INPUT, action, callerInfo, requester->responseChannel); + auto task = std::make_shared(SaTaskCode::START_INPUT, action, callerInfo, requester->imcResponseChannel); task->SetHiSysReporter(reporter); return SaTaskManager::GetInstance().PostTask(task); } @@ -755,6 +763,7 @@ ErrCode InputMethodSystemAbility::IsDefaultImeScreen(uint32_t requestId, uint64_ auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [displayId](ServiceResponseData &data, ActionInnerData &) -> int32_t { bool resultValue = ImeInfoInquirer::GetInstance().IsDefaultImeScreen(displayId); @@ -762,7 +771,7 @@ ErrCode InputMethodSystemAbility::IsDefaultImeScreen(uint32_t requestId, uint64_ return ErrorCode::NO_ERROR; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_DEFAULT_IME_SCREEN, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_DEFAULT_IME_SCREEN, action, callerInfo, requester->imaResponseChannel)); } int32_t InputMethodSystemAbility::ShowInputInner( @@ -785,6 +794,7 @@ ErrCode InputMethodSystemAbility::HideInput(uint32_t requestId, const sptrimcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, client](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -802,7 +812,7 @@ ErrCode InputMethodSystemAbility::HideInput(uint32_t requestId, const sptrOnHideInput(client); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::HIDE_INPUT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::HIDE_INPUT, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::StopInputSession(uint32_t requestId) @@ -810,6 +820,7 @@ ErrCode InputMethodSystemAbility::StopInputSession(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -823,7 +834,7 @@ ErrCode InputMethodSystemAbility::StopInputSession(uint32_t requestId) return session->OnHideCurrentInput(sharedThis->GetCallingDisplayId(callerInfo.pid)); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::STOP_INPUT_SESSION, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::STOP_INPUT_SESSION, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::RequestShowInput(uint32_t requestId) @@ -831,6 +842,7 @@ ErrCode InputMethodSystemAbility::RequestShowInput(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -846,7 +858,7 @@ ErrCode InputMethodSystemAbility::RequestShowInput(uint32_t requestId) return session->OnRequestShowInput(sharedThis->GetCallingDisplayId(callerInfo.pid)); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::REQUEST_SHOW_INPUT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::REQUEST_SHOW_INPUT, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::RequestHideInput(uint32_t requestId, bool isFocusTriggered) @@ -854,6 +866,7 @@ ErrCode InputMethodSystemAbility::RequestHideInput(uint32_t requestId, bool isFo auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, isFocusTriggered](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -875,7 +888,7 @@ ErrCode InputMethodSystemAbility::RequestHideInput(uint32_t requestId, bool isFo return session->OnRequestHideInput(callerInfo.pid, sharedThis->GetCallingDisplayId(callerInfo.pid)); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::REQUEST_HIDE_INPUT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::REQUEST_HIDE_INPUT, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::SetCoreAndAgent( @@ -884,6 +897,7 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent( CallerInfo callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [core, agent, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -892,7 +906,7 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent( return sharedThis->SetCoreAndAgentTask(core, agent); }; auto task = - std::make_shared(SaTaskCode::SET_CORE_AND_AGENT, action, callerInfo, requester->responseChannel); + std::make_shared(SaTaskCode::SET_CORE_AND_AGENT, action, callerInfo, requester->imaResponseChannel); return SaTaskManager::GetInstance().PostTask(task); } @@ -922,6 +936,7 @@ ErrCode InputMethodSystemAbility::RegisterProxyIme( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, displayId, core, agent]( @@ -931,7 +946,7 @@ ErrCode InputMethodSystemAbility::RegisterProxyIme( return sharedThis->RegisterProxyImeTask(callerInfo, displayId, core, agent); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::REGISTER_PROXY_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::REGISTER_PROXY_IME, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::UnregisterProxyIme(uint32_t requestId, uint64_t displayId) @@ -939,6 +954,7 @@ ErrCode InputMethodSystemAbility::UnregisterProxyIme(uint32_t requestId, uint64_ auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, displayId](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -947,7 +963,7 @@ ErrCode InputMethodSystemAbility::UnregisterProxyIme(uint32_t requestId, uint64_ return sharedThis->UnregisterProxyImeTask(callerInfo, displayId); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::UNREGISTER_PROXY_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::UNREGISTER_PROXY_IME, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::InitConnect(uint32_t requestId) @@ -955,6 +971,7 @@ ErrCode InputMethodSystemAbility::InitConnect(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -969,7 +986,7 @@ ErrCode InputMethodSystemAbility::InitConnect(uint32_t requestId) return session->InitConnect(callerInfo.pid); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::INIT_CONNECT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::INIT_CONNECT, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::HideCurrentInput(uint32_t requestId) @@ -977,6 +994,7 @@ ErrCode InputMethodSystemAbility::HideCurrentInput(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -985,7 +1003,7 @@ ErrCode InputMethodSystemAbility::HideCurrentInput(uint32_t requestId) return sharedThis->HideCurrentInputTask(callerInfo); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::HIDE_CURRENT_INPUT, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::HIDE_CURRENT_INPUT, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::ShowCurrentInputInner(const CallerInfo &callerInfo) @@ -1009,6 +1027,7 @@ ErrCode InputMethodSystemAbility::PanelStatusChange(uint32_t requestId, uint32_t auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, status, info, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1017,7 +1036,7 @@ ErrCode InputMethodSystemAbility::PanelStatusChange(uint32_t requestId, uint32_t return sharedThis->PanelStatusChangeTask(callerInfo, status, info); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::PANEL_STATUS_CHANGE, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::PANEL_STATUS_CHANGE, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::UpdateListenEventFlag( @@ -1026,6 +1045,7 @@ ErrCode InputMethodSystemAbility::UpdateListenEventFlag( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, clientInfoInner, eventFlag, weakThis]( @@ -1034,8 +1054,8 @@ ErrCode InputMethodSystemAbility::UpdateListenEventFlag( GET_SHARED_THIS(weakThis, sharedThis, ErrorCode::ERROR_IMSA_NULLPTR); return sharedThis->UpdateListenEventFlagTask(callerInfo, clientInfoInner, eventFlag); }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::UPDATE_LISTEN_EVENT_FLAG, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::UPDATE_LISTEN_EVENT_FLAG, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::SetCallingWindow( @@ -1044,6 +1064,7 @@ ErrCode InputMethodSystemAbility::SetCallingWindow( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, windowId, client, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1052,7 +1073,7 @@ ErrCode InputMethodSystemAbility::SetCallingWindow( return sharedThis->SetCallingWindowTask(callerInfo, windowId, client); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::SET_CALLING_WINDOW, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::SET_CALLING_WINDOW, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::GetInputStartInfo(uint32_t requestId) @@ -1060,6 +1081,7 @@ ErrCode InputMethodSystemAbility::GetInputStartInfo(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1077,7 +1099,7 @@ ErrCode InputMethodSystemAbility::GetInputStartInfo(uint32_t requestId) return ret; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_INPUT_START_INFO, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::GET_INPUT_START_INFO, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::IsCurrentIme(uint32_t requestId) @@ -1085,6 +1107,7 @@ ErrCode InputMethodSystemAbility::IsCurrentIme(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1095,13 +1118,15 @@ ErrCode InputMethodSystemAbility::IsCurrentIme(uint32_t requestId) return ErrorCode::NO_ERROR; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_CURRENT_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_CURRENT_IME, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::IsInputTypeSupported(uint32_t requestId, int32_t type) { auto callerInfo = GetCallerInfo(requestId); + auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, type](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1109,8 +1134,8 @@ ErrCode InputMethodSystemAbility::IsInputTypeSupported(uint32_t requestId, int32 data = resultValue; return ErrorCode::NO_ERROR; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_INPUT_TYPE_SUPPORTED, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::IS_INPUT_TYPE_SUPPORTED, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::StartInputType(uint32_t requestId, int32_t type) @@ -1118,6 +1143,7 @@ ErrCode InputMethodSystemAbility::StartInputType(uint32_t requestId, int32_t typ auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, type](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1126,7 +1152,7 @@ ErrCode InputMethodSystemAbility::StartInputType(uint32_t requestId, int32_t typ return sharedThis->StartInputType(callerInfo, static_cast(type)); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::START_INPUT_TYPE, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::START_INPUT_TYPE, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::ExitCurrentInputType(uint32_t requestId) @@ -1134,6 +1160,7 @@ ErrCode InputMethodSystemAbility::ExitCurrentInputType(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1141,8 +1168,8 @@ ErrCode InputMethodSystemAbility::ExitCurrentInputType(uint32_t requestId) GET_SHARED_THIS(weakThis, sharedThis, ErrorCode::ERROR_IMSA_NULLPTR); return sharedThis->ExitCurrentInputTypeTask(callerInfo); }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::EXIT_CURRENT_INPUT_TYPE, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::EXIT_CURRENT_INPUT_TYPE, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::IsDefaultIme(uint32_t requestId) @@ -1150,6 +1177,7 @@ ErrCode InputMethodSystemAbility::IsDefaultIme(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1160,7 +1188,7 @@ ErrCode InputMethodSystemAbility::IsDefaultIme(uint32_t requestId) return ret; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_DEFAULT_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_DEFAULT_IME, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::IsSystemApp(uint32_t requestId) @@ -1168,6 +1196,7 @@ ErrCode InputMethodSystemAbility::IsSystemApp(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1178,7 +1207,26 @@ ErrCode InputMethodSystemAbility::IsSystemApp(uint32_t requestId) return ErrorCode::NO_ERROR; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_SYSTEM_APP, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_SYSTEM_APP, action, callerInfo, requester->imcResponseChannel)); +} + +ErrCode InputMethodSystemAbility::IsSystemImeApp(uint32_t requestId) +{ + auto callerInfo = GetCallerInfo(requestId); + auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); + CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + + std::weak_ptr weakThis = shared_from_this(); + SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { + std::shared_ptr sharedThis = nullptr; + GET_SHARED_THIS(weakThis, sharedThis, ErrorCode::ERROR_IMSA_NULLPTR); + bool resultValue = sharedThis->identityChecker_->IsSystemApp(IPCSkeleton::GetCallingFullTokenID()); + data = resultValue; + return ErrorCode::NO_ERROR; + }; + return SaTaskManager::GetInstance().PostTask( + std::make_shared(SaTaskCode::IS_SYSTEM_APP, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::IsCapacitySupport(uint32_t requestId, int32_t capacity) @@ -1186,6 +1234,7 @@ ErrCode InputMethodSystemAbility::IsCapacitySupport(uint32_t requestId, int32_t auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo, capacity](ServiceResponseData &data, ActionInnerData &) -> int32_t { IMSA_HILOGI("capacity:%{public}d", capacity); @@ -1202,7 +1251,7 @@ ErrCode InputMethodSystemAbility::IsCapacitySupport(uint32_t requestId, int32_t return ErrorCode::NO_ERROR; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_DEFAULT_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_DEFAULT_IME, action, callerInfo, requester->imaResponseChannel)); } int32_t InputMethodSystemAbility::IsDefaultImeFromTokenId(int32_t userId, uint32_t tokenId) @@ -1224,6 +1273,7 @@ ErrCode InputMethodSystemAbility::IsCurrentImeByPid(uint32_t requestId, int32_t auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, pid](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1234,8 +1284,8 @@ ErrCode InputMethodSystemAbility::IsCurrentImeByPid(uint32_t requestId, int32_t data = resultValue; return ret; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_CURRENT_IME_BY_PID, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared + (SaTaskCode::IS_CURRENT_IME_BY_PID, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::IsPanelShown(uint32_t requestId, const PanelInfo &panelInfo) @@ -1243,6 +1293,7 @@ int32_t InputMethodSystemAbility::IsPanelShown(uint32_t requestId, const PanelIn auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, panelInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -1260,7 +1311,7 @@ int32_t InputMethodSystemAbility::IsPanelShown(uint32_t requestId, const PanelIn return ret; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_PANEL_SHOWN, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_PANEL_SHOWN, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::DisplayOptionalInputMethod(uint32_t requestId) @@ -1268,6 +1319,7 @@ int32_t InputMethodSystemAbility::DisplayOptionalInputMethod(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1277,7 +1329,7 @@ int32_t InputMethodSystemAbility::DisplayOptionalInputMethod(uint32_t requestId) return sharedThis->OnDisplayOptionalInputMethod(); }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::DISPLAY_OPTIONAL_INPUT_METHOD, action, callerInfo, requester->responseChannel)); + SaTaskCode::DISPLAY_OPTIONAL_INPUT_METHOD, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::SwitchInputMethod( @@ -1286,6 +1338,7 @@ ErrCode InputMethodSystemAbility::SwitchInputMethod( CallerInfo callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, bundleName, subName, trigger, weakThis]( @@ -1295,7 +1348,7 @@ ErrCode InputMethodSystemAbility::SwitchInputMethod( return sharedThis->SwitchInputMethodTask(callerInfo, bundleName, subName, trigger); }; auto task = - std::make_shared(SaTaskCode::SWITCH_INPUT_METHOD, action, callerInfo, requester->responseChannel); + std::make_shared(SaTaskCode::SWITCH_INPUT_METHOD, action, callerInfo, requester->imcResponseChannel); return SaTaskManager::GetInstance().PostTask(task); } @@ -1339,6 +1392,7 @@ ErrCode InputMethodSystemAbility::EnableIme( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, bundleName, extensionName, status, weakThis]( @@ -1353,7 +1407,7 @@ ErrCode InputMethodSystemAbility::EnableIme( return sharedThis->EnableIme(callerInfo.userId, bundleName, extensionName, static_cast(status)); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::ENABLE_IME, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::ENABLE_IME, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::EnableIme( @@ -1535,6 +1589,7 @@ int32_t InputMethodSystemAbility::HideCurrentInputDeprecated(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1548,7 +1603,7 @@ int32_t InputMethodSystemAbility::HideCurrentInputDeprecated(uint32_t requestId) return session->OnHideCurrentInput(sharedThis->GetCallingDisplayId(callerInfo.pid)); }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::HIDE_CURRENT_INPUT_DEPRECATED, action, callerInfo, requester->responseChannel)); + SaTaskCode::HIDE_CURRENT_INPUT_DEPRECATED, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::ShowCurrentInputDeprecated(uint32_t requestId) @@ -1556,6 +1611,7 @@ int32_t InputMethodSystemAbility::ShowCurrentInputDeprecated(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -1569,7 +1625,7 @@ int32_t InputMethodSystemAbility::ShowCurrentInputDeprecated(uint32_t requestId) return session->OnShowCurrentInput(sharedThis->GetCallingDisplayId(callerInfo.pid)); }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::SHOW_CURRENT_INPUT_DEPRECATED, action, callerInfo, requester->responseChannel)); + SaTaskCode::SHOW_CURRENT_INPUT_DEPRECATED, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::GetCurrentInputMethod(uint32_t requestId) @@ -1577,6 +1633,7 @@ ErrCode InputMethodSystemAbility::GetCurrentInputMethod(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { auto prop = ImeInfoInquirer::GetInstance().GetCurrentInputMethod(callerInfo.userId); @@ -1587,8 +1644,8 @@ ErrCode InputMethodSystemAbility::GetCurrentInputMethod(uint32_t requestId) data = *prop; return ERR_OK; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_CURRENT_INPUT_METHOD, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::GET_CURRENT_INPUT_METHOD, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::IsDefaultImeSet(uint32_t requestId) @@ -1596,6 +1653,7 @@ ErrCode InputMethodSystemAbility::IsDefaultImeSet(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { bool resultValue = ImeInfoInquirer::GetInstance().IsDefaultImeSet(callerInfo.userId); @@ -1603,7 +1661,7 @@ ErrCode InputMethodSystemAbility::IsDefaultImeSet(uint32_t requestId) return ERR_OK; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::IS_DEFAULT_IME_SET, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::IS_DEFAULT_IME_SET, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::GetCurrentInputMethodSubtype(uint32_t requestId) @@ -1611,6 +1669,7 @@ ErrCode InputMethodSystemAbility::GetCurrentInputMethodSubtype(uint32_t requestI auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { auto prop = ImeInfoInquirer::GetInstance().GetCurrentSubtype(callerInfo.userId); @@ -1622,7 +1681,7 @@ ErrCode InputMethodSystemAbility::GetCurrentInputMethodSubtype(uint32_t requestI return ERR_OK; }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::GET_CURRENT_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->responseChannel)); + SaTaskCode::GET_CURRENT_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::GetDefaultInputMethod(uint32_t requestId, bool isBrief) @@ -1630,6 +1689,7 @@ ErrCode InputMethodSystemAbility::GetDefaultInputMethod(uint32_t requestId, bool auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo, isBrief](ServiceResponseData &data, ActionInnerData &) -> int32_t { std::shared_ptr property = std::make_shared(); @@ -1639,8 +1699,8 @@ ErrCode InputMethodSystemAbility::GetDefaultInputMethod(uint32_t requestId, bool } return ret; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_DEFAULT_INPUT_METHOD, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::GET_DEFAULT_INPUT_METHOD, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::GetInputMethodConfig(uint32_t requestId) @@ -1648,6 +1708,7 @@ ErrCode InputMethodSystemAbility::GetInputMethodConfig(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo](ServiceResponseData &data, ActionInnerData &) -> int32_t { AppExecFwk::ElementName inputMethodConfig; @@ -1657,8 +1718,8 @@ ErrCode InputMethodSystemAbility::GetInputMethodConfig(uint32_t requestId) } return ret; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_INPUT_METHOD_CONFIG, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::GET_INPUT_METHOD_CONFIG, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::ListInputMethod(uint32_t requestId, uint32_t status) @@ -1666,6 +1727,7 @@ ErrCode InputMethodSystemAbility::ListInputMethod(uint32_t requestId, uint32_t s auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo, status](ServiceResponseData &, ActionInnerData &) -> int32_t { std::vector props; @@ -1673,7 +1735,7 @@ ErrCode InputMethodSystemAbility::ListInputMethod(uint32_t requestId, uint32_t s callerInfo.userId, static_cast(status), props); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::LIST_INPUT_METHOD, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::LIST_INPUT_METHOD, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::ListCurrentInputMethodSubtype(uint32_t requestId) @@ -1681,13 +1743,14 @@ ErrCode InputMethodSystemAbility::ListCurrentInputMethodSubtype(uint32_t request auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo](ServiceResponseData &, ActionInnerData &) -> int32_t { std::vector subProps; return ImeInfoInquirer::GetInstance().ListCurrentInputMethodSubtype(callerInfo.userId, subProps); }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::LIST_CURRENT_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->responseChannel)); + SaTaskCode::LIST_CURRENT_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::ListInputMethodSubtype(uint32_t requestId, const std::string &bundleName) @@ -1695,13 +1758,14 @@ int32_t InputMethodSystemAbility::ListInputMethodSubtype(uint32_t requestId, con auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); SaActionFunc action = [callerInfo, bundleName](ServiceResponseData &, ActionInnerData &) -> int32_t { std::vector subProps; return ImeInfoInquirer::GetInstance().ListInputMethodSubtype(callerInfo.userId, bundleName, subProps); }; return SaTaskManager::GetInstance().PostTask(std::make_shared( - SaTaskCode::LIST_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->responseChannel)); + SaTaskCode::LIST_INPUT_METHOD_SUBTYPE, action, callerInfo, requester->imcResponseChannel)); } int32_t InputMethodSystemAbility::OnUserStarted(const EventFwk::CommonEventData &data) @@ -1952,22 +2016,8 @@ int32_t InputMethodSystemAbility::SwitchType() void InputMethodSystemAbility::InitMonitors() { - master // subscribe sa status change listeners SubscribeSaListeners(); -======= - int32_t ret = InitAccountMonitor(); - IMSA_HILOGI("init account monitor, ret: %{public}d.", ret); - SubscribeCommonEvent(); - ret = InitMemMgrMonitor(); - IMSA_HILOGI("init MemMgr monitor, ret: %{public}d.", ret); - ret = InitKeyEventMonitor(); - IMSA_HILOGI("init KeyEvent monitor, ret: %{public}d.", ret); - ret = InitWmsMonitor(); - IMSA_HILOGI("init wms monitor, ret: %{public}d.", ret); - ret = InitPasteboardMonitor(); - IMSA_HILOGI("init Pasteboard monitor, ret: %{public}d.", ret); ->>>>>>> master InitSystemLanguageMonitor(); } @@ -1980,6 +2030,7 @@ void InputMethodSystemAbility::SubscribeSaListeners() ImCommonEventManager::GetInstance().RegisterSaHandler(MULTIMODAL_INPUT_SERVICE_ID, [this] { HandleMMIStarted(); }); ImCommonEventManager::GetInstance().RegisterSaHandler(WINDOW_MANAGER_SERVICE_ID, [this] { HandleWmsStarted(); }); ImCommonEventManager::GetInstance().RegisterSaHandler(COMMON_EVENT_SERVICE_ID, [this] { SubscribeCommonEvents(); }); + ImCommonEventManager::GetInstance().RegisterSaHandler(PASTEBOARD_SERVICE_ID, [this] { HandlePasteboardStarted(); }); // subscribe ImCommonEventManager::GetInstance().SubscribeSaStatus(); @@ -2067,19 +2118,6 @@ void InputMethodSystemAbility::HandlePasteboardStarted() data->imeStateManager->PasteBoardActiveIme(); } -bool InputMethodSystemAbility::InitPasteboardMonitor() -{ - auto commonEventMgr = ImCommonEventManager::GetInstance(); - if (commonEventMgr == nullptr) { - IMSA_HILOGE("commonEventMgr is nullptr."); - return false; - } - - return commonEventMgr->SubscribePasteboardService([this]() { - HandlePasteboardStarted(); - }); -} - void InputMethodSystemAbility::InitSystemLanguageMonitor() { SystemLanguageObserver::GetInstance().Watch(); @@ -2160,6 +2198,7 @@ int32_t InputMethodSystemAbility::GetSecurityMode(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -2171,7 +2210,7 @@ int32_t InputMethodSystemAbility::GetSecurityMode(uint32_t requestId) return ret; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_SECURITY_MODE, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::GET_SECURITY_MODE, action, callerInfo, requester->imaResponseChannel)); } ErrCode InputMethodSystemAbility::UnRegisteredProxyIme( @@ -2180,6 +2219,7 @@ ErrCode InputMethodSystemAbility::UnRegisteredProxyIme( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imaResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, type, core, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -2187,8 +2227,8 @@ ErrCode InputMethodSystemAbility::UnRegisteredProxyIme( GET_SHARED_THIS(weakThis, sharedThis, ErrorCode::ERROR_IMSA_NULLPTR); return sharedThis->UnRegisteredProxyImeTask(callerInfo, type, core); }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::UNREGISTERED_PROXY_IME, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::UNREGISTERED_PROXY_IME, action, callerInfo, requester->imaResponseChannel)); } int32_t InputMethodSystemAbility::CheckEnableAndSwitchPermission(const CallerInfo &callerInfo) @@ -2277,6 +2317,7 @@ int32_t InputMethodSystemAbility::ConnectSystemCmd(uint32_t requestId, const spt auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [weakThis, callerInfo, channel](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -2288,7 +2329,7 @@ int32_t InputMethodSystemAbility::ConnectSystemCmd(uint32_t requestId, const spt return ret; }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::CONNECT_SYSTEM_CMD, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::CONNECT_SYSTEM_CMD, action, callerInfo, requester->imcResponseChannel)); } void InputMethodSystemAbility::HandleWmsConnected(int32_t userId, int32_t screenId) @@ -2626,6 +2667,7 @@ ErrCode InputMethodSystemAbility::GetInputMethodState(uint32_t requestId) auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, weakThis](ServiceResponseData &data, ActionInnerData &) -> int32_t { @@ -2636,8 +2678,8 @@ ErrCode InputMethodSystemAbility::GetInputMethodState(uint32_t requestId) data = status; return ret; }; - return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::GET_INPUT_METHOD_STATE, action, callerInfo, requester->responseChannel)); + return SaTaskManager::GetInstance().PostTask(std::make_shared( + SaTaskCode::GET_INPUT_METHOD_STATE, action, callerInfo, requester->imcResponseChannel)); } ErrCode InputMethodSystemAbility::ShowCurrentInput(uint32_t requestId, uint32_t type) @@ -2645,6 +2687,7 @@ ErrCode InputMethodSystemAbility::ShowCurrentInput(uint32_t requestId, uint32_t auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); // 1 - generate ShowCurrentInput task std::weak_ptr weakThis = shared_from_this(); @@ -2660,7 +2703,7 @@ ErrCode InputMethodSystemAbility::ShowCurrentInput(uint32_t requestId, uint32_t sharedThis->ReportShowCurrentInput(callerInfo, type, ret); }; auto task = - std::make_shared(SaTaskCode::SHOW_CURRENT_INPUT, action, callerInfo, requester->responseChannel); + std::make_shared(SaTaskCode::SHOW_CURRENT_INPUT, action, callerInfo, requester->imcResponseChannel); task->SetHiSysReporter(reporter); return SaTaskManager::GetInstance().PostTask(task); } @@ -2671,6 +2714,7 @@ ErrCode InputMethodSystemAbility::ShowInput( auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); // 1 - generate ShowInput task std::weak_ptr weakThis = shared_from_this(); @@ -2686,7 +2730,7 @@ ErrCode InputMethodSystemAbility::ShowInput( GET_SHARED_THIS(weakThis, sharedThis, ErrorCode::ERROR_IMSA_NULLPTR); sharedThis->ReportShowInput(callerInfo, type, ret); }; - auto task = std::make_shared(SaTaskCode::SHOW_INPUT, action, callerInfo, requester->responseChannel); + auto task = std::make_shared(SaTaskCode::SHOW_INPUT, action, callerInfo, requester->imcResponseChannel); task->SetHiSysReporter(reporter); return SaTaskManager::GetInstance().PostTask(task); } @@ -2761,6 +2805,7 @@ int32_t InputMethodSystemAbility::SendPrivateData(uint32_t requestId, const Valu auto callerInfo = GetCallerInfo(requestId); auto requester = RequesterManager::GetInstance().GetRequester(callerInfo.pid); CHECK_NULLPTR_RETURN(requester, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); + CHECK_NULLPTR_RETURN(requester->imcResponseChannel, ErrorCode::ERROR_IMSA_REQUESTER_NOT_FOUND); std::weak_ptr weakThis = shared_from_this(); SaActionFunc action = [callerInfo, value, weakThis](ServiceResponseData &, ActionInnerData &) -> int32_t { @@ -2769,7 +2814,7 @@ int32_t InputMethodSystemAbility::SendPrivateData(uint32_t requestId, const Valu return sharedThis->SendPrivateDataTask(callerInfo, value); }; return SaTaskManager::GetInstance().PostTask( - std::make_shared(SaTaskCode::SEND_PRIVATE_DATA, action, callerInfo, requester->responseChannel)); + std::make_shared(SaTaskCode::SEND_PRIVATE_DATA, action, callerInfo, requester->imcResponseChannel)); } InputType InputMethodSystemAbility::GetSecurityInputType(const InputClientInfo &inputClientInfo) diff --git a/services/task_manager/include/requester_manager.h b/services/task_manager/include/requester_manager.h index c62dd6e4f..775a4ab5a 100644 --- a/services/task_manager/include/requester_manager.h +++ b/services/task_manager/include/requester_manager.h @@ -30,7 +30,8 @@ namespace OHOS { namespace MiscServices { struct RequesterInfo { uint32_t requestCount{ 0 }; - sptr responseChannel{ nullptr }; + sptr imaResponseChannel{ nullptr }; + sptr imcResponseChannel{ nullptr }; sptr deathRecipient{ nullptr }; }; @@ -49,15 +50,16 @@ public: static RequesterManager &GetInstance(); std::shared_ptr GetRequester(int32_t pid); - int32_t Add(int32_t pid, sptr channel); + int32_t AddImaChannel(int32_t pid, sptr channel); + int32_t AddImcChannel(int32_t pid, sptr channel); void TaskIn(int32_t pid); void TaskOut(int32_t pid); private: void OnClientDied(int32_t pid); - std::mutex clientsMutex_{}; - std::unordered_map> requestClients_; + std::mutex mutex_{}; + std::unordered_map> requesterMap_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/task_manager/include/tasks/sa_task.h b/services/task_manager/include/tasks/sa_task.h index 1eb421de4..7b0e02926 100644 --- a/services/task_manager/include/tasks/sa_task.h +++ b/services/task_manager/include/tasks/sa_task.h @@ -123,6 +123,7 @@ enum class SaTaskCode : uint32_t { IS_DEFAULT_IME, IS_DEFAULT_IME_SET, IS_SYSTEM_APP, + IS_SYSTEM_IME_APP, IS_DEFAULT_IME_SCREEN, ENABLE_IME, @@ -147,23 +148,33 @@ enum class SaTaskCode : uint32_t { class SaTask { public: - explicit SaTask(SaTaskCode code) : code_(code), seqId_(GetNextSeqId()), responseChannel_(nullptr) + explicit SaTask(SaTaskCode code) + : code_(code), seqId_(GetNextSeqId()), imaResponseChannel_(nullptr), imcResponseChannel_(nullptr) { } - explicit SaTask(SaTaskCode code, uint64_t seqId) : code_(code), seqId_(seqId), responseChannel_(nullptr) + explicit SaTask(SaTaskCode code, uint64_t seqId) + : code_(code), seqId_(seqId), imaResponseChannel_(nullptr), imcResponseChannel_(nullptr) { } - SaTask(SaTaskCode code, SaActionFunc func) : code_(code), seqId_(GetNextSeqId()), responseChannel_(nullptr) + SaTask(SaTaskCode code, SaActionFunc func) + : code_(code), seqId_(GetNextSeqId()), imaResponseChannel_(nullptr), imcResponseChannel_(nullptr) { action_ = std::make_unique(func); } SaTask(SaTaskCode code, std::unique_ptr action) - : code_(code), seqId_(GetNextSeqId()), responseChannel_(nullptr) + : code_(code), seqId_(GetNextSeqId()), imaResponseChannel_(nullptr), imcResponseChannel_(nullptr) { action_ = std::move(action); } - SaTask(SaTaskCode code, SaActionFunc func, CallerInfo info, sptr channel) - : code_(code), seqId_(GetNextSeqId()), callerInfo_(info), responseChannel_(channel) + SaTask(SaTaskCode code, SaActionFunc func, CallerInfo info, sptr channel) + : code_(code), seqId_(GetNextSeqId()), callerInfo_(info), imaResponseChannel_(channel), + imcResponseChannel_(nullptr) + { + action_ = std::make_unique(func); + } + SaTask(SaTaskCode code, SaActionFunc func, CallerInfo info, sptr channel) + : code_(code), seqId_(GetNextSeqId()), callerInfo_(info), imcResponseChannel_(channel), + imaResponseChannel_(nullptr) { action_ = std::make_unique(func); } @@ -212,7 +223,8 @@ protected: int32_t retCode_{ ErrorCode::NO_ERROR }; CallerInfo callerInfo_; - sptr responseChannel_{ nullptr }; + sptr imaResponseChannel_; + sptr imcResponseChannel_; ServiceResponseData responseData_{ std::monostate{} }; std::unique_ptr action_{ nullptr }; diff --git a/services/task_manager/src/requester_manager.cpp b/services/task_manager/src/requester_manager.cpp index f0cf2fe9d..2415b8b17 100644 --- a/services/task_manager/src/requester_manager.cpp +++ b/services/task_manager/src/requester_manager.cpp @@ -28,12 +28,16 @@ RequesterManager &RequesterManager::GetInstance() std::shared_ptr RequesterManager::GetRequester(int32_t pid) { - std::lock_guard lock(clientsMutex_); - auto iter = requestClients_.find(pid); - if (iter == requestClients_.end() || iter->second == nullptr || iter->second->responseChannel == nullptr) { + std::lock_guard lock(mutex_); + auto iter = requesterMap_.find(pid); + if (iter == requesterMap_.end() || iter->second == nullptr) { IMSA_HILOGE("client: %{public}d not registered or nullptr", pid); return nullptr; } + if (iter->second->imaResponseChannel == nullptr &&iter->second->imcResponseChannel = nullptr) { + IMSA_HILOGE("client: %{public}d channel is nullptr", pid); + return nullptr; + } auto requesterInfo = iter->second; if (requesterInfo->requestCount >= MAX_REQUEST_COUNT) { IMSA_HILOGE("requests from client: %{public}d, count: %{public}d, too much", pid, requesterInfo->requestCount); @@ -42,14 +46,59 @@ std::shared_ptr RequesterManager::GetRequester(int32_t pid) return requesterInfo; } -int32_t RequesterManager::Add(int32_t pid, sptr channel) +int32_t RequesterManager::AddImaChannel(int32_t pid, sptr channel) +{ + std::lock_guard lock(mutex_); + auto iter = requesterMap_.find(pid); + if (iter != requesterMap_.end() && iter->second != nullptr) { + if (iter->second->imaResponseChannel != nullptr) { + IMSA_HILOGE("client: %{public}d already registered", pid); + return ErrorCode::NO_ERROR; + } + if (iter->second->imcResponseChannel != nullptr) { + iter->second->imaResponseChannel = channel; + IMSA_HILOGI("register success, pid: %{public}d", pid); + return ErrorCode::NO_ERROR; + } + } + + auto info = std::make_shared(); + std::weak_ptr weakThis = shared_from_this(); + info->deathRecipient->SetDeathRecipient([pid, weakThis](const wptr &remote) { + auto sharedThis = weakThis.lock(); + if (sharedThis == nullptr) { + IMSA_HILOGE("sharedThis is nullptr"); + return; + } + sharedThis->OnClientDied(pid); + }); + auto object = channel->AsObject(); + if (object == nullptr || (object->IsProxyObject() && !object->AddDeathRecipient(info->deathRecipient))) { + IMSA_HILOGE("failed to add death recipient"); + return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; + } + + info->imaResponseChannel = channel; + requesterMap_.insert_or_assign(pid, info); + IMSA_HILOGI("register success, pid: %{public}d", pid); +} + +int32_t RequesterManager::AddImcChannel(int32_t pid, sptr channel) { - std::lock_guard lock(clientsMutex_); - auto iter = requestClients_.find(pid); - if (iter != requestClients_.end() && iter->second != nullptr && iter->second->responseChannel != nullptr) { - IMSA_HILOGE("client: %{public}d already registered", pid); - return ErrorCode::NO_ERROR; + std::lock_guard lock(mutex); + auto iter = requesterMap_.find(pid); + if (iter != requesterMap_.end() && iter->second != nullptr) { + if (iter->second->imcResponseChannel != nullptr) { + IMSA_HILOGE("client: %{public}d already registered", pid); + return ErrorCode::NO_ERROR; + } + if (iter->second->imaResponseChannel != nullptr) { + iter->second->imcResponseChannel = channel; + IMSA_HILOGI("register success, pid: %{public}d", pid); + return ErrorCode::NO_ERROR; + } } + auto info = std::make_shared(); std::weak_ptr weakThis = shared_from_this(); info->deathRecipient->SetDeathRecipient([pid, weakThis](const wptr &remote) { @@ -65,16 +114,17 @@ int32_t RequesterManager::Add(int32_t pid, sptr channel) IMSA_HILOGE("failed to add death recipient"); return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; } - info->responseChannel = channel; - requestClients_.insert_or_assign(pid, info); + + info->imcResponseChannel = channel; + requesterMap_.insert_or_assign(pid, info); IMSA_HILOGI("register success, pid: %{public}d", pid); } void RequesterManager::TaskIn(int32_t pid) { - std::lock_guard lock(clientsMutex_); - auto iter = requestClients_.find(pid); - if (iter == requestClients_.end()) { + std::lock_guard lock(mutex_); + auto iter = requesterMap_.find(pid); + if (iter == requesterMap_.end()) { IMSA_HILOGE("client: %{public}d not found"); return; } @@ -87,9 +137,9 @@ void RequesterManager::TaskIn(int32_t pid) void RequesterManager::TaskOut(int32_t pid) { - std::lock_guard lock(clientsMutex_); - auto iter = requestClients_.find(pid); - if (iter == requestClients_.end()) { + std::lock_guard lock(mutex_); + auto iter = requesterMap_.find(pid); + if (iter == requesterMap_.end()) { IMSA_HILOGE("client: %{public}d not found"); return; } @@ -102,18 +152,23 @@ void RequesterManager::TaskOut(int32_t pid) void RequesterManager::OnClientDied(int32_t pid) { - std::lock_guard lock(clientsMutex_); + std::lock_guard lock(mutex_); IMSA_HILOGI("requester: %{public}d died", pid); - auto iter = requestClients_.find(pid); - if (iter == requestClients_.end()) { + auto iter = requesterMap_.find(pid); + if (iter == requesterMap_.end()) { IMSA_HILOGD("already removed"); return; } auto info = iter->second; - if (info != nullptr && info->responseChannel != nullptr && info->responseChannel->AsObject() != nullptr) { - info->responseChannel->AsObject()->RemoveDeathRecipient(info->deathRecipient); + if (info != nullptr) { + if (info->imaResponseChannel != nullptr && info->imaResponseChannel->AsObject() != nullptr) { + info->imaResponseChannel->AsObject()->RemoveDeathRecipient(info->deathRecipient); + } + if (info->imcResponseChannel != nullptr && info->imcResponseChannel->AsObject() != nullptr) { + info->imcResponseChannel->AsObject()->RemoveDeathRecipient(info->deathRecipient); + } } - requestClients_.erase(pid); + requesterMap_.erase(pid); IMSA_HILOGI("requester: %{public}d removed", pid); } } // namespace MiscServices diff --git a/services/task_manager/src/tasks/sa_task.cpp b/services/task_manager/src/tasks/sa_task.cpp index 51b31f1ac..df7cef0cc 100644 --- a/services/task_manager/src/tasks/sa_task.cpp +++ b/services/task_manager/src/tasks/sa_task.cpp @@ -202,10 +202,15 @@ void SaTask::InvokeResponse() hiSysReporter_->Execute(retCode_, responseData_); } - if (responseChannel_ != nullptr) { + if (imaResponseChannel_ != nullptr) { ServiceResponseDataInner inner; inner.data = responseData_; - responseChannel_->OnResponse(callerInfo_.requestId, retCode_, inner); + imaResponseChannel_->OnResponse(callerInfo_.requestId, retCode_, inner); + } + if (imcResponseChannel_ != nullptr) { + ServiceResponseDataInner inner; + inner.data = responseData_; + imaResponseChannel_->OnResponse(callerInfo_.requestId, retCode_, inner); } action_ = nullptr; -- Gitee