修复load page 发送无障碍事件时序问题

Signed-off-by: cuijiawei2022 <cuijiawei14@huawei.com>
This commit is contained in:
cuijiawei2022 2024-11-08 22:00:11 +08:00
parent 94b69e71d5
commit 5b16048fc1
9 changed files with 114 additions and 13 deletions

View File

@ -2112,6 +2112,13 @@ void AceContainer::AttachView(std::shared_ptr<Window> window, const RefPtr<AceVi
};
pipelineContext_->SetUIExtensionEventCallback(uiExtensionEventCallback);
auto accessibilityEventCallback = [weak = WeakClaim(this)] (uint32_t eventId, int64_t parameter) {
auto container = weak.Upgrade();
CHECK_NULL_VOID(container);
container->FireAccessibilityEventCallback(eventId, parameter);
};
pipelineContext_->SetAccessibilityEventCallback(accessibilityEventCallback);
if (GetSettings().usePlatformAsUIThread) {
FrameReport::GetInstance().Init();
} else {
@ -3235,6 +3242,24 @@ void AceContainer::HandleAccessibilityHoverEvent(float pointX, float pointY, int
TaskExecutor::TaskType::UI, "ArkUIHandleAccessibilityHoverEvent");
}
void AceContainer::FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter)
{
CHECK_NULL_VOID(taskExecutor_);
taskExecutor_->PostTask(
[weak = WeakClaim(this), eventId, parameter] {
auto container = weak.Upgrade();
CHECK_NULL_VOID(container);
ContainerScope scope(container->GetInstanceId());
auto pipelineContext = container->GetPipelineContext();
auto ngPipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
CHECK_NULL_VOID(ngPipeline);
auto accessibilityManager = ngPipeline->GetAccessibilityManager();
CHECK_NULL_VOID(accessibilityManager);
accessibilityManager->FireAccessibilityEventCallback(eventId, parameter);
},
TaskExecutor::TaskType::UI, "ArkUIHandleAccessibilityEventCallback");
}
std::vector<Ace::RectF> AceContainer::GetOverlayNodePositions()
{
auto pipeline = AceType::DynamicCast<NG::PipelineContext>(pipelineContext_);

View File

@ -711,6 +711,7 @@ public:
return Rect(rect.posX_, rect.posY_, rect.width_, rect.height_);
}
void FireUIExtensionEventCallback(uint32_t eventId);
void FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter);
private:
virtual bool MaybeRelease() override;

View File

