diff --git a/frameworks/napi/input_device/include/js_util.h b/frameworks/napi/input_device/include/js_util.h index aea47e47725a9c987ebfe5e87ac618c681485209..9848771650bc254bd13a094eb817f844f228a0df 100644 --- a/frameworks/napi/input_device/include/js_util.h +++ b/frameworks/napi/input_device/include/js_util.h @@ -42,6 +42,10 @@ public: int32_t keyboardRepeatDelay { 0 }; int32_t keyboardRepeatRate { 0 }; }; + struct ReportData : RefBase { + napi_ref ref { nullptr }; + int32_t deviceId { 0 }; + }; struct CallbackInfo : RefBase { napi_env env { nullptr }; napi_ref ref { nullptr }; diff --git a/frameworks/napi/input_device/src/js_event_target.cpp b/frameworks/napi/input_device/src/js_event_target.cpp index 96c90e695bf188390e7cf001ff0b78e14bd93469..2258e49828129b027a7fb6086771fe95a38ff44c 100644 --- a/frameworks/napi/input_device/src/js_event_target.cpp +++ b/frameworks/napi/input_device/src/js_event_target.cpp @@ -53,7 +53,8 @@ void JsEventTarget::EmitAddedDeviceEvent(uv_work_t *work, int32_t status) MMI_HILOGE("Check data is nullptr"); return; } - auto temp = static_cast(work->data); + sptr reportData(static_cast(work->data)); + reportData->DecStrongRef(nullptr); JsUtil::DeletePtr(work); auto addEvent = devListener_.find(CHANGED_TYPE); if (addEvent == devListener_.end()) { @@ -62,7 +63,7 @@ void JsEventTarget::EmitAddedDeviceEvent(uv_work_t *work, int32_t status) } for (const auto &item : addEvent->second) { CHKPC(item->env); - if (item->ref != temp) { + if (item->ref != reportData->ref) { continue; } napi_handle_scope scope = nullptr; @@ -82,7 +83,7 @@ void JsEventTarget::EmitAddedDeviceEvent(uv_work_t *work, int32_t status) CHKRV_SCOPE_DEL(item->env, napi_get_reference_value(item->env, item->ref, &handler), GET_REFERENCE_VALUE, scope); napi_value deviceId = nullptr; - CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, item->data.deviceId, &deviceId), CREATE_INT32, scope); + CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope); CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "deviceId", deviceId), SET_NAMED_PROPERTY, scope); napi_value ret = nullptr; @@ -102,7 +103,8 @@ void JsEventTarget::EmitRemoveDeviceEvent(uv_work_t *work, int32_t status) MMI_HILOGE("Check data is nullptr"); return; } - auto temp = static_cast(work->data); + sptr reportData(static_cast(work->data)); + reportData->DecStrongRef(nullptr); JsUtil::DeletePtr(work); auto removeEvent = devListener_.find(CHANGED_TYPE); if (removeEvent == devListener_.end()) { @@ -111,7 +113,7 @@ void JsEventTarget::EmitRemoveDeviceEvent(uv_work_t *work, int32_t status) } for (const auto &item : removeEvent->second) { CHKPC(item->env); - if (item->ref != temp) { + if (item->ref != reportData->ref) { continue; } napi_handle_scope scope = nullptr; @@ -124,7 +126,7 @@ void JsEventTarget::EmitRemoveDeviceEvent(uv_work_t *work, int32_t status) CHKRV_SCOPE_DEL(item->env, napi_create_string_utf8(item->env, REMOVE_EVENT.c_str(), NAPI_AUTO_LENGTH, &eventType), CREATE_STRING_UTF8, scope); napi_value deviceId = nullptr; - CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, item->data.deviceId, &deviceId), CREATE_INT32, scope); + CHKRV_SCOPE_DEL(item->env, napi_create_int32(item->env, reportData->deviceId, &deviceId), CREATE_INT32, scope); napi_value object = nullptr; CHKRV_SCOPE_DEL(item->env, napi_create_object(item->env, &object), CREATE_OBJECT, scope); CHKRV_SCOPE_DEL(item->env, napi_set_named_property(item->env, object, "type", eventType), SET_NAMED_PROPERTY, @@ -158,13 +160,18 @@ void JsEventTarget::OnDeviceAdded(int32_t deviceId, const std::string &type) CHKRV(napi_get_uv_event_loop(item->env, &loop), GET_UV_EVENT_LOOP); uv_work_t *work = new (std::nothrow) uv_work_t; CHKPV(work); - item->data.deviceId = deviceId; - work->data = item->ref; + sptr reportData = new (std::nothrow) JsUtil::ReportData; + CHKPV(reportData); + reportData->deviceId = deviceId; + reportData->ref = item->ref; + reportData->IncStrongRef(nullptr); + work->data = reportData.GetRefPtr(); int32_t ret = uv_queue_work_with_qos( loop, work, [](uv_work_t *work) {}, EmitAddedDeviceEvent, uv_qos_user_initiated); if (ret != 0) { MMI_HILOGE("uv_queue_work_with_qos failed"); JsUtil::DeletePtr(work); + reportData->DecStrongRef(nullptr); return; } } @@ -186,13 +193,18 @@ void JsEventTarget::OnDeviceRemoved(int32_t deviceId, const std::string &type) CHKRV(napi_get_uv_event_loop(item->env, &loop), GET_UV_EVENT_LOOP); uv_work_t *work = new (std::nothrow) uv_work_t; CHKPV(work); - item->data.deviceId = deviceId; - work->data = item->ref; + sptr reportData = new (std::nothrow) JsUtil::ReportData; + CHKPV(reportData); + reportData->deviceId = deviceId; + reportData->ref = item->ref; + reportData->IncStrongRef(nullptr); + work->data = reportData.GetRefPtr(); int32_t ret = uv_queue_work_with_qos( loop, work, [](uv_work_t *work) {}, EmitRemoveDeviceEvent, uv_qos_user_initiated); if (ret != 0) { MMI_HILOGE("uv_queue_work_with_qos failed"); JsUtil::DeletePtr(work); + reportData->DecStrongRef(nullptr); return; } } diff --git a/service/device_manager/include/input_device_manager.h b/service/device_manager/include/input_device_manager.h index c2fe5ac6b20fe1eb7663d20182b3095e39e60fbb..efb18455226ea3416b4d157eb6bad2ecb844e2cb 100644 --- a/service/device_manager/include/input_device_manager.h +++ b/service/device_manager/include/input_device_manager.h @@ -59,7 +59,7 @@ public: void Attach(std::shared_ptr observer); void Detach(std::shared_ptr observer); void NotifyPointerDevice(bool hasPointerDevice, bool isVisible); - void AddDevListener(SessionPtr sess, std::function callback); + void AddDevListener(SessionPtr sess); void RemoveDevListener(SessionPtr sess); void Dump(int32_t fd, const std::vector &args); void DumpDeviceList(int32_t fd, const std::vector &args); @@ -87,14 +87,18 @@ private: void FillInputDevice(std::shared_ptr inputDevice, libinput_device *deviceOrigin) const; std::string GetInputIdentification(struct libinput_device* inputDevice); void NotifyDevCallback(int32_t deviceId, struct InputDeviceInfo inDevice); + int32_t NotifyMessage(SessionPtr sess, int32_t id, const std::string &type); + void InitSessionLostCallback(); + void OnSessionLost(SessionPtr session); private: std::map inputDevice_; std::map inputDeviceScreens_; std::list> observers_; - std::map> devListener_; + std::list devListener_; inputDeviceCallback devCallbacks_ { nullptr }; std::map displayInputBindInfos_; DeviceConfigManagement configManagement_; + bool sessionLostCallbackInitialized_ { false }; }; #define InputDevMgr ::OHOS::DelayedSingleton::GetInstance() diff --git a/service/device_manager/src/input_device_manager.cpp b/service/device_manager/src/input_device_manager.cpp index 10468c143553f9cddead336e0ea235c9dd43a2fd..0466bf99396ddde4920c537a9279e2ca49e81fd4 100644 --- a/service/device_manager/src/input_device_manager.cpp +++ b/service/device_manager/src/input_device_manager.cpp @@ -22,12 +22,15 @@ #include "dfx_hisysevent.h" #include "event_dispatch_handler.h" +#include "input_event_handler.h" #include "input_windows_manager.h" #include "key_auto_repeat.h" #include "key_event_normalize.h" #include "key_event_value_transformation.h" #include "key_map_manager.h" +#include "net_packet.h" #include "pointer_drawing_manager.h" +#include "proto.h" #include "util_ex.h" #include "util_napi_error.h" @@ -264,26 +267,18 @@ void InputDeviceManager::SetInputStatusChangeCallback(inputDeviceCallback callba devCallbacks_ = callback; } -void InputDeviceManager::AddDevListener(SessionPtr sess, std::function callback) +void InputDeviceManager::AddDevListener(SessionPtr sess) { CALL_DEBUG_ENTER; - auto ret = devListener_.insert({ sess, callback }); - if (!ret.second) { - MMI_HILOGE("Session is duplicated"); - return; - } + InitSessionLostCallback(); + devListener_.push_back(sess); } void InputDeviceManager::RemoveDevListener(SessionPtr sess) { CALL_DEBUG_ENTER; - auto iter = devListener_.find(sess); - if (iter == devListener_.end()) { - MMI_HILOGE("Session does not exist"); - return; - } + devListener_.remove(sess); MMI_HILOGI("sess with fd%{public}d with pid %{public}d has been deleted", sess->GetFd(), sess->GetPid()); - devListener_.erase(iter); } #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING @@ -389,9 +384,9 @@ void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice) MakeDeviceInfo(inputDevice, info); inputDevice_[deviceId] = info; if (info.enable) { - for (const auto &item : devListener_) { - CHKPC(item.first); - item.second(deviceId, "add"); + for (const auto& item : devListener_) { + CHKPV(item); + NotifyMessage(item, deviceId, "add"); } } NotifyDevCallback(deviceId, info); @@ -458,9 +453,9 @@ void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevic } #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING if (enable) { - for (const auto &item : devListener_) { - CHKPC(item.first); - item.second(deviceId, "remove"); + for (const auto& item : devListener_) { + CHKPV(item); + NotifyMessage(item, deviceId, "remove"); } } ScanPointerDevice(); @@ -660,13 +655,49 @@ int32_t InputDeviceManager::OnEnableInputDevice(bool enable) if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) { continue; } - for (const auto &listener : devListener_) { - CHKPC(listener.first); - listener.second(item.first, enable ? "add" : "remove"); + for (const auto& listener : devListener_) { + CHKPR(listener, ERROR_NULL_POINTER); + NotifyMessage(listener, item.first, enable ? "add" : "remove"); } } } return RET_OK; } + +int32_t InputDeviceManager::NotifyMessage(SessionPtr sess, int32_t id, const std::string &type) +{ + CALL_DEBUG_ENTER; + CHKPR(sess, ERROR_NULL_POINTER); + NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER); + pkt << type << id; + if (pkt.ChkRWError()) { + MMI_HILOGE("Packet write data failed"); + return RET_ERR; + } + if (!sess->SendMsg(pkt)) { + MMI_HILOGE("Sending failed"); + } + return RET_OK; +} + +void InputDeviceManager::InitSessionLostCallback() +{ + if (sessionLostCallbackInitialized_) { + MMI_HILOGE("Init session is failed"); + return; + } + auto udsServerPtr = InputHandler->GetUDSServer(); + CHKPV(udsServerPtr); + udsServerPtr->AddSessionDeletedCallback(std::bind( + &InputDeviceManager::OnSessionLost, this, std::placeholders::_1)); + sessionLostCallbackInitialized_ = true; + MMI_HILOGD("The callback on session deleted is registered successfully"); +} + +void InputDeviceManager::OnSessionLost(SessionPtr session) +{ + CALL_DEBUG_ENTER; + devListener_.remove(session); +} } // namespace MMI } // namespace OHOS diff --git a/service/module_loader/src/mmi_service.cpp b/service/module_loader/src/mmi_service.cpp index 397daa996dc7567f8ef5a7c8721ed214cabff2ce..2c548c6ac9542fbeed6da79151b01bd8f05b0432 100644 --- a/service/module_loader/src/mmi_service.cpp +++ b/service/module_loader/src/mmi_service.cpp @@ -896,24 +896,7 @@ int32_t MMIService::OnRegisterDevListener(int32_t pid) { auto sess = GetSession(GetClientFd(pid)); CHKPR(sess, RET_ERR); - InputDevMgr->AddDevListener(sess, [sess](int32_t id, const std::string &type) { - CALL_DEBUG_ENTER; - CHKPV(sess); - NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER); - pkt << type << id; - if (pkt.ChkRWError()) { - MMI_HILOGE("Packet write data failed"); - return; - } - if (!sess->SendMsg(pkt)) { - MMI_HILOGE("Sending failed"); - if (!sess->IsSocketValid()) { - MMI_HILOGE("sess fd:%{public}d pid:%{public}d is ENOSOCKET, delete it!", sess->GetFd(), sess->GetPid()); - InputDevMgr->RemoveDevListener(sess); - } - return; - } - }); + InputDevMgr->AddDevListener(sess); return RET_OK; } diff --git a/service/window_manager/src/input_windows_manager.cpp b/service/window_manager/src/input_windows_manager.cpp index eb35572749fe00cde94ad7dd8562d5ec5c4bbefe..56d6c8dcf8ce9aa52528fff61c38eb99a0558561 100644 --- a/service/window_manager/src/input_windows_manager.cpp +++ b/service/window_manager/src/input_windows_manager.cpp @@ -1681,6 +1681,7 @@ int32_t InputWindowsManager::UpdateMouseTarget(std::shared_ptr poi IPointerDrawingManager::GetInstance()->OnWindowInfo(info); } GetPointerStyle(touchWindow->pid, touchWindow->id, pointerStyle); + dragPointerStyle_ = pointerStyle; if (!touchWindow) { MMI_HILOGE("TouchWindow is nullptr"); return RET_ERR;