forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Report onscreen text to Fuchsia context engine. (flutter#4097)
Add a class to track onscreen text via SemanticsNodes from the accessibility layer, and report this text to the ContextEngine.
- Loading branch information
1 parent
4aee64f
commit 9d98d88
Showing
6 changed files
with
140 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright 2017 The Fuchsia Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/content_handler/accessibility_bridge.h" | ||
|
||
#include <unordered_set> | ||
|
||
#include "apps/maxwell/services/context/context_writer.fidl.h" | ||
#include "flutter/lib/ui/semantics/semantics_node.h" | ||
#include "lib/app/cpp/application_context.h" | ||
#include "lib/fxl/macros.h" | ||
#include "third_party/rapidjson/rapidjson/document.h" | ||
#include "third_party/rapidjson/rapidjson/stringbuffer.h" | ||
#include "third_party/rapidjson/rapidjson/writer.h" | ||
|
||
namespace flutter_runner { | ||
|
||
AccessibilityBridge::AccessibilityBridge(app::ApplicationContext* context) | ||
: writer_(context->ConnectToEnvironmentService<maxwell::ContextWriter>()) { | ||
writer_.set_connection_error_handler( | ||
[] { FXL_LOG(ERROR) << "Error connecting to ContextWriter."; }); | ||
} | ||
|
||
void AccessibilityBridge::UpdateSemantics( | ||
const std::vector<blink::SemanticsNode>& update) { | ||
for (const auto& node : update) { | ||
semantics_nodes_[node.id] = node; | ||
} | ||
std::vector<int> visited_nodes; | ||
UpdateVisitedForNodeAndChildren(0, &visited_nodes); | ||
EraseUnvisitedNodes(visited_nodes); | ||
|
||
// The data sent to the Context Service is a JSON formatted list of labels | ||
// for all on screen widgets. | ||
rapidjson::Document nodes_json(rapidjson::kArrayType); | ||
for (const int node_index : visited_nodes) { | ||
const auto& node = semantics_nodes_[node_index]; | ||
if (!node.label.empty()) { | ||
rapidjson::Value value; | ||
value.SetString(node.label.data(), node.label.size()); | ||
nodes_json.PushBack(value, nodes_json.GetAllocator()); | ||
} | ||
} | ||
|
||
if (nodes_json.Size() > 0) { | ||
rapidjson::StringBuffer buffer; | ||
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer); | ||
nodes_json.Accept(writer); | ||
writer_->WriteEntityTopic("/inferred/accessibility_text", | ||
buffer.GetString()); | ||
} | ||
} | ||
|
||
void AccessibilityBridge::UpdateVisitedForNodeAndChildren( | ||
const int id, | ||
std::vector<int>* visited_nodes) { | ||
std::map<int, blink::SemanticsNode>::const_iterator it = | ||
semantics_nodes_.find(id); | ||
if (it == semantics_nodes_.end()) { | ||
return; | ||
} | ||
|
||
visited_nodes->push_back(id); | ||
for (const int child : it->second.children) { | ||
UpdateVisitedForNodeAndChildren(child, visited_nodes); | ||
} | ||
} | ||
|
||
void AccessibilityBridge::EraseUnvisitedNodes( | ||
const std::vector<int>& visited_nodes) { | ||
const std::unordered_set<int> visited_nodes_lookup(visited_nodes.begin(), | ||
visited_nodes.end()); | ||
for (auto it = semantics_nodes_.begin(); it != semantics_nodes_.end();) { | ||
if (visited_nodes_lookup.find((*it).first) == visited_nodes_lookup.end()) { | ||
it = semantics_nodes_.erase(it); | ||
} else { | ||
++it; | ||
} | ||
} | ||
} | ||
|
||
} // namespace flutter_runner |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright 2017 The Fuchsia Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_CONTENT_HANDLER_ACCESSIBILITY_BRIDGE_H_ | ||
#define FLUTTER_CONTENT_HANDLER_ACCESSIBILITY_BRIDGE_H_ | ||
|
||
#include <map> | ||
|
||
#include "apps/maxwell/services/context/context_writer.fidl.h" | ||
#include "flutter/lib/ui/semantics/semantics_node.h" | ||
#include "lib/app/cpp/application_context.h" | ||
|
||
namespace flutter_runner { | ||
|
||
// Maintain an up-to-date list of SemanticsNodes on screen, and communicate | ||
// with the Context Service. | ||
class AccessibilityBridge { | ||
public: | ||
explicit AccessibilityBridge(app::ApplicationContext* context); | ||
|
||
// Update the internal representation of the semantics nodes, and write the | ||
// semantics to Context Service. | ||
void UpdateSemantics(const std::vector<blink::SemanticsNode>& update); | ||
|
||
private: | ||
// Walk the semantics node tree starting at |id|, and store the id of each | ||
// visited child in |visited_nodes|. | ||
void UpdateVisitedForNodeAndChildren(const int id, | ||
std::vector<int>* visited_nodes); | ||
|
||
// Remove any node from |semantics_nodes_| that doesn't have an id in | ||
// |visited_nodes|. | ||
void EraseUnvisitedNodes(const std::vector<int>& visited_nodes); | ||
|
||
std::map<int, blink::SemanticsNode> semantics_nodes_; | ||
maxwell::ContextWriterPtr writer_; | ||
}; | ||
|
||
} // namespace flutter_runner | ||
|
||
#endif // FLUTTER_CONTENT_HANDLER_ACCESSIBILITY_BRIDGE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters