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

Unified Diff: chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc

Issue 2826423003: Expand Chrome OS ARC support to create one tree source per package (Closed)
Patch Set: Remove logging. Created 3 years, 8 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: chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
index 908e8737ed31b5d7d29ff1076bbef939e58ea61d..06cbd281c2221f88f9284332ec7e5b80c443ed25 100644
--- a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
+++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -6,7 +6,7 @@
#include "base/command_line.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
-#include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h"
+#include "chrome/browser/profiles/profile.h"
#include "chromeos/chromeos_switches.h"
#include "components/arc/arc_bridge_service.h"
#include "components/exo/shell_surface.h"
@@ -14,32 +14,9 @@
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
namespace {
-// This class keeps focus on a |ShellSurface| without interfering with default
-// focus management in |ShellSurface|. For example, touch causes the
-// |ShellSurface| to lose focus to its ancestor containing View.
-class FocusStealer : public views::View {
- public:
- explicit FocusStealer(int32_t id) : id_(id) {
- SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
- set_owned_by_client();
- }
-
- // views::View overrides.
- void GetAccessibleNodeData(ui::AXNodeData* node_data) override {
- node_data->AddIntAttribute(ui::AX_ATTR_CHILD_TREE_ID, id_);
- node_data->role = ui::AX_ROLE_CLIENT;
- }
-
- private:
- int32_t id_;
- DISALLOW_COPY_AND_ASSIGN(FocusStealer);
-};
-
exo::Surface* GetArcSurface(const aura::Window* window) {
if (!window)
return nullptr;
@@ -50,6 +27,18 @@ exo::Surface* GetArcSurface(const aura::Window* window) {
return arc_surface;
}
+int32_t GetTaskId(aura::Window* window) {
+ const std::string arc_app_id = exo::ShellSurface::GetApplicationId(window);
+ if (arc_app_id.empty())
+ return -1;
dmazzoni 2017/04/25 16:09:24 how about kNoTaskId?
David Tseng 2017/04/25 22:48:03 Done.
+
+ int task_id = -1;
+ if (sscanf(arc_app_id.c_str(), "org.chromium.arc.%d", &task_id) != 1)
+ return -1;
+
+ return task_id;
+}
+
void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data) {
chromeos::AccessibilityManager* accessibility_manager =
chromeos::AccessibilityManager::Get();
@@ -70,40 +59,56 @@ void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data) {
accessibility_manager->OnViewFocusedInArc(bounds_in_screen);
}
+arc::mojom::AccessibilityFilterType GetFilterType() {
+ chromeos::AccessibilityManager* accessibility_manager =
+ chromeos::AccessibilityManager::Get();
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ chromeos::switches::kEnableChromeVoxArcSupport))
+ return arc::mojom::AccessibilityFilterType::ALL;
+
+ if (!accessibility_manager)
+ return arc::mojom::AccessibilityFilterType::OFF;
+
+ if (accessibility_manager->IsSpokenFeedbackEnabled())
+ return arc::mojom::AccessibilityFilterType::WHITELISTED_PACKAGE_NAME;
+
+ if (accessibility_manager->IsFocusHighlightEnabled())
+ return arc::mojom::AccessibilityFilterType::FOCUS;
+
+ return arc::mojom::AccessibilityFilterType::OFF;
+}
+
} // namespace
namespace arc {
ArcAccessibilityHelperBridge::ArcAccessibilityHelperBridge(
ArcBridgeService* bridge_service)
- : ArcService(bridge_service), binding_(this) {
+ : ArcService(bridge_service), binding_(this), current_task_id_(0) {
arc_bridge_service()->accessibility_helper()->AddObserver(this);
}
ArcAccessibilityHelperBridge::~ArcAccessibilityHelperBridge() {
arc_bridge_service()->accessibility_helper()->RemoveObserver(this);
+ ArcAppListPrefs::Get(chromeos::AccessibilityManager::Get()->profile())
+ ->RemoveObserver(this);
}
void ArcAccessibilityHelperBridge::OnInstanceReady() {
+ ArcAppListPrefs::Get(chromeos::AccessibilityManager::Get()->profile())
+ ->AddObserver(this);
auto* instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service()->accessibility_helper(), Init);
DCHECK(instance);
instance->Init(binding_.CreateInterfacePtrAndBind());
- chromeos::AccessibilityManager* accessibility_manager =
- chromeos::AccessibilityManager::Get();
- if (base::CommandLine::ForCurrentProcess()->HasSwitch(
- chromeos::switches::kEnableChromeVoxArcSupport)) {
- instance->SetFilter(arc::mojom::AccessibilityFilterType::ALL);
- if (!tree_source_) {
- tree_source_.reset(new AXTreeSourceArc(tree_id()));
- focus_stealer_.reset(new FocusStealer(tree_source_->tree_id()));
- exo::WMHelper::GetInstance()->AddActivationObserver(this);
- }
- } else if (accessibility_manager &&
- accessibility_manager->IsFocusHighlightEnabled()) {
- instance->SetFilter(arc::mojom::AccessibilityFilterType::FOCUS);
- }
+ arc::mojom::AccessibilityFilterType filter_type = GetFilterType();
+ instance->SetFilter(filter_type);
+
+ if (filter_type == arc::mojom::AccessibilityFilterType::ALL ||
+ filter_type ==
+ arc::mojom::AccessibilityFilterType::WHITELISTED_PACKAGE_NAME)
+ exo::WMHelper::GetInstance()->AddActivationObserver(this);
}
void ArcAccessibilityHelperBridge::OnAccessibilityEventDeprecated(
@@ -115,8 +120,44 @@ void ArcAccessibilityHelperBridge::OnAccessibilityEventDeprecated(
void ArcAccessibilityHelperBridge::OnAccessibilityEvent(
mojom::AccessibilityEventDataPtr event_data) {
- if (tree_source_) {
- tree_source_->NotifyAccessibilityEvent(event_data.get());
+ arc::mojom::AccessibilityFilterType filter_type = GetFilterType();
+
+ if (filter_type == arc::mojom::AccessibilityFilterType::ALL ||
+ filter_type ==
+ arc::mojom::AccessibilityFilterType::WHITELISTED_PACKAGE_NAME) {
+ // Get the task id for this package.
+ if (event_data->nodeData.size()) {
dmazzoni 2017/04/25 16:09:24 nit: early-exit if the size is zero instead, to av
David Tseng 2017/04/25 22:48:03 Done.
+ arc::mojom::AccessibilityNodeInfoData* node =
+ event_data->nodeData[0].get();
+ if (!node->stringProperties)
+ return;
+
+ auto it = node->stringProperties->find(
+ arc::mojom::AccessibilityStringProperty::PACKAGE_NAME);
+ if (it == node->stringProperties->end())
+ return;
+
+ auto task_id_it = package_name_to_task_id_.find(it->second);
+ if (task_id_it == package_name_to_task_id_.end())
+ return;
+
+ int32_t task_id = task_id_it->second;
+
+ // Reject updates to non-current task ids. We can do this currently
+ // because all events include the entire tree.
+ if (task_id != current_task_id_)
+ return;
+
+ auto tree_it = task_id_to_tree_.find(task_id);
+ AXTreeSourceArc* tree_source;
+ if (tree_it == task_id_to_tree_.end()) {
+ tree_source = new AXTreeSourceArc(this);
+ task_id_to_tree_[task_id] = tree_source;
+ } else {
+ tree_source = tree_it->second;
+ }
+ tree_source->NotifyAccessibilityEvent(event_data.get());
+ }
return;
}
@@ -127,40 +168,7 @@ void ArcAccessibilityHelperBridge::OnAccessibilityEvent(
DispatchFocusChange(event_data.get()->nodeData[0].get());
}
-void ArcAccessibilityHelperBridge::OnWindowActivated(
- aura::Window* gained_active,
- aura::Window* lost_active) {
- if (gained_active == lost_active || !tree_source_)
- return;
-
- exo::Surface* active_surface = GetArcSurface(gained_active);
- exo::Surface* inactive_surface = GetArcSurface(lost_active);
-
- // Detach the accessibility tree from an inactive ShellSurface so that any
- // client walking the desktop tree gets non-duplicated linearization.
- if (inactive_surface) {
- views::Widget* widget = views::Widget::GetWidgetForNativeView(lost_active);
- if (widget && widget->GetContentsView()) {
- views::View* view = widget->GetContentsView();
- view->RemoveChildView(focus_stealer_.get());
- view->NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false);
- }
- }
-
- if (!active_surface)
- return;
-
- views::Widget* widget = views::Widget::GetWidgetForNativeView(gained_active);
- if (widget && widget->GetContentsView()) {
- views::View* view = widget->GetContentsView();
- if (!view->Contains(focus_stealer_.get()))
- view->AddChildView(focus_stealer_.get());
- focus_stealer_->RequestFocus();
- view->NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false);
- }
-}
-
-void ArcAccessibilityHelperBridge::PerformAction(const ui::AXActionData& data) {
+void ArcAccessibilityHelperBridge::OnAction(const ui::AXActionData& data) {
arc::mojom::AccessibilityActionType mojo_action;
switch (data.action) {
case ui::AX_ACTION_DO_DEFAULT:
@@ -175,4 +183,40 @@ void ArcAccessibilityHelperBridge::PerformAction(const ui::AXActionData& data) {
instance->PerformAction(data.target_node_id, mojo_action);
}
+void ArcAccessibilityHelperBridge::OnWindowActivated(
+ aura::Window* gained_active,
+ aura::Window* lost_active) {
+ if (gained_active == lost_active)
+ return;
+
+ if (!GetArcSurface(gained_active))
+ return;
+
+ // Grab the tree source associated with this app.
+ int32_t task_id = GetTaskId(gained_active);
+ auto it = task_id_to_tree_.find(task_id);
+ if (it != task_id_to_tree_.end())
+ it->second->Focus(gained_active);
+}
+
+void ArcAccessibilityHelperBridge::OnTaskCreated(
+ int task_id,
+ const std::string& package_name,
+ const std::string& activity,
+ const std::string& intent) {
+ package_name_to_task_id_[package_name] = task_id;
dmazzoni 2017/04/25 16:09:25 DCHECK that the package name doesn't already have
David Tseng 2017/04/25 22:48:03 It's possible for the package name / task id to be
+}
+
+void ArcAccessibilityHelperBridge::OnTaskDestroyed(int task_id) {
+ auto it = task_id_to_tree_.find(task_id);
+ if (it != task_id_to_tree_.end()) {
+ delete it->second;
+ task_id_to_tree_.erase(it);
+ }
+}
+
+void ArcAccessibilityHelperBridge::OnTaskSetActive(int32_t task_id) {
+ current_task_id_ = task_id;
+}
+
} // namespace arc

Powered by Google App Engine
This is Rietveld 408576698