From 53a287081d64cf0065d9608f188a0fef49298ddb Mon Sep 17 00:00:00 2001 From: Mupceet Date: Sat, 15 Oct 2022 15:06:18 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=97=A0=E9=9A=9C=E7=A2=8D=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=BC=82=E5=B8=B8=E6=97=B6=E5=BA=94=E8=AF=A5=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E5=AE=A2=E6=88=B7=E7=AB=AF=E8=BF=9E=E6=8E=A5=E7=8A=B6?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mupceet --- .../include/accessible_ability_client_impl.h | 21 ++- .../src/accessible_ability_client_impl.cpp | 168 ++++++++++++++---- .../accessible_ability_client_impl_test.cpp | 15 ++ 3 files changed, 166 insertions(+), 38 deletions(-) diff --git a/frameworks/aafwk/include/accessible_ability_client_impl.h b/frameworks/aafwk/include/accessible_ability_client_impl.h index 3c153a08..6b554a75 100644 --- a/frameworks/aafwk/include/accessible_ability_client_impl.h +++ b/frameworks/aafwk/include/accessible_ability_client_impl.h @@ -17,6 +17,7 @@ #define ACCESSIBLE_ABILITY_CLIENT_IMPL_H #include +#include #include "accessible_ability_channel_client.h" #include "accessible_ability_client.h" #include "accessible_ability_client_stub.h" @@ -34,7 +35,7 @@ public: /** * @brief The deconstructor of AccessibleAbilityClientImpl. */ - ~AccessibleAbilityClientImpl() = default; + ~AccessibleAbilityClientImpl(); /** * @brief Gets remote object. @@ -242,6 +243,12 @@ public: */ void ResetAAClient(const wptr &remote); + /** + * @brief Notify AA client and clean data when service is died. + * @param remote The object access to AAMS. + */ + void NotifyServiceDied(const wptr &remote); + private: class AccessibleAbilityDeathRecipient final : public IRemoteObject::DeathRecipient { public: @@ -254,6 +261,17 @@ private: AccessibleAbilityClientImpl &client_; }; + class AccessibilityServiceDeathRecipient final : public IRemoteObject::DeathRecipient { + public: + AccessibilityServiceDeathRecipient(AccessibleAbilityClientImpl &client) : client_(client) {} + ~AccessibilityServiceDeathRecipient() = default; + DISALLOW_COPY_AND_MOVE(AccessibilityServiceDeathRecipient); + + void OnRemoteDied(const wptr &remote); + private: + AccessibleAbilityClientImpl &client_; + }; + bool GetCacheElementInfo(const int32_t windowId, const int32_t elementId, AccessibilityElementInfo &elementInfo) const; void SetCacheElementInfo(const int32_t windowId, @@ -262,6 +280,7 @@ private: const uint32_t mode, AccessibilityElementInfo &info); sptr deathRecipient_ = nullptr; + sptr accessibilityServiceDeathRecipient_ = nullptr; sptr serviceProxy_ = nullptr; std::shared_ptr listener_ = nullptr; std::shared_ptr channelClient_ = nullptr; diff --git a/frameworks/aafwk/src/accessible_ability_client_impl.cpp b/frameworks/aafwk/src/accessible_ability_client_impl.cpp index 9603df17..e3011b8e 100644 --- a/frameworks/aafwk/src/accessible_ability_client_impl.cpp +++ b/frameworks/aafwk/src/accessible_ability_client_impl.cpp @@ -68,6 +68,25 @@ AccessibleAbilityClientImpl::AccessibleAbilityClientImpl() HILOG_ERROR("Get aams proxy failed"); return; } + + // Add death recipient + if (!accessibilityServiceDeathRecipient_) { + accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this); + } + + if (serviceProxy_->AsObject()) { + HILOG_DEBUG("Add death recipient"); + serviceProxy_->AsObject()->AddDeathRecipient(accessibilityServiceDeathRecipient_); + } +} + +AccessibleAbilityClientImpl::~AccessibleAbilityClientImpl() +{ + HILOG_DEBUG(); + if (serviceProxy_ && serviceProxy_->AsObject()) { + HILOG_DEBUG("Remove service death recipient"); + serviceProxy_->AsObject()->RemoveDeathRecipient(accessibilityServiceDeathRecipient_); + } } sptr AccessibleAbilityClientImpl::GetRemoteObject() @@ -83,6 +102,7 @@ sptr AccessibleAbilityClientImpl::GetRemoteObject() bool AccessibleAbilityClientImpl::RegisterAbilityListener(const std::shared_ptr &listener) { HILOG_INFO(); + std::lock_guard lock(mutex_); if (listener_) { HILOG_DEBUG("listener already exists."); return false; @@ -100,79 +120,105 @@ void AccessibleAbilityClientImpl::Init(const sptr &ch return; } - if (!listener_) { - HILOG_ERROR("listener_ is nullptr."); - return; - } - - channelClient_ = std::make_shared(channelId, channel); - - // Add death recipient - if (!deathRecipient_) { - deathRecipient_ = new(std::nothrow) AccessibleAbilityDeathRecipient(*this); - if (!deathRecipient_) { - HILOG_ERROR("Failed to create deathRecipient."); + std::shared_ptr listener = nullptr; + { + std::lock_guard lock(mutex_); + if (!listener_) { + HILOG_ERROR("listener_ is nullptr."); return; } + listener = listener_; + channelClient_ = std::make_shared(channelId, channel); + + // Add death recipient + if (!deathRecipient_) { + deathRecipient_ = new(std::nothrow) AccessibleAbilityDeathRecipient(*this); + if (!deathRecipient_) { + HILOG_ERROR("Failed to create deathRecipient."); + return; + } + } + + if (channel->AsObject()) { + HILOG_DEBUG("Add death recipient"); + channel->AsObject()->AddDeathRecipient(deathRecipient_); + } } - auto object = channelClient_->GetRemote(); - if (object) { - HILOG_DEBUG("Add death recipient"); - object->AddDeathRecipient(deathRecipient_); - } std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_WINDOW_REGIST)); - listener_->OnAbilityConnected(); + if (listener) { + listener->OnAbilityConnected(); + } } void AccessibleAbilityClientImpl::Disconnect(const int32_t channelId) { HILOG_INFO("channelId[%{public}d]", channelId); - // Delete death recipient - if (channelClient_ && channelClient_->GetRemote()) { - HILOG_ERROR("Remove death recipient"); - channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_); + std::shared_ptr listener = nullptr; + { + std::lock_guard lock(mutex_); + // Delete death recipient + if (channelClient_ && channelClient_->GetRemote()) { + HILOG_ERROR("Remove death recipient"); + channelClient_->GetRemote()->RemoveDeathRecipient(deathRecipient_); + } + + // Remove channel + channelClient_ = nullptr; + listener = listener_; + listener_ = nullptr; } - // Remove channel - channelClient_ = nullptr; - - if (listener_) { - listener_->OnAbilityDisconnected(); - listener_ = nullptr; + if (listener) { + listener->OnAbilityDisconnected(); } } void AccessibleAbilityClientImpl::OnAccessibilityEvent(const AccessibilityEventInfo &eventInfo) { HILOG_INFO(); - if (!channelClient_) { - HILOG_ERROR("The channel is invalid."); - return; + std::shared_ptr listener = nullptr; + { + std::lock_guard lock(mutex_); + if (!channelClient_) { + HILOG_ERROR("The channel is invalid."); + return; + } + listener = listener_; } - if (listener_) { - listener_->OnAccessibilityEvent(eventInfo); + if (listener) { + listener->OnAccessibilityEvent(eventInfo); } } void AccessibleAbilityClientImpl::OnKeyPressEvent(const MMI::KeyEvent &keyEvent, const int32_t sequence) { HILOG_INFO("sequence[%{public}d]", sequence); - if (!channelClient_) { + std::shared_ptr listener = nullptr; + std::shared_ptr channel = nullptr; + { + std::lock_guard lock(mutex_); + listener = listener_; + channel = channelClient_; + } + + if (!channel) { HILOG_ERROR("The channel is invalid."); return; } - if (listener_) { + bool handled = false; + if (listener) { std::shared_ptr tmp = std::make_shared(keyEvent); - bool handled = listener_->OnKeyPressEvent(tmp); - channelClient_->SetOnKeyPressEventResult(handled, sequence); + handled = listener->OnKeyPressEvent(tmp); } + channel->SetOnKeyPressEventResult(handled, sequence); } bool AccessibleAbilityClientImpl::GetFocus(const int32_t focusType, AccessibilityElementInfo &elementInfo) { HILOG_INFO("focusType[%{public}d]", focusType); + std::lock_guard lock(mutex_); if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) { HILOG_ERROR("focusType is not allowed."); return false; @@ -190,6 +236,7 @@ bool AccessibleAbilityClientImpl::GetFocusByElementInfo(const AccessibilityEleme const int32_t focusType, AccessibilityElementInfo &elementInfo) { HILOG_INFO("focusType[%{public}d]", focusType); + std::lock_guard lock(mutex_); if ((focusType != FOCUS_TYPE_INPUT) && (focusType != FOCUS_TYPE_ACCESSIBILITY)) { HILOG_ERROR("focusType is not allowed."); return false; @@ -210,6 +257,7 @@ bool AccessibleAbilityClientImpl::GetFocusByElementInfo(const AccessibilityEleme bool AccessibleAbilityClientImpl::InjectGesture(const std::shared_ptr &gesturePath) { HILOG_INFO(); + std::lock_guard lock(mutex_); if (!gesturePath) { HILOG_ERROR("The gesturePath is null."); @@ -234,6 +282,7 @@ bool AccessibleAbilityClientImpl::InjectGesture(const std::shared_ptr lock(mutex_); if (!channelClient_ || !serviceProxy_) { HILOG_ERROR("The channel is invalid."); return false; @@ -257,6 +306,7 @@ bool AccessibleAbilityClientImpl::GetRootByWindow(const AccessibilityWindowInfo AccessibilityElementInfo &elementInfo) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -279,6 +329,7 @@ bool AccessibleAbilityClientImpl::GetRootByWindow(const AccessibilityWindowInfo bool AccessibleAbilityClientImpl::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo) { HILOG_INFO("windowId[%{public}d]", windowId); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -289,6 +340,7 @@ bool AccessibleAbilityClientImpl::GetWindow(const int32_t windowId, Accessibilit bool AccessibleAbilityClientImpl::GetWindows(std::vector &windows) { HILOG_INFO(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -299,6 +351,7 @@ bool AccessibleAbilityClientImpl::GetWindows(std::vector &windows) { HILOG_INFO("displayId[%{public}" PRIu64 "]", displayId); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -311,6 +364,7 @@ bool AccessibleAbilityClientImpl::GetNext(const AccessibilityElementInfo &elemen { HILOG_INFO("windowId[%{public}d], elementId[%{public}d], direction[%{public}d]", elementInfo.GetWindowId(), elementInfo.GetAccessibilityId(), direction); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -327,6 +381,7 @@ bool AccessibleAbilityClientImpl::GetChildElementInfo(const int32_t index, const AccessibilityElementInfo &child) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -355,6 +410,7 @@ bool AccessibleAbilityClientImpl::GetChildren(const AccessibilityElementInfo &pa std::vector &children) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -390,6 +446,7 @@ bool AccessibleAbilityClientImpl::GetByContent(const AccessibilityElementInfo &e std::vector &elementInfos) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -404,6 +461,7 @@ bool AccessibleAbilityClientImpl::GetSource(const AccessibilityEventInfo &eventI AccessibilityElementInfo &elementInfo) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -427,6 +485,7 @@ bool AccessibleAbilityClientImpl::GetParentElementInfo(const AccessibilityElemen AccessibilityElementInfo &parent) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -450,6 +509,7 @@ bool AccessibleAbilityClientImpl::ExecuteAction(const AccessibilityElementInfo & const std::map &actionArguments) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -468,6 +528,7 @@ bool AccessibleAbilityClientImpl::ExecuteAction(const AccessibilityElementInfo & bool AccessibleAbilityClientImpl::SetTargetBundleName(const std::vector &targetBundleNames) { HILOG_INFO("targetBundleNames size[%{public}zu]", targetBundleNames.size()); + std::lock_guard lock(mutex_); if (!channelClient_) { HILOG_ERROR("The channel is invalid."); return false; @@ -481,9 +542,41 @@ void AccessibleAbilityClientImpl::AccessibleAbilityDeathRecipient::OnRemoteDied( client_.ResetAAClient(remote); } +void AccessibleAbilityClientImpl::AccessibilityServiceDeathRecipient::OnRemoteDied(const wptr& remote) +{ + HILOG_ERROR(); + client_.NotifyServiceDied(remote); +} + +void AccessibleAbilityClientImpl::NotifyServiceDied(const wptr &remote) +{ + std::shared_ptr listener = nullptr; + { + std::lock_guard lock(mutex_); + if (!serviceProxy_) { + HILOG_ERROR("serviceProxy_ is nullptr"); + return; + } + sptr object = serviceProxy_->AsObject(); + if (object && (remote == object)) { + listener = listener_; + listener_ = nullptr; + + object->RemoveDeathRecipient(accessibilityServiceDeathRecipient_); + channelClient_ = nullptr; + HILOG_DEBUG("ResetAAClient OK"); + } + } + + if (listener) { + listener->OnAbilityDisconnected(); + } +} + void AccessibleAbilityClientImpl::ResetAAClient(const wptr &remote) { HILOG_DEBUG(); + std::lock_guard lock(mutex_); if (channelClient_) { sptr object = channelClient_->GetRemote(); if (object && (remote == object)) { @@ -497,6 +590,7 @@ void AccessibleAbilityClientImpl::ResetAAClient(const wptr &remot void AccessibleAbilityClientImpl::SetCacheMode(const int32_t cacheMode) { HILOG_INFO("set cache mode: [%{public}d]", cacheMode); + std::lock_guard lock(mutex_); cacheWindowId_ = -1; cacheElementInfos_.clear(); if (cacheMode < 0) { diff --git a/frameworks/aafwk/test/unittest/accessible_ability_client_impl_test.cpp b/frameworks/aafwk/test/unittest/accessible_ability_client_impl_test.cpp index ace8361d..4fd844cd 100644 --- a/frameworks/aafwk/test/unittest/accessible_ability_client_impl_test.cpp +++ b/frameworks/aafwk/test/unittest/accessible_ability_client_impl_test.cpp @@ -844,5 +844,20 @@ HWTEST_F(AccessibleAbilityClientImplTest, GetWindow_002, TestSize.Level1) EXPECT_TRUE(instance_->GetWindow(0, windowInfo)); GTEST_LOG_(INFO) << "GetWindow_002 end"; } + +/** + * @tc.number: NotifyServiceDied_001 + * @tc.name: NotifyServiceDied + * @tc.desc: Test function NotifyServiceDied + */ +HWTEST_F(AccessibleAbilityClientImplTest, NotifyServiceDied_001, TestSize.Level1) +{ + GTEST_LOG_(INFO) << "NotifyServiceDied_001 start"; + Connect(); + wptr remote = nullptr; + instance_->NotifyServiceDied(remote); + EXPECT_EQ(AccessibilityAbilityHelper::GetInstance().GetTestChannelId(), static_cast(CHANNEL_ID)); + GTEST_LOG_(INFO) << "NotifyServiceDied_001 end"; +} } // namespace Accessibility } // namespace OHOS \ No newline at end of file From efa10f338e95a5865d20d41efbadfca4cbb68843 Mon Sep 17 00:00:00 2001 From: Mupceet Date: Sat, 15 Oct 2022 15:34:48 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mupceet --- frameworks/aafwk/include/accessible_ability_client_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/aafwk/include/accessible_ability_client_impl.h b/frameworks/aafwk/include/accessible_ability_client_impl.h index 6b554a75..14329bd0 100644 --- a/frameworks/aafwk/include/accessible_ability_client_impl.h +++ b/frameworks/aafwk/include/accessible_ability_client_impl.h @@ -287,6 +287,7 @@ private: uint32_t cacheMode_ = 0; int32_t cacheWindowId_ = -1; std::map cacheElementInfos_; + std::mutex mutex_; }; } // namespace Accessibility } // namespace OHOS From 794ab8412959e2cabee0535b63d82c5ea500aa14 Mon Sep 17 00:00:00 2001 From: Mupceet Date: Mon, 17 Oct 2022 09:36:26 +0800 Subject: [PATCH 3/3] fix review problem Signed-off-by: Mupceet --- frameworks/aafwk/src/accessible_ability_client_impl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frameworks/aafwk/src/accessible_ability_client_impl.cpp b/frameworks/aafwk/src/accessible_ability_client_impl.cpp index e3011b8e..11b162da 100644 --- a/frameworks/aafwk/src/accessible_ability_client_impl.cpp +++ b/frameworks/aafwk/src/accessible_ability_client_impl.cpp @@ -72,6 +72,10 @@ AccessibleAbilityClientImpl::AccessibleAbilityClientImpl() // Add death recipient if (!accessibilityServiceDeathRecipient_) { accessibilityServiceDeathRecipient_ = new(std::nothrow) AccessibilityServiceDeathRecipient(*this); + if (!accessibilityServiceDeathRecipient_) { + HILOG_ERROR("Failed to create service deathRecipient."); + return; + } } if (serviceProxy_->AsObject()) {