@ -66,8 +66,9 @@ constexpr int32_t ROOT_DECOR_BASE = 3100000;
constexpr int32_t CARD_NODE_ID_RATION = 10000;
constexpr int32_t CARD_ROOT_NODE_ID_RATION = 1000;
constexpr int32_t CARD_BASE = 100000;
constexpr int32_t UEC_EVENT_TASK_DELAY_MILLISECOND = 200;
constexpr int32_t DELAY_SEND_EVENT_MILLISECOND = 20;
constexpr uint32_t SUB_TREE_OFFSET_IN_PAGE_ID = 16;
constexpr int32_t MAX_PAGE_ID_WITH_SUB_TREE = (1 << SUB_TREE_OFFSET_IN_PAGE_ID);
const std::string ACTION_ARGU_SCROLL_STUB = "scrolltype"; // wait for change
const std::string ACTION_DEFAULT_PARAM = "ACCESSIBILITY_ACTION_INVALID";
@ -1230,6 +1231,18 @@ bool IsUserCheckedOrSelected(const RefPtr<NG::FrameNode> frameNode)
}
return false;
}
void UpdateElementInfoPageIdWithTreeId(Accessibility::AccessibilityElementInfo& info, int32_t treeId)
{
int32_t pageId = info.GetPageId();
if ((pageId >= MAX_PAGE_ID_WITH_SUB_TREE) || (pageId < 0)) {
TAG_LOGE(AceLogTag::ACE_ACCESSIBILITY, "pageId %{public}d cannot set tree id", pageId);
} else {
uint32_t unsignedPageId = static_cast<uint32_t>(pageId);
uint32_t unsignedTreeId = static_cast<uint32_t>(treeId);
info.SetPageId((unsignedTreeId << SUB_TREE_OFFSET_IN_PAGE_ID) | unsignedPageId);
}
}
}
void UpdateAccessibilityTextValueInfo(
RefPtr<NG::AccessibilityProperty>& accessibilityProperty, AccessibilityElementInfo& nodeInfo)
@ -2455,6 +2468,7 @@ bool JsAccessibilityManager::SendAccessibilitySyncEvent(
eventInfo.SetSource(elementId);
UpdateElementInfoTreeId(info);
eventInfo.SetElementInfo(info);
eventInfo.SetPageId(info.GetPageId());
TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
"send accessibility componentType:%{public}s event:%{public}d accessibilityId:%{public}" PRId64,
eventInfo.GetComponentType().c_str(), eventInfo.GetEventType(), eventInfo.GetAccessibilityId());
@ -5318,17 +5332,6 @@ void JsAccessibilityManager::JsInteractionOperation::SetChildTreeIdAndWinId(
auto jsAccessibilityManager = GetHandler().Upgrade();
CHECK_NULL_VOID(jsAccessibilityManager);
jsAccessibilityManager->NotifySetChildTreeIdAndWinId(splitElementId, treeId, childWindowId);
auto context = jsAccessibilityManager->GetPipelineContext().Upgrade();
CHECK_NULL_VOID(context);
context->GetTaskExecutor()->PostDelayedTask(
[weak = GetHandler(), splitElementId] {
auto jsAccessibilityManager = weak.Upgrade();
CHECK_NULL_VOID(jsAccessibilityManager);
ACE_SCOPED_TRACE("SendUecOnTreeEvent");
jsAccessibilityManager->SendUecOnTreeEvent(splitElementId);
},
TaskExecutor::TaskType::UI, UEC_EVENT_TASK_DELAY_MILLISECOND, "ArkUIAccessibilitySendUecOnTreeEvent");
}
void JsAccessibilityManager::JsInteractionOperation::SetBelongTreeId(const int32_t treeId)
@ -5366,6 +5369,8 @@ void JsAccessibilityManager::UpdateElementInfoTreeId(Accessibility::Accessibilit
info.SetParent(parentId);
}
UpdateElementInfoPageIdWithTreeId(info, treeId);
std::vector<int64_t> childIds = info.GetChildIds();
for (int64_t child : childIds) {
info.RemoveChild(child);
@ -5392,6 +5397,8 @@ void JsAccessibilityManager::UpdateElementInfosTreeId(std::list<Accessibility::A
item.SetParent(parentId);
}
UpdateElementInfoPageIdWithTreeId(item, treeId);
std::vector<int64_t> childIds = item.GetChildIds();
for (int64_t child : childIds) {
item.RemoveChild(child);
@ -6188,4 +6195,19 @@ void JsAccessibilityManager::GetWebCursorPosition(const int64_t elementId, const
callback.SetCursorPositionResult(node->GetSelectionStart(), requestId);
}
#endif // WEB_SUPPORTED
void JsAccessibilityManager::FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter)
{
auto eventType = static_cast<AccessibilityCallbackEventId>(eventId);
AccessibilityEvent event;
switch (eventType) {
case AccessibilityCallbackEventId::ON_LOAD_PAGE:
event.nodeId = parameter;
event.windowChangeTypes = WindowUpdateType::WINDOW_UPDATE_ACTIVE;
event.type = AccessibilityEventType::CHANGE;
SendAccessibilityAsyncEvent(event);
default:
break;
}
}
} // namespace OHOS::Ace::Framework

View File

@ -252,6 +252,8 @@ public:
const std::vector<std::string>& params,
std::vector<std::string>& info) override;
void FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter) override;
protected:
void OnDumpInfoNG(const std::vector<std::string>& params, uint32_t windowId, bool hasJson = false) override;
void DumpHandleEvent(const std::vector<std::string>& params) override;

View File

@ -84,6 +84,22 @@ struct AccessibilityParentRectInfo {
int32_t rotateDegree = 0; // final rotate degree of parent interface
};
enum class AccessibilityCallbackEventId : uint32_t {
ON_LOAD_PAGE = 0,
ON_SHOW = 1,
ON_HIDE = 2,
};
struct AccessibilityCallbackEvent {
AccessibilityCallbackEventId eventId;
int64_t parameter;
AccessibilityCallbackEvent(AccessibilityCallbackEventId id, int64_t para) : eventId(id), parameter(para) {}
bool operator < (const AccessibilityCallbackEvent& other) const
{
return eventId < other.eventId;
}
};
class AccessibilitySAObserverCallback {
public:
explicit AccessibilitySAObserverCallback(int64_t accessibilityId) : accessibilityId_(accessibilityId)
@ -244,6 +260,8 @@ public:
return false;
}
virtual void FireAccessibilityEventCallback(uint32_t eventId, int64_t parameter) {}
bool IsRegister()
{
return isReg_;

View File

@ -893,6 +893,29 @@ void PipelineBase::FireUIExtensionEventOnceImmediately(NG::UIExtCallbackEventId
uiExtensionEventCallback_(static_cast<uint32_t>(eventId));
}
void PipelineBase::SetAccessibilityEventCallback(std::function<void(uint32_t, int64_t)>&& callback)
{
ACE_FUNCTION_TRACE();
accessibilityCallback_ = callback;
}
void PipelineBase::AddAccessibilityCallbackEvent(AccessibilityCallbackEventId event, int64_t parameter)
{
ACE_SCOPED_TRACE("AccessibilityCallbackEvent event[%u]", static_cast<uint32_t>(event));
accessibilityEvents_.insert(AccessibilityCallbackEvent(event, parameter));
}
void PipelineBase::FireAccessibilityEvents()
{
if (!accessibilityCallback_ || accessibilityEvents_.empty()) {
return;
}
for (auto it = accessibilityEvents_.begin(); it != accessibilityEvents_.end();) {
accessibilityCallback_(static_cast<uint32_t>(it->eventId), it->parameter);
it = accessibilityEvents_.erase(it);
}
}
void PipelineBase::SetSubWindowVsyncCallback(AceVsyncCallback&& callback, int32_t subWindowId)
{
if (callback) {

View File

@ -1444,6 +1444,13 @@ public:
// Prints out the count of the unexecuted finish callback
std::string GetUnexecutedFinishCount() const;
void SetAccessibilityEventCallback(std::function<void(uint32_t, int64_t)>&& callback);
void AddAccessibilityCallbackEvent(AccessibilityCallbackEventId event, int64_t parameter);
void FireAccessibilityEvents();
protected:
virtual bool MaybeRelease() override;
void TryCallNextFrameLayoutCallback()
@ -1635,6 +1642,8 @@ private:
std::function<double()> windowDensityCallback_;
std::function<void(uint32_t)> uiExtensionEventCallback_;
std::set<NG::UIExtCallbackEvent> uiExtensionEvents_;
std::function<void(uint32_t, int64_t)> accessibilityCallback_;
std::set<AccessibilityCallbackEvent> accessibilityEvents_;
ACE_DISALLOW_COPY_AND_MOVE(PipelineBase);
};

View File

@ -952,6 +952,7 @@ void PipelineContext::FlushVsync(uint64_t nanoTimestamp, uint32_t frameCount)
if (IsFocusWindowIdSetted()) {
FireAllUIExtensionEvents();
}
FireAccessibilityEvents();
// Keep the call sent at the end of the function
ResSchedReport::GetInstance().LoadPageEvent(ResDefine::LOAD_PAGE_COMPLETE_EVENT);
window_->Unlock();

View File

@ -604,7 +604,7 @@ HWTEST_F(JsThirdProviderInteractionOperationTest, JsThirdProviderInteractionOper
auto jsInteractionOperation = AceType::MakeRefPtr<Framework::JsThirdProviderInteractionOperation>(
ohAccessibilityProvider, jsAccessibilityManager, frameNode);
int32_t treeId = 3;
int32_t treeId = 0;
jsInteractionOperation->SetBelongTreeId(treeId);
int32_t pageId = 4;
frameNode->SetHostPageId(pageId);