| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/win/settings_app_monitor.h" | 5 #include "chrome/browser/win/settings_app_monitor.h" |
| 6 | 6 |
| 7 #include <atlbase.h> | 7 #include <atlbase.h> |
| 8 #include <atlcom.h> | 8 #include <atlcom.h> |
| 9 #include <oleauto.h> | 9 #include <oleauto.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 // Create a condition that will include only elements with the right class | 220 // Create a condition that will include only elements with the right class |
| 221 // name in the tree view. | 221 // name in the tree view. |
| 222 base::win::ScopedVariant class_name(L"Flyout"); | 222 base::win::ScopedVariant class_name(L"Flyout"); |
| 223 base::win::ScopedComPtr<IUIAutomationCondition> condition; | 223 base::win::ScopedComPtr<IUIAutomationCondition> condition; |
| 224 HRESULT result = automation->CreatePropertyCondition( | 224 HRESULT result = automation->CreatePropertyCondition( |
| 225 UIA_ClassNamePropertyId, class_name, condition.Receive()); | 225 UIA_ClassNamePropertyId, class_name, condition.Receive()); |
| 226 if (FAILED(result)) | 226 if (FAILED(result)) |
| 227 return base::string16(); | 227 return base::string16(); |
| 228 | 228 |
| 229 base::win::ScopedComPtr<IUIAutomationTreeWalker> tree_walker; | 229 base::win::ScopedComPtr<IUIAutomationTreeWalker> tree_walker; |
| 230 result = automation->CreateTreeWalker(condition.get(), tree_walker.Receive()); | 230 result = automation->CreateTreeWalker(condition.Get(), tree_walker.Receive()); |
| 231 if (FAILED(result)) | 231 if (FAILED(result)) |
| 232 return base::string16(); | 232 return base::string16(); |
| 233 | 233 |
| 234 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; | 234 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; |
| 235 result = automation->CreateCacheRequest(cache_request.Receive()); | 235 result = automation->CreateCacheRequest(cache_request.Receive()); |
| 236 if (FAILED(result)) | 236 if (FAILED(result)) |
| 237 return base::string16(); | 237 return base::string16(); |
| 238 ConfigureCacheRequest(cache_request.get()); | 238 ConfigureCacheRequest(cache_request.Get()); |
| 239 | 239 |
| 240 // From MSDN, NormalizeElementBuildCache() "Retrieves the ancestor element | 240 // From MSDN, NormalizeElementBuildCache() "Retrieves the ancestor element |
| 241 // nearest to the specified Microsoft UI Automation element in the tree view". | 241 // nearest to the specified Microsoft UI Automation element in the tree view". |
| 242 IUIAutomationElement* flyout_element = nullptr; | 242 IUIAutomationElement* flyout_element = nullptr; |
| 243 result = tree_walker->NormalizeElementBuildCache(element, cache_request.get(), | 243 result = tree_walker->NormalizeElementBuildCache(element, cache_request.Get(), |
| 244 &flyout_element); | 244 &flyout_element); |
| 245 if (FAILED(result) || !flyout_element) | 245 if (FAILED(result) || !flyout_element) |
| 246 return base::string16(); | 246 return base::string16(); |
| 247 | 247 |
| 248 return GetCachedBstrValue(flyout_element, UIA_AutomationIdPropertyId); | 248 return GetCachedBstrValue(flyout_element, UIA_AutomationIdPropertyId); |
| 249 } | 249 } |
| 250 | 250 |
| 251 ElementType DetectElementType(IUIAutomation* automation, | 251 ElementType DetectElementType(IUIAutomation* automation, |
| 252 IUIAutomationElement* sender) { | 252 IUIAutomationElement* sender) { |
| 253 DCHECK(automation); | 253 DCHECK(automation); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 << ", is peripheral: " | 553 << ", is peripheral: " |
| 554 << GetCachedBoolValue(sender, UIA_IsPeripheralPropertyId) | 554 << GetCachedBoolValue(sender, UIA_IsPeripheralPropertyId) |
| 555 << ", class name: " | 555 << ", class name: " |
| 556 << GetCachedBstrValue(sender, UIA_ClassNamePropertyId) | 556 << GetCachedBstrValue(sender, UIA_ClassNamePropertyId) |
| 557 << ", pid: " << GetCachedInt32Value(sender, UIA_ProcessIdPropertyId) | 557 << ", pid: " << GetCachedInt32Value(sender, UIA_ProcessIdPropertyId) |
| 558 << ", value: " | 558 << ", value: " |
| 559 << GetCachedBstrValue(sender, UIA_ValueValuePropertyId) | 559 << GetCachedBstrValue(sender, UIA_ValueValuePropertyId) |
| 560 << ", runtime id: " << IntArrayToString(GetCachedInt32ArrayValue( | 560 << ", runtime id: " << IntArrayToString(GetCachedInt32ArrayValue( |
| 561 sender, UIA_RuntimeIdPropertyId)); | 561 sender, UIA_RuntimeIdPropertyId)); |
| 562 | 562 |
| 563 switch (DetectElementType(automation_.get(), sender)) { | 563 switch (DetectElementType(automation_.Get(), sender)) { |
| 564 case ElementType::DEFAULT_BROWSER: | 564 case ElementType::DEFAULT_BROWSER: |
| 565 context_runner_->PostTask( | 565 context_runner_->PostTask( |
| 566 FROM_HERE, | 566 FROM_HERE, |
| 567 base::Bind(&SettingsAppMonitor::Context::HandleChooserInvoked, | 567 base::Bind(&SettingsAppMonitor::Context::HandleChooserInvoked, |
| 568 context_)); | 568 context_)); |
| 569 break; | 569 break; |
| 570 case ElementType::BROWSER_BUTTON: { | 570 case ElementType::BROWSER_BUTTON: { |
| 571 base::string16 browser_name( | 571 base::string16 browser_name( |
| 572 GetCachedBstrValue(sender, UIA_NamePropertyId)); | 572 GetCachedBstrValue(sender, UIA_NamePropertyId)); |
| 573 if (!browser_name.empty()) { | 573 if (!browser_name.empty()) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 event_handler_.Reset(); | 672 event_handler_.Reset(); |
| 673 automation_->RemoveAllEventHandlers(); | 673 automation_->RemoveAllEventHandlers(); |
| 674 } | 674 } |
| 675 } | 675 } |
| 676 | 676 |
| 677 void SettingsAppMonitor::Context::HandleFocusChangedEvent( | 677 void SettingsAppMonitor::Context::HandleFocusChangedEvent( |
| 678 base::win::ScopedComPtr<IUIAutomationElement> sender) { | 678 base::win::ScopedComPtr<IUIAutomationElement> sender) { |
| 679 DCHECK(task_runner_->BelongsToCurrentThread()); | 679 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 680 | 680 |
| 681 // Duplicate focus changed events are suppressed. | 681 // Duplicate focus changed events are suppressed. |
| 682 ElementType element_type = DetectElementType(automation_.get(), sender.get()); | 682 ElementType element_type = DetectElementType(automation_.Get(), sender.Get()); |
| 683 if (last_focused_element_ == element_type) | 683 if (last_focused_element_ == element_type) |
| 684 return; | 684 return; |
| 685 last_focused_element_ = element_type; | 685 last_focused_element_ = element_type; |
| 686 | 686 |
| 687 if (element_type == ElementType::DEFAULT_BROWSER) { | 687 if (element_type == ElementType::DEFAULT_BROWSER) { |
| 688 monitor_runner_->PostTask( | 688 monitor_runner_->PostTask( |
| 689 FROM_HERE, base::Bind(&SettingsAppMonitor::OnAppFocused, monitor_)); | 689 FROM_HERE, base::Bind(&SettingsAppMonitor::OnAppFocused, monitor_)); |
| 690 } else if (element_type == ElementType::CHECK_IT_OUT) { | 690 } else if (element_type == ElementType::CHECK_IT_OUT) { |
| 691 monitor_runner_->PostTask( | 691 monitor_runner_->PostTask( |
| 692 FROM_HERE, base::Bind(&SettingsAppMonitor::OnPromoFocused, monitor_)); | 692 FROM_HERE, base::Bind(&SettingsAppMonitor::OnPromoFocused, monitor_)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 obj->QueryInterface(event_handler_.Receive()); | 726 obj->QueryInterface(event_handler_.Receive()); |
| 727 } | 727 } |
| 728 } | 728 } |
| 729 return event_handler_; | 729 return event_handler_; |
| 730 } | 730 } |
| 731 | 731 |
| 732 base::win::ScopedComPtr<IUIAutomationEventHandler> | 732 base::win::ScopedComPtr<IUIAutomationEventHandler> |
| 733 SettingsAppMonitor::Context::GetAutomationEventHandler() { | 733 SettingsAppMonitor::Context::GetAutomationEventHandler() { |
| 734 DCHECK(task_runner_->BelongsToCurrentThread()); | 734 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 735 base::win::ScopedComPtr<IUIAutomationEventHandler> handler; | 735 base::win::ScopedComPtr<IUIAutomationEventHandler> handler; |
| 736 handler.QueryFrom(GetEventHandler().get()); | 736 handler.QueryFrom(GetEventHandler().Get()); |
| 737 return handler; | 737 return handler; |
| 738 } | 738 } |
| 739 | 739 |
| 740 base::win::ScopedComPtr<IUIAutomationFocusChangedEventHandler> | 740 base::win::ScopedComPtr<IUIAutomationFocusChangedEventHandler> |
| 741 SettingsAppMonitor::Context::GetFocusChangedEventHandler() { | 741 SettingsAppMonitor::Context::GetFocusChangedEventHandler() { |
| 742 DCHECK(task_runner_->BelongsToCurrentThread()); | 742 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 743 base::win::ScopedComPtr<IUIAutomationFocusChangedEventHandler> handler; | 743 base::win::ScopedComPtr<IUIAutomationFocusChangedEventHandler> handler; |
| 744 handler.QueryFrom(GetEventHandler().get()); | 744 handler.QueryFrom(GetEventHandler().Get()); |
| 745 return handler; | 745 return handler; |
| 746 } | 746 } |
| 747 | 747 |
| 748 HRESULT SettingsAppMonitor::Context::InstallObservers() { | 748 HRESULT SettingsAppMonitor::Context::InstallObservers() { |
| 749 DCHECK(task_runner_->BelongsToCurrentThread()); | 749 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 750 DCHECK(automation_); | 750 DCHECK(automation_); |
| 751 | 751 |
| 752 // Create a cache request so that elements received by way of events contain | 752 // Create a cache request so that elements received by way of events contain |
| 753 // all data needed for procesing. | 753 // all data needed for procesing. |
| 754 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; | 754 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; |
| 755 HRESULT result = automation_->CreateCacheRequest(cache_request.Receive()); | 755 HRESULT result = automation_->CreateCacheRequest(cache_request.Receive()); |
| 756 if (FAILED(result)) | 756 if (FAILED(result)) |
| 757 return result; | 757 return result; |
| 758 ConfigureCacheRequest(cache_request.get()); | 758 ConfigureCacheRequest(cache_request.Get()); |
| 759 | 759 |
| 760 // Observe changes in focus. | 760 // Observe changes in focus. |
| 761 result = automation_->AddFocusChangedEventHandler( | 761 result = automation_->AddFocusChangedEventHandler( |
| 762 cache_request.get(), GetFocusChangedEventHandler().get()); | 762 cache_request.Get(), GetFocusChangedEventHandler().Get()); |
| 763 if (FAILED(result)) | 763 if (FAILED(result)) |
| 764 return result; | 764 return result; |
| 765 | 765 |
| 766 // Observe invocations. | 766 // Observe invocations. |
| 767 base::win::ScopedComPtr<IUIAutomationElement> desktop; | 767 base::win::ScopedComPtr<IUIAutomationElement> desktop; |
| 768 result = automation_->GetRootElement(desktop.Receive()); | 768 result = automation_->GetRootElement(desktop.Receive()); |
| 769 if (desktop) { | 769 if (desktop) { |
| 770 result = automation_->AddAutomationEventHandler( | 770 result = automation_->AddAutomationEventHandler( |
| 771 UIA_Invoke_InvokedEventId, desktop.get(), TreeScope_Subtree, | 771 UIA_Invoke_InvokedEventId, desktop.Get(), TreeScope_Subtree, |
| 772 cache_request.get(), GetAutomationEventHandler().get()); | 772 cache_request.Get(), GetAutomationEventHandler().Get()); |
| 773 } | 773 } |
| 774 | 774 |
| 775 return result; | 775 return result; |
| 776 } | 776 } |
| 777 | 777 |
| 778 | 778 |
| 779 // SettingsAppMonitor ---------------------------------------------------------- | 779 // SettingsAppMonitor ---------------------------------------------------------- |
| 780 | 780 |
| 781 SettingsAppMonitor::SettingsAppMonitor(Delegate* delegate) | 781 SettingsAppMonitor::SettingsAppMonitor(Delegate* delegate) |
| 782 : delegate_(delegate), | 782 : delegate_(delegate), |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 833 delegate_->OnPromoFocused(); | 833 delegate_->OnPromoFocused(); |
| 834 } | 834 } |
| 835 | 835 |
| 836 void SettingsAppMonitor::OnPromoChoiceMade(bool accept_promo) { | 836 void SettingsAppMonitor::OnPromoChoiceMade(bool accept_promo) { |
| 837 DCHECK(thread_checker_.CalledOnValidThread()); | 837 DCHECK(thread_checker_.CalledOnValidThread()); |
| 838 delegate_->OnPromoChoiceMade(accept_promo); | 838 delegate_->OnPromoChoiceMade(accept_promo); |
| 839 } | 839 } |
| 840 | 840 |
| 841 } // namespace win | 841 } // namespace win |
| 842 } // namespace shell_integration | 842 } // namespace shell_integration |
| OLD | NEW |