10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file. 40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/ash/accessibility/automation_manager_ash.h" 60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <vector> 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/singleton.h" 100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/browser_process.h" 110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/extensions/api/automation_internal/automation_util.h" 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/profiles/profile_manager.h" 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/public/browser/ax_event_notification_details.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/browser_context.h" 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/accessibility/ax_aura_obj_cache.h" 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/views/accessibility/ax_aura_obj_wrapper.h" 170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/views/view.h" 180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/views/widget/widget.h" 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using content::BrowserContext; 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AutomationManagerAsh* AutomationManagerAsh::GetInstance() { 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return Singleton<AutomationManagerAsh>::get(); 250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::Enable(BrowserContext* context) { 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu enabled_ = true; 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Reset(); 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendEvent(context, current_tree_->GetRoot(), ui::AX_EVENT_LOAD_COMPLETE); 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::Disable() { 345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu enabled_ = false; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Reset the serializer to save memory. 375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu current_tree_serializer_->Reset(); 385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::HandleEvent(BrowserContext* context, 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch views::View* view, 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ui::AXEvent event_type) { 435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!enabled_) { 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(dtseng): Events should only be delivered to extensions with the 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // desktop permission. 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch views::Widget* widget = view->GetWidget(); 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!widget) 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!context && g_browser_process->profile_manager()) { 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) context = g_browser_process->profile_manager()->GetLastUsedProfile(); 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!context) { 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) LOG(WARNING) << "Accessibility notification but no browser context"; 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::AXAuraObjWrapper* aura_obj = 625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu views::AXAuraObjCache::GetInstance()->GetOrCreate(view); 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) SendEvent(context, aura_obj, event_type); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::DoDefault(int32 id) { 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(enabled_); 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_tree_->DoDefault(id); 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::Focus(int32 id) { 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(enabled_); 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_tree_->Focus(id); 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::MakeVisible(int32 id) { 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(enabled_); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_tree_->MakeVisible(id); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::SetSelection(int32 id, int32 start, int32 end) { 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CHECK(enabled_); 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_tree_->SetSelection(id, start, end); 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AutomationManagerAsh::AutomationManagerAsh() : enabled_(false) {} 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)AutomationManagerAsh::~AutomationManagerAsh() {} 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::Reset() { 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) current_tree_.reset(new AXTreeSourceAsh()); 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_tree_serializer_.reset( 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new ui::AXTreeSerializer<views::AXAuraObjWrapper*>( 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_tree_.get())); 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void AutomationManagerAsh::SendEvent(BrowserContext* context, 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) views::AXAuraObjWrapper* aura_obj, 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::AXEvent event_type) { 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::AXTreeUpdate update; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) current_tree_serializer_->SerializeChanges(aura_obj, &update); 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Route this event to special process/routing ids recognized by the 1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Automation API as the desktop tree. 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(dtseng): Would idealy define these special desktop constants in idl. 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::AXEventNotificationDetails detail(update.node_id_to_clear, 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch update.nodes, 1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch event_type, 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu aura_obj->GetID(), 1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 0, /* process_id */ 1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 0 /* routing_id */); 1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::vector<content::AXEventNotificationDetails> details; 1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch details.push_back(detail); 1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch extensions::automation_util::DispatchAccessibilityEventsToAutomation( 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci details, context, gfx::Vector2d()); 1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 117