Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(872)

Unified Diff: content/public/browser/voice_interaction_helper.cc

Issue 2768093005: Send voice interaction structure from cros to Arc. (Closed)
Patch Set: address review comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/browser/voice_interaction_helper.cc
diff --git a/content/public/browser/voice_interaction_helper.cc b/content/public/browser/voice_interaction_helper.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a55a26c1f79c743b4dd5f06cc54ef14aa855b057
--- /dev/null
+++ b/content/public/browser/voice_interaction_helper.cc
@@ -0,0 +1,172 @@
+// Copyright 2017 The Chromium 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 "content/public/browser/voice_interaction_helper.h"
+
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/accessibility/platform/ax_android_constants.h"
+
+namespace content {
+
+namespace {
+
+std::string GetClassName(BrowserAccessibility* node) {
+ const char* class_name = nullptr;
Luis Héctor Chávez 2017/04/03 23:24:12 Since you're only setting this once per branch, ho
Muyuan 2017/04/04 00:39:39 Done.
+
+ switch (node->GetRole()) {
+ case ui::AX_ROLE_SEARCH_BOX:
+ case ui::AX_ROLE_SPIN_BUTTON:
+ case ui::AX_ROLE_TEXT_FIELD:
+ class_name = ui::kAXEditTextClassname;
+ break;
+ case ui::AX_ROLE_SLIDER:
+ class_name = ui::kAXSeekBarClassname;
+ break;
+ case ui::AX_ROLE_COLOR_WELL:
+ case ui::AX_ROLE_COMBO_BOX:
+ case ui::AX_ROLE_DATE:
+ case ui::AX_ROLE_POP_UP_BUTTON:
+ case ui::AX_ROLE_INPUT_TIME:
+ class_name = ui::kAXSpinnerClassname;
+ break;
+ case ui::AX_ROLE_BUTTON:
+ case ui::AX_ROLE_MENU_BUTTON:
+ class_name = ui::kAXButtonClassname;
+ break;
+ case ui::AX_ROLE_CHECK_BOX:
+ case ui::AX_ROLE_SWITCH:
+ class_name = ui::kAXCheckBoxClassname;
+ break;
+ case ui::AX_ROLE_RADIO_BUTTON:
+ class_name = ui::kAXRadioButtonClassname;
+ break;
+ case ui::AX_ROLE_TOGGLE_BUTTON:
+ class_name = ui::kAXToggleButtonClassname;
+ break;
+ case ui::AX_ROLE_CANVAS:
+ case ui::AX_ROLE_IMAGE:
+ case ui::AX_ROLE_SVG_ROOT:
+ class_name = ui::kAXImageClassname;
+ break;
+ case ui::AX_ROLE_METER:
+ case ui::AX_ROLE_PROGRESS_INDICATOR:
+ class_name = ui::kAXProgressBarClassname;
+ break;
+ case ui::AX_ROLE_TAB_LIST:
+ class_name = ui::kAXTabWidgetClassname;
+ break;
+ case ui::AX_ROLE_GRID:
+ case ui::AX_ROLE_TABLE:
+ class_name = ui::kAXGridViewClassname;
+ break;
+ case ui::AX_ROLE_LIST:
+ case ui::AX_ROLE_LIST_BOX:
+ case ui::AX_ROLE_DESCRIPTION_LIST:
+ class_name = ui::kAXListViewClassname;
+ break;
+ case ui::AX_ROLE_DIALOG:
+ class_name = ui::kAXDialogClassname;
+ break;
+ case ui::AX_ROLE_ROOT_WEB_AREA:
+ if (node->PlatformGetParent() == nullptr) {
+ class_name = ui::kAXWebViewClassname;
+ } else {
+ class_name = ui::kAXViewClassname;
+ }
+ break;
+ case ui::AX_ROLE_MENU_ITEM:
+ case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
+ case ui::AX_ROLE_MENU_ITEM_RADIO:
+ class_name = ui::kAXMenuItemClassname;
+ break;
+ default:
+ class_name = ui::kAXViewClassname;
+ break;
+ }
+
+ return std::string(class_name);
+}
+
+// TODO(muyuanli): refactor code in web_contents_android
+// to use this function as well.
+std::unique_ptr<AXViewStructure> WalkAXTreeDepthFirst(
+ BrowserAccessibility* node,
+ gfx::Rect rect,
+ const ui::AXTreeUpdate& update) {
+ auto result = base::MakeUnique<AXViewStructure>();
+ result->text = node->GetText();
+ result->class_name = GetClassName(node);
+
+ const int text_style = node->GetIntAttribute(ui::AX_ATTR_TEXT_STYLE);
+ result->bold = (text_style & ui::AX_TEXT_STYLE_BOLD) != 0;
+ result->italic = (text_style & ui::AX_TEXT_STYLE_ITALIC) != 0;
+ result->line_through = (text_style & ui::AX_TEXT_STYLE_LINE_THROUGH) != 0;
+ result->underline = (text_style & ui::AX_TEXT_STYLE_ITALIC) != 0;
+
+ result->text_size = node->GetFloatAttribute(ui::AX_ATTR_FONT_SIZE);
+ result->bgcolor = node->GetIntAttribute(ui::AX_ATTR_BACKGROUND_COLOR);
+
+ const gfx::Rect& absolute_rect = node->GetPageBoundsRect();
+ gfx::Rect parent_relative_rect = absolute_rect;
+ bool is_root = node->GetParent() == nullptr;
+ if (!is_root) {
+ parent_relative_rect.Offset(-rect.OffsetFromOrigin());
+ }
+ result->rect = gfx::Rect(parent_relative_rect.x(), parent_relative_rect.y(),
+ absolute_rect.width(), absolute_rect.height());
+ result->has_selection = false;
+
+ if (node->PlatformIsLeaf()) {
+ int start_selection = 0;
+ int end_selection = 0;
+ if (update.tree_data.sel_anchor_object_id == node->GetId()) {
+ start_selection = update.tree_data.sel_anchor_offset;
+ end_selection = node->GetText().length();
+ }
+ if (update.tree_data.sel_focus_object_id == node->GetId()) {
+ end_selection = update.tree_data.sel_focus_offset;
+ }
+ if (end_selection > 0) {
+ result->has_selection = true;
+ result->start_selection = start_selection;
+ result->end_selection = end_selection;
+ }
+ }
+
+ for (unsigned int i = 0; i < node->PlatformChildCount(); i++) {
+ auto child =
+ WalkAXTreeDepthFirst(node->PlatformGetChild(i), absolute_rect, update);
+ result->children.push_back(std::move(child));
+ }
+
+ return result;
+}
+
+void AXSnapshotCallback(
+ const base::Callback<void(std::unique_ptr<AXViewStructure>)>& callback,
+ const ui::AXTreeUpdate& ax_tree_update) {
+ auto manager = std::unique_ptr<content::BrowserAccessibilityManager>(
+ content::BrowserAccessibilityManager::Create(ax_tree_update, nullptr));
+ callback.Run(
+ WalkAXTreeDepthFirst(manager->GetRoot(), gfx::Rect(), ax_tree_update));
+}
+
+} // namespace
+
+AXViewStructure::AXViewStructure() {}
+
+AXViewStructure::~AXViewStructure() {}
+
+void GetAXViewStructure(
+ WebContents* web_contents,
+ const base::Callback<void(std::unique_ptr<AXViewStructure>)>& callback) {
+ WebContentsImpl* web_contents_impl =
+ static_cast<WebContentsImpl*>(web_contents);
+ web_contents_impl->RequestAXTreeSnapshot(
+ base::Bind(&AXSnapshotCallback, callback));
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698