From c648949626d3356d1e3c6ec2c1bba27e77b2636d Mon Sep 17 00:00:00 2001 From: xxxx Date: Tue, 17 May 2022 16:44:36 +0800 Subject: [PATCH] Description:support dynamic load SA Match-id-abde2643acbee9a6e866fe8f9c964364f6668bb6 --- bundle.json | 1 + common/include/constants_dinput.h | 2 + common/include/input_hub.cpp | 35 ++++++++++++--- .../ipc/include/distributed_input_client.h | 9 +++- .../ipc/src/distributed_input_client.cpp | 34 ++++++++++++++- sa_profile/4809.xml | 4 +- sa_profile/4810.xml | 4 +- sa_profile/BUILD.gn | 7 +++ sa_profile/dinput.cfg | 9 ++++ .../common/include/dinput_softbus_define.h | 6 +-- .../src/distributed_input_sink_manager.cpp | 5 ++- .../src/distributed_input_sink_transport.cpp | 8 ++-- .../src/distributed_input_source_manager.cpp | 2 + .../distributed_input_source_transport.cpp | 6 +-- sinkhandler/BUILD.gn | 3 +- .../include/distributed_input_sink_handler.h | 5 +++ .../include/load_d_input_sink_callback.h | 36 ++++++++++++++++ .../src/distributed_input_sink_handler.cpp | 36 +++++++++++++++- .../src/load_d_input_sink_callback.cpp | 43 +++++++++++++++++++ sourcehandler/BUILD.gn | 3 +- .../distributed_input_source_handler.h | 5 +++ .../include/load_d_input_source_callback.h | 35 +++++++++++++++ .../src/distributed_input_source_handler.cpp | 38 +++++++++++++++- .../src/load_d_input_source_callback.cpp | 43 +++++++++++++++++++ 24 files changed, 354 insertions(+), 25 deletions(-) create mode 100644 sa_profile/dinput.cfg create mode 100644 sinkhandler/include/load_d_input_sink_callback.h create mode 100644 sinkhandler/src/load_d_input_sink_callback.cpp create mode 100644 sourcehandler/include/load_d_input_source_callback.h create mode 100644 sourcehandler/src/load_d_input_source_callback.cpp diff --git a/bundle.json b/bundle.json index 7d51b32..1f849bb 100644 --- a/bundle.json +++ b/bundle.json @@ -46,6 +46,7 @@ "//foundation/distributedhardware/distributedinput/interfaces/inner_kits:libdinput_sdk", "//foundation/distributedhardware/distributedinput/sa_profile:distributed_input_source_sa_profile", "//foundation/distributedhardware/distributedinput/sa_profile:distributed_input_sink_sa_profile", + "//foundation/distributedhardware/distributedinput/sa_profile:dinput.cfg", "//foundation/distributedhardware/distributedinput/services/source/sourcemanager:libdinput_source", "//foundation/distributedhardware/distributedinput/services/source/transport:libdinput_source_trans", "//foundation/distributedhardware/distributedinput/services/source/inputinject:libdinput_inject", diff --git a/common/include/constants_dinput.h b/common/include/constants_dinput.h index 9a639bd..29f52d2 100644 --- a/common/include/constants_dinput.h +++ b/common/include/constants_dinput.h @@ -87,6 +87,8 @@ namespace DistributedInput { */ const int32_t INPUT_TYPE_ALL = INPUT_TYPE_MOUSE | INPUT_TYPE_KEYBOARD | INPUT_TYPE_TOUCH; + constexpr int32_t INPUT_LOADSA_TIMEOUT_MS = 10000; + enum class EHandlerMsgType { DINPUT_SINK_EVENT_HANDLER_MSG = 1, DINPUT_SOURCE_EVENT_HANDLER_MSG = 2 diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index 1796cb3..6dbcd19 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -14,6 +14,7 @@ */ #include "input_hub.h" +#include #include #include #include @@ -87,7 +88,7 @@ int32_t InputHub::Release() size_t InputHub::CollectInputEvents(RawEvent* buffer, size_t bufferSize) { size_t count; - for ( ; ; ) { + for (; ;) { if (needToScanDevices_) { needToScanDevices_ = false; ScanInputDevices(DEVICE_PATH); @@ -233,7 +234,7 @@ size_t InputHub::CollectInputHandler(InputDeviceEvent* buffer, size_t bufferSize { InputDeviceEvent* event = buffer; size_t capacity = bufferSize; - for ( ; ; ) { + for (; ;) { // Report any devices that had last been added/removed. for (auto it = closingDevices_.begin(); it != closingDevices_.end();) { std::unique_ptr device = std::move(*it); @@ -347,10 +348,34 @@ std::vector InputHub::GetAllInputDevices() void InputHub::ScanInputDevices(const std::string& dirname) { - for (const auto& entry : std::filesystem::directory_iterator(dirname)) { - OpenInputDeviceLocked(entry.path()); + char devname[PATH_MAX]; + char *filename; + DIR *dir; + struct dirent *de; + dir = opendir(dirname.c_str()); + if (dir == nullptr) { + DHLOGE("error opendir dev/input :%{public}s\n", strerror(errno)); + return; } - return; + + if (strcpy_s(devname, PATH_MAX, dirname.c_str()) != 0) { + DHLOGE("error strcpy_s :%{public}s\n", strerror(errno)); + } + filename = devname + strlen(devname); + *filename++ = '/'; + while ((de = readdir(dir))) { + if (de->d_name[0] == '.' && + (de->d_name[1] == '\0' || + (de->d_name[1] == '.' && de->d_name[DIR_FILE_NAME_SECOND] == '\0'))) { + continue; + } + if (strcpy_s(filename, sizeof(de->d_name), de->d_name) != 0) { + DHLOGE("error strcpy_s second :%{public}s\n", strerror(errno)); + } + DHLOGE("scan dir failed for %{public}s", filename); + OpenInputDeviceLocked(devname); + } + closedir(dir); } int32_t InputHub::OpenInputDeviceLocked(const std::string& devicePath) diff --git a/interfaces/ipc/include/distributed_input_client.h b/interfaces/ipc/include/distributed_input_client.h index e2c0aaf..e675776 100644 --- a/interfaces/ipc/include/distributed_input_client.h +++ b/interfaces/ipc/include/distributed_input_client.h @@ -66,8 +66,15 @@ public: DInputServerType IsStartDistributedInput(const uint32_t& inputType); -public: + bool HasDInputSourceProxy(); + bool SetDInputSourceProxy(const sptr &remoteObject); + + bool HasDInputSinkProxy(); + + bool SetDInputSinkProxy(const sptr &remoteObject); + +public: class RegisterDInputCb : public OHOS::DistributedHardware::DistributedInput::RegisterDInputCallbackStub { public: RegisterDInputCb() = default; diff --git a/interfaces/ipc/src/distributed_input_client.cpp b/interfaces/ipc/src/distributed_input_client.cpp index 1f3be75..3baa674 100644 --- a/interfaces/ipc/src/distributed_input_client.cpp +++ b/interfaces/ipc/src/distributed_input_client.cpp @@ -340,7 +340,7 @@ bool DistributedInputClient::GetDInputSourceProxy() if (!systemAbilityManager) { return false; } - + DHLOGI("%s try get sa: %d", __func__, DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID); sptr remoteObject = systemAbilityManager->GetSystemAbility( DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID); if (!remoteObject) { @@ -356,6 +356,38 @@ bool DistributedInputClient::GetDInputSourceProxy() return true; } +bool DistributedInputClient::HasDInputSourceProxy() +{ + return dInputSourceProxy_ != nullptr; +} + +bool DistributedInputClient::SetDInputSourceProxy(const sptr &remoteObject) +{ + dInputSourceProxy_ = iface_cast(remoteObject); + + if ((!dInputSourceProxy_) || (!dInputSourceProxy_->AsObject())) { + DHLOGE("Failed to get dinput source proxy."); + return false; + } + return true; +} + +bool DistributedInputClient::HasDInputSinkProxy() +{ + return dInputSinkProxy_ != nullptr; +} + +bool DistributedInputClient::SetDInputSinkProxy(const sptr &remoteObject) +{ + dInputSinkProxy_ = iface_cast(remoteObject); + + if ((!dInputSinkProxy_) || (!dInputSinkProxy_->AsObject())) { + DHLOGE("Failed to get dinput sink proxy."); + return false; + } + return true; +} + bool DistributedInputClient::GetDInputSinkProxy() { if (!dInputSinkProxy_) { diff --git a/sa_profile/4809.xml b/sa_profile/4809.xml index 228a233..970cf96 100644 --- a/sa_profile/4809.xml +++ b/sa_profile/4809.xml @@ -14,13 +14,13 @@ * limitations under the License. --> - dhardware + dinput 4809 libdinput_source.z.so - true + false true 1 diff --git a/sa_profile/4810.xml b/sa_profile/4810.xml index 7c62437..1427dce 100644 --- a/sa_profile/4810.xml +++ b/sa_profile/4810.xml @@ -14,13 +14,13 @@ * limitations under the License. --> - dhardware + dinput 4810 libdinput_sink.z.so - true + false true 1 diff --git a/sa_profile/BUILD.gn b/sa_profile/BUILD.gn index 1e6afb7..ca0206e 100644 --- a/sa_profile/BUILD.gn +++ b/sa_profile/BUILD.gn @@ -29,4 +29,11 @@ ohos_sa_profile("distributed_input_sink_sa_profile") { ] part_name = "distributed_input" +} + +ohos_prebuilt_etc("dinput.cfg") { + relative_install_dir = "init" + source = "dinput.cfg" + part_name = "distributed_input" + subsystem_name = "distributedhardware" } \ No newline at end of file diff --git a/sa_profile/dinput.cfg b/sa_profile/dinput.cfg new file mode 100644 index 0000000..50cff05 --- /dev/null +++ b/sa_profile/dinput.cfg @@ -0,0 +1,9 @@ +{ + "services" : [{ + "name" : "dinput", + "path" : ["/system/bin/sa_main", "/system/profile/dinput.xml"], + "uid" : "root", + "gid" : ["system", "uhid", "root"], + "ondemand" : true + }] +} \ No newline at end of file diff --git a/services/common/include/dinput_softbus_define.h b/services/common/include/dinput_softbus_define.h index 55a5def..7931cd0 100644 --- a/services/common/include/dinput_softbus_define.h +++ b/services/common/include/dinput_softbus_define.h @@ -41,9 +41,9 @@ namespace DistributedInput { const uint32_t DEVICE_ID_SIZE_MAX = 65; const uint32_t INTERCEPT_STRING_LENGTH = 20; - const std::string DINPUT_PKG_NAME = "DBinderBus_" + std::to_string(getpid()); - const std::string SESSION_NAME_SOURCE = "DBinderInput_so_"; - const std::string SESSION_NAME_SINK = "DBinderInput_si_"; + const std::string DINPUT_PKG_NAME = "ohos.dhardware.dinput"; + const std::string SESSION_NAME_SOURCE = "ohos.dhardware.dinput.so_"; + const std::string SESSION_NAME_SINK = "ohos.dhardware.dinput.si_"; const std::string GROUP_ID = "input_softbus_group_id"; #define DINPUT_SOFTBUS_KEY_CMD_TYPE "dinput_softbus_key_cmd_type" diff --git a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp index 5423f4a..00313be 100644 --- a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp +++ b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp @@ -157,7 +157,7 @@ void DistributedInputSinkManager::DInputSinkListener::onStartRemoteInput( // add the input type if (startRes == SUCCESS) { sinkManagerObj_->SetInputTypes(sinkManagerObj_->GetInputTypes() | inputTypes); - DistributedInputCollector::GetInstance().SetInputTypes(sinkManagerObj_->GetInputTypes()); + DistributedInputCollector::GetInstance().SetInputTypes(sinkManagerObj_->GetInputTypes()); } IStartDInputServerCallback *startServerCB = sinkManagerObj_->GetStartDInputServerCback(); @@ -297,6 +297,9 @@ int32_t DistributedInputSinkManager::Release() } serviceRunningState_ = ServiceSinkRunningState::STATE_NOT_START; + DHLOGI("exit dinput sink sa."); + exit(0); + return SUCCESS; } diff --git a/services/sink/transport/src/distributed_input_sink_transport.cpp b/services/sink/transport/src/distributed_input_sink_transport.cpp index c51c599..f72051f 100644 --- a/services/sink/transport/src/distributed_input_sink_transport.cpp +++ b/services/sink/transport/src/distributed_input_sink_transport.cpp @@ -73,7 +73,7 @@ DistributedInputSinkTransport::~DistributedInputSinkTransport() { DHLOGI("~DistributedInputSinkTransport"); sessionDevMap_.clear(); - (void)RemoveSessionServer(DH_FWK_PKG_NAME.c_str(), mySessionName_.c_str()); + (void)RemoveSessionServer(DINPUT_PKG_NAME.c_str(), mySessionName_.c_str()); } DistributedInputSinkTransport::DInputSinkEventHandler::DInputSinkEventHandler( @@ -123,7 +123,8 @@ int32_t DistributedInputSinkTransport::Init() DHLOGE("Init unique_ptr localNode nullptr."); return FAILURE; } - int32_t retCode = GetLocalNodeDeviceInfo(DH_FWK_PKG_NAME.c_str(), localNode.get()); + int32_t retCode = GetLocalNodeDeviceInfo(DINPUT_PKG_NAME.c_str(), localNode.get()); + if (retCode != SUCCESS) { DHLOGE("Init could not get local device id."); return FAILURE; @@ -132,7 +133,8 @@ int32_t DistributedInputSinkTransport::Init() DHLOGI("Init device networkId is %s", networkId.c_str()); mySessionName_ = SESSION_NAME_SINK + networkId.substr(0, INTERCEPT_STRING_LENGTH); - int32_t ret = CreateSessionServer(DH_FWK_PKG_NAME.c_str(), mySessionName_.c_str(), &iSessionListener); + + int32_t ret = CreateSessionServer(DINPUT_PKG_NAME.c_str(), mySessionName_.c_str(), &iSessionListener); if (ret != SUCCESS) { DHLOGE("Init CreateSessionServer failed, error code %d.", ret); return FAILURE; diff --git a/services/source/sourcemanager/src/distributed_input_source_manager.cpp b/services/source/sourcemanager/src/distributed_input_source_manager.cpp index b9f3dab..54bf213 100644 --- a/services/source/sourcemanager/src/distributed_input_source_manager.cpp +++ b/services/source/sourcemanager/src/distributed_input_source_manager.cpp @@ -532,6 +532,8 @@ int32_t DistributedInputSourceManager::Release() callBackHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); serviceRunningState_ = ServiceSourceRunningState::STATE_NOT_START; + DHLOGI("exit dinput source sa."); + exit(0); return SUCCESS; } diff --git a/services/source/transport/src/distributed_input_source_transport.cpp b/services/source/transport/src/distributed_input_source_transport.cpp index bdb0fbd..5f1892a 100644 --- a/services/source/transport/src/distributed_input_source_transport.cpp +++ b/services/source/transport/src/distributed_input_source_transport.cpp @@ -91,7 +91,7 @@ int32_t DistributedInputSourceTransport::Init() }; auto localNode = std::make_unique(); - int32_t retCode = GetLocalNodeDeviceInfo(DH_FWK_PKG_NAME.c_str(), localNode.get()); + int32_t retCode = GetLocalNodeDeviceInfo(DINPUT_PKG_NAME.c_str(), localNode.get()); if (retCode != SUCCESS) { DHLOGE("Init Could not get local device id."); return FAILURE; @@ -100,7 +100,7 @@ int32_t DistributedInputSourceTransport::Init() DHLOGI("Init device local networkId is %s", networkId.c_str()); mySessionName_ = SESSION_NAME_SOURCE + networkId.substr(0, INTERCEPT_STRING_LENGTH); - int32_t ret = CreateSessionServer(DH_FWK_PKG_NAME.c_str(), mySessionName_.c_str(), &iSessionListener); + int32_t ret = CreateSessionServer(DINPUT_PKG_NAME.c_str(), mySessionName_.c_str(), &iSessionListener); if (ret != SUCCESS) { DHLOGE("Init CreateSessionServer failed, error code %d.", ret); return FAILURE; @@ -117,7 +117,7 @@ DistributedInputSourceTransport::~DistributedInputSourceTransport() sessionDevMap_.clear(); devHardwareMap_.clear(); - (void)RemoveSessionServer(DH_FWK_PKG_NAME.c_str(), mySessionName_.c_str()); + (void)RemoveSessionServer(DINPUT_PKG_NAME.c_str(), mySessionName_.c_str()); } int32_t DistributedInputSourceTransport::CheckDeviceSessionState(const std::string &devId, const std::string &hwId) diff --git a/sinkhandler/BUILD.gn b/sinkhandler/BUILD.gn index a76d4aa..4daf24f 100644 --- a/sinkhandler/BUILD.gn +++ b/sinkhandler/BUILD.gn @@ -34,7 +34,8 @@ ohos_shared_library("libdinput_sink_handler") { ] sources = [ - "src/distributed_input_sink_handler.cpp" + "src/distributed_input_sink_handler.cpp", + "src/load_d_input_sink_callback.cpp" ] defines = [ diff --git a/sinkhandler/include/distributed_input_sink_handler.h b/sinkhandler/include/distributed_input_sink_handler.h index 671244f..3aa4f04 100644 --- a/sinkhandler/include/distributed_input_sink_handler.h +++ b/sinkhandler/include/distributed_input_sink_handler.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ public: int32_t ReleaseSink() override; int32_t SubscribeLocalHardware(const std::string& dhId, const std::string& parameters) override; int32_t UnsubscribeLocalHardware(const std::string& dhId) override; + void FinishStartSA(const std::string ¶ms, const sptr &remoteObject); public: class SALoadSinkCb : public OHOS::SystemAbilityLoadCallbackStub { @@ -63,6 +65,9 @@ private: DistributedInputSinkHandler() = default; ~DistributedInputSinkHandler(); OHOS::sptr sysSinkCallback = nullptr; + + std::mutex proxyMutex_; + std::condition_variable proxyConVar_; }; #ifdef __cplusplus diff --git a/sinkhandler/include/load_d_input_sink_callback.h b/sinkhandler/include/load_d_input_sink_callback.h new file mode 100644 index 0000000..580447a --- /dev/null +++ b/sinkhandler/include/load_d_input_sink_callback.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOAD_D_INPUT_SOURCE_CALLBACK_H +#define LOAD_D_INPUT_SOURCE_CALLBACK_H + +#include "system_ability_load_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +namespace DistributedInput { +class LoadDInputSinkCallback : public SystemAbilityLoadCallbackStub { +public: + explicit LoadDInputSinkCallback(const std::string ¶ms); + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, + const sptr &remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; +private: + std::string params_; +}; +} +} +} +#endif \ No newline at end of file diff --git a/sinkhandler/src/distributed_input_sink_handler.cpp b/sinkhandler/src/distributed_input_sink_handler.cpp index fb549fe..6253c1d 100644 --- a/sinkhandler/src/distributed_input_sink_handler.cpp +++ b/sinkhandler/src/distributed_input_sink_handler.cpp @@ -15,6 +15,7 @@ #include "distributed_input_sink_handler.h" #include "i_distributed_sink_input.h" +#include "load_d_input_sink_callback.h" #include "distributed_hardware_log.h" namespace OHOS { @@ -29,7 +30,40 @@ DistributedInputSinkHandler::~DistributedInputSinkHandler() int32_t DistributedInputSinkHandler::InitSink(const std::string ¶ms) { - return DistributedInputClient::GetInstance().InitSink(); + DHLOGD("InitSource"); + std::unique_lock lock(proxyMutex_); + if (!DistributedInputClient::GetInstance().HasDInputSinkProxy()) { + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!samgr) { + DHLOGE("Failed to get system ability mgr."); + return FAILURE_DIS; + } + sptr loadCallback = new LoadDInputSinkCallback(params); + int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID, loadCallback); + if (ret != ERR_OK) { + DHLOGE("Failed to Load systemAbility, systemAbilityId:%d, ret code:%d", + DISTRIBUTED_HARDWARE_INPUT_SINK_SA_ID, ret); + return FAILURE_DIS; + } + } + + auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(INPUT_LOADSA_TIMEOUT_MS), + [this]() { return (DistributedInputClient::GetInstance().HasDInputSinkProxy()); }); + if (!waitStatus) { + DHLOGE("dinput load sa timeout."); + return FAILURE_DIS; + } + + return SUCCESS; +} + +void DistributedInputSinkHandler::FinishStartSA(const std::string ¶ms, const sptr &remoteObject) +{ + DHLOGD("FinishStartSA"); + std::unique_lock lock(proxyMutex_); + DistributedInputClient::GetInstance().SetDInputSinkProxy(remoteObject); + DistributedInputClient::GetInstance().InitSink(); + proxyConVar_.notify_all(); } int32_t DistributedInputSinkHandler::ReleaseSink() diff --git a/sinkhandler/src/load_d_input_sink_callback.cpp b/sinkhandler/src/load_d_input_sink_callback.cpp new file mode 100644 index 0000000..d1765f0 --- /dev/null +++ b/sinkhandler/src/load_d_input_sink_callback.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "load_d_input_sink_callback.h" + +#include "distributed_hardware_log.h" +#include "distributed_input_sink_handler.h" + +namespace OHOS { +namespace DistributedHardware { +namespace DistributedInput { + LoadDInputSinkCallback::LoadDInputSinkCallback(const std::string ¶ms) : params_(params) {} + +void LoadDInputSinkCallback::OnLoadSystemAbilitySuccess( + int32_t systemAbilityId, const sptr &remoteObject) +{ + DHLOGI("load dinput SA success, systemAbilityId:%d, remoteObject result:%s", + systemAbilityId, (remoteObject != nullptr) ? "true" : "false"); + if (remoteObject == nullptr) { + DHLOGE("remoteObject is nullptr"); + return; + } + DistributedInputSinkHandler::GetInstance().FinishStartSA(params_, remoteObject); +} + +void LoadDInputSinkCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + DHLOGE("load dinput SA failed, systemAbilityId:%d", systemAbilityId); +} +} +} +} diff --git a/sourcehandler/BUILD.gn b/sourcehandler/BUILD.gn index 197b532..b3418b2 100644 --- a/sourcehandler/BUILD.gn +++ b/sourcehandler/BUILD.gn @@ -34,7 +34,8 @@ ohos_shared_library("libdinput_source_handler") { ] sources = [ - "src/distributed_input_source_handler.cpp" + "src/distributed_input_source_handler.cpp", + "src/load_d_input_source_callback.cpp" ] defines = [ diff --git a/sourcehandler/include/distributed_input_source_handler.h b/sourcehandler/include/distributed_input_source_handler.h index 83affa7..3f6820b 100644 --- a/sourcehandler/include/distributed_input_source_handler.h +++ b/sourcehandler/include/distributed_input_source_handler.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -41,6 +42,7 @@ public: std::shared_ptr callback) override; int32_t ConfigDistributedHardware(const std::string& devId, const std::string& dhId, const std::string& key, const std::string& value) override; + void FinishStartSA(const std::string ¶ms, const sptr &remoteObject); public: @@ -68,6 +70,9 @@ private: DistributedInputSourceHandler() = default; ~DistributedInputSourceHandler(); OHOS::sptr sysSourceCallback = nullptr; + + std::mutex proxyMutex_; + std::condition_variable proxyConVar_; }; #ifdef __cplusplus diff --git a/sourcehandler/include/load_d_input_source_callback.h b/sourcehandler/include/load_d_input_source_callback.h new file mode 100644 index 0000000..b14f791 --- /dev/null +++ b/sourcehandler/include/load_d_input_source_callback.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOAD_D_INPUT_SOURCE_CALLBACK_H +#define LOAD_D_INPUT_SOURCE_CALLBACK_H + +#include "system_ability_load_callback_stub.h" + +namespace OHOS { +namespace DistributedHardware { +namespace DistributedInput { +class LoadDInputSourceCallback : public SystemAbilityLoadCallbackStub { +public: + explicit LoadDInputSourceCallback(const std::string ¶ms); + void OnLoadSystemAbilitySuccess(int32_t systemAbilityId, const sptr &remoteObject) override; + void OnLoadSystemAbilityFail(int32_t systemAbilityId) override; +private: + std::string params_; +}; +} +} +} +#endif \ No newline at end of file diff --git a/sourcehandler/src/distributed_input_source_handler.cpp b/sourcehandler/src/distributed_input_source_handler.cpp index 2280325..614cc73 100644 --- a/sourcehandler/src/distributed_input_source_handler.cpp +++ b/sourcehandler/src/distributed_input_source_handler.cpp @@ -14,7 +14,10 @@ */ #include "distributed_input_source_handler.h" + +#include "distributed_hardware_log.h" #include "i_distributed_source_input.h" +#include "load_d_input_source_callback.h" namespace OHOS { namespace DistributedHardware { @@ -27,7 +30,40 @@ DistributedInputSourceHandler::~DistributedInputSourceHandler() int32_t DistributedInputSourceHandler::InitSource(const std::string ¶ms) { - return DistributedInputClient::GetInstance().InitSource(); + DHLOGD("InitSource"); + std::unique_lock lock(proxyMutex_); + if (!DistributedInputClient::GetInstance().HasDInputSourceProxy()) { + sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!samgr) { + DHLOGE("Failed to get system ability mgr."); + return FAILURE_DIS; + } + sptr loadCallback = new LoadDInputSourceCallback(params); + int32_t ret = samgr->LoadSystemAbility(DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID, loadCallback); + if (ret != ERR_OK) { + DHLOGE("Failed to Load systemAbility, systemAbilityId:%d, ret code:%d", + DISTRIBUTED_HARDWARE_INPUT_SOURCE_SA_ID, ret); + return FAILURE_DIS; + } + } + + auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(INPUT_LOADSA_TIMEOUT_MS), + [this]() { return (DistributedInputClient::GetInstance().HasDInputSourceProxy()); }); + if (!waitStatus) { + DHLOGE("dinput load sa timeout."); + return FAILURE_DIS; + } + + return SUCCESS; +} + +void DistributedInputSourceHandler::FinishStartSA(const std::string ¶ms, const sptr &remoteObject) +{ + DHLOGD("FinishStartSA"); + std::unique_lock lock(proxyMutex_); + DistributedInputClient::GetInstance().SetDInputSourceProxy(remoteObject); + DistributedInputClient::GetInstance().InitSource(); + proxyConVar_.notify_all(); } int32_t DistributedInputSourceHandler::ReleaseSource() diff --git a/sourcehandler/src/load_d_input_source_callback.cpp b/sourcehandler/src/load_d_input_source_callback.cpp new file mode 100644 index 0000000..a230a7e --- /dev/null +++ b/sourcehandler/src/load_d_input_source_callback.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "load_d_input_source_callback.h" + +#include "distributed_hardware_log.h" +#include "distributed_input_source_handler.h" + +namespace OHOS { +namespace DistributedHardware { +namespace DistributedInput { +LoadDInputSourceCallback::LoadDInputSourceCallback(const std::string ¶ms) : params_(params) {} + +void LoadDInputSourceCallback::OnLoadSystemAbilitySuccess( + int32_t systemAbilityId, const sptr &remoteObject) +{ + DHLOGI("load dinput SA success, systemAbilityId:%d, remoteObject result:%s", + systemAbilityId, (remoteObject != nullptr) ? "true" : "false"); + if (remoteObject == nullptr) { + DHLOGE("remoteObject is nullptr"); + return; + } + DistributedInputSourceHandler::GetInstance().FinishStartSA(params_, remoteObject); +} + +void LoadDInputSourceCallback::OnLoadSystemAbilityFail(int32_t systemAbilityId) +{ + DHLOGE("load dinput SA failed, systemAbilityId:%d", systemAbilityId); +} +} +} +}