OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "win8/test/ui_automation_client.h" | 5 #include "win8/test/ui_automation_client.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 <uiautomation.h> | 10 #include <uiautomation.h> |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Deletes the instance. | 34 // Deletes the instance. |
35 void DeleteOnAutomationThread(); | 35 void DeleteOnAutomationThread(); |
36 | 36 |
37 // Initializes the context, invoking |init_callback| via |client_runner| when | 37 // Initializes the context, invoking |init_callback| via |client_runner| when |
38 // done. On success, |result_callback| will eventually be called after the | 38 // done. On success, |result_callback| will eventually be called after the |
39 // window has been processed. On failure, this instance self-destructs after | 39 // window has been processed. On failure, this instance self-destructs after |
40 // posting |init_callback|. | 40 // posting |init_callback|. |
41 void Initialize( | 41 void Initialize( |
42 scoped_refptr<base::SingleThreadTaskRunner> client_runner, | 42 scoped_refptr<base::SingleThreadTaskRunner> client_runner, |
43 string16 class_name, | 43 base::string16 class_name, |
44 string16 item_name, | 44 base::string16 item_name, |
45 UIAutomationClient::InitializedCallback init_callback, | 45 UIAutomationClient::InitializedCallback init_callback, |
46 UIAutomationClient::ResultCallback result_callback); | 46 UIAutomationClient::ResultCallback result_callback); |
47 | 47 |
48 // Methods invoked by event handlers via weak pointers. | 48 // Methods invoked by event handlers via weak pointers. |
49 void HandleAutomationEvent( | 49 void HandleAutomationEvent( |
50 base::win::ScopedComPtr<IUIAutomationElement> sender, | 50 base::win::ScopedComPtr<IUIAutomationElement> sender, |
51 EVENTID eventId); | 51 EVENTID eventId); |
52 | 52 |
53 private: | 53 private: |
54 class EventHandler; | 54 class EventHandler; |
55 | 55 |
56 // The only and only method that may be called from outside of the automation | 56 // The only and only method that may be called from outside of the automation |
57 // thread. | 57 // thread. |
58 Context(); | 58 Context(); |
59 ~Context(); | 59 ~Context(); |
60 | 60 |
61 HRESULT InstallWindowObserver(); | 61 HRESULT InstallWindowObserver(); |
62 HRESULT RemoveWindowObserver(); | 62 HRESULT RemoveWindowObserver(); |
63 | 63 |
64 void HandleWindowOpen( | 64 void HandleWindowOpen( |
65 const base::win::ScopedComPtr<IUIAutomationElement>& window); | 65 const base::win::ScopedComPtr<IUIAutomationElement>& window); |
66 void ProcessWindow( | 66 void ProcessWindow( |
67 const base::win::ScopedComPtr<IUIAutomationElement>& window); | 67 const base::win::ScopedComPtr<IUIAutomationElement>& window); |
68 HRESULT InvokeDesiredItem( | 68 HRESULT InvokeDesiredItem( |
69 const base::win::ScopedComPtr<IUIAutomationElement>& element); | 69 const base::win::ScopedComPtr<IUIAutomationElement>& element); |
70 HRESULT GetInvokableItems( | 70 HRESULT GetInvokableItems( |
71 const base::win::ScopedComPtr<IUIAutomationElement>& element, | 71 const base::win::ScopedComPtr<IUIAutomationElement>& element, |
72 std::vector<string16>* choices); | 72 std::vector<base::string16>* choices); |
73 void CloseWindow(const base::win::ScopedComPtr<IUIAutomationElement>& window); | 73 void CloseWindow(const base::win::ScopedComPtr<IUIAutomationElement>& window); |
74 | 74 |
75 base::ThreadChecker thread_checker_; | 75 base::ThreadChecker thread_checker_; |
76 | 76 |
77 // The loop on which the client itself lives. | 77 // The loop on which the client itself lives. |
78 scoped_refptr<base::SingleThreadTaskRunner> client_runner_; | 78 scoped_refptr<base::SingleThreadTaskRunner> client_runner_; |
79 | 79 |
80 // The class name of the window for which the client waits. | 80 // The class name of the window for which the client waits. |
81 string16 class_name_; | 81 base::string16 class_name_; |
82 | 82 |
83 // The name of the item to invoke. | 83 // The name of the item to invoke. |
84 string16 item_name_; | 84 base::string16 item_name_; |
85 | 85 |
86 // The consumer's result callback. | 86 // The consumer's result callback. |
87 ResultCallback result_callback_; | 87 ResultCallback result_callback_; |
88 | 88 |
89 // The automation client. | 89 // The automation client. |
90 base::win::ScopedComPtr<IUIAutomation> automation_; | 90 base::win::ScopedComPtr<IUIAutomation> automation_; |
91 | 91 |
92 // A handler of Window open events. | 92 // A handler of Window open events. |
93 base::win::ScopedComPtr<IUIAutomationEventHandler> event_handler_; | 93 base::win::ScopedComPtr<IUIAutomationEventHandler> event_handler_; |
94 | 94 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 | 173 |
174 if (event_handler_.get()) { | 174 if (event_handler_.get()) { |
175 event_handler_ = NULL; | 175 event_handler_ = NULL; |
176 HRESULT result = automation_->RemoveAllEventHandlers(); | 176 HRESULT result = automation_->RemoveAllEventHandlers(); |
177 LOG_IF(ERROR, FAILED(result)) << std::hex << result; | 177 LOG_IF(ERROR, FAILED(result)) << std::hex << result; |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 void UIAutomationClient::Context::Initialize( | 181 void UIAutomationClient::Context::Initialize( |
182 scoped_refptr<base::SingleThreadTaskRunner> client_runner, | 182 scoped_refptr<base::SingleThreadTaskRunner> client_runner, |
183 string16 class_name, | 183 base::string16 class_name, |
184 string16 item_name, | 184 base::string16 item_name, |
185 UIAutomationClient::InitializedCallback init_callback, | 185 UIAutomationClient::InitializedCallback init_callback, |
186 UIAutomationClient::ResultCallback result_callback) { | 186 UIAutomationClient::ResultCallback result_callback) { |
187 // This and all other methods must be called on the automation thread. | 187 // This and all other methods must be called on the automation thread. |
188 DCHECK(!client_runner->BelongsToCurrentThread()); | 188 DCHECK(!client_runner->BelongsToCurrentThread()); |
189 // Bind the checker to this thread. | 189 // Bind the checker to this thread. |
190 thread_checker_.DetachFromThread(); | 190 thread_checker_.DetachFromThread(); |
191 DCHECK(thread_checker_.CalledOnValidThread()); | 191 DCHECK(thread_checker_.CalledOnValidThread()); |
192 | 192 |
193 client_runner_ = client_runner; | 193 client_runner_ = client_runner; |
194 class_name_ = class_name; | 194 class_name_ = class_name; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 if (FAILED(hr)) { | 318 if (FAILED(hr)) { |
319 LOG(ERROR) << std::hex << hr; | 319 LOG(ERROR) << std::hex << hr; |
320 return; | 320 return; |
321 } | 321 } |
322 | 322 |
323 if (V_VT(&var) != VT_BSTR) { | 323 if (V_VT(&var) != VT_BSTR) { |
324 LOG(ERROR) << __FUNCTION__ " class name is not a BSTR: " << V_VT(&var); | 324 LOG(ERROR) << __FUNCTION__ " class name is not a BSTR: " << V_VT(&var); |
325 return; | 325 return; |
326 } | 326 } |
327 | 327 |
328 string16 class_name(V_BSTR(&var)); | 328 base::string16 class_name(V_BSTR(&var)); |
329 | 329 |
330 // Window class names are atoms, which are case-insensitive. | 330 // Window class names are atoms, which are case-insensitive. |
331 if (class_name.size() == class_name_.size() && | 331 if (class_name.size() == class_name_.size() && |
332 std::equal(class_name.begin(), class_name.end(), class_name_.begin(), | 332 std::equal(class_name.begin(), class_name.end(), class_name_.begin(), |
333 base::CaseInsensitiveCompare<wchar_t>())) { | 333 base::CaseInsensitiveCompare<wchar_t>())) { |
334 RemoveWindowObserver(); | 334 RemoveWindowObserver(); |
335 ProcessWindow(window); | 335 ProcessWindow(window); |
336 } | 336 } |
337 } | 337 } |
338 | 338 |
339 // Processes |window| by invoking the desired child item. If the item cannot be | 339 // Processes |window| by invoking the desired child item. If the item cannot be |
340 // found or invoked, an attempt is made to get a list of all invokable children. | 340 // found or invoked, an attempt is made to get a list of all invokable children. |
341 // The results are posted back to the client on |client_runner_|, and this | 341 // The results are posted back to the client on |client_runner_|, and this |
342 // instance self-destructs. | 342 // instance self-destructs. |
343 void UIAutomationClient::Context::ProcessWindow( | 343 void UIAutomationClient::Context::ProcessWindow( |
344 const base::win::ScopedComPtr<IUIAutomationElement>& window) { | 344 const base::win::ScopedComPtr<IUIAutomationElement>& window) { |
345 DCHECK(thread_checker_.CalledOnValidThread()); | 345 DCHECK(thread_checker_.CalledOnValidThread()); |
346 | 346 |
347 HRESULT result = S_OK; | 347 HRESULT result = S_OK; |
348 std::vector<string16> choices; | 348 std::vector<base::string16> choices; |
349 result = InvokeDesiredItem(window); | 349 result = InvokeDesiredItem(window); |
350 if (FAILED(result)) { | 350 if (FAILED(result)) { |
351 GetInvokableItems(window, &choices); | 351 GetInvokableItems(window, &choices); |
352 CloseWindow(window); | 352 CloseWindow(window); |
353 } | 353 } |
354 | 354 |
355 client_runner_->PostTask(FROM_HERE, | 355 client_runner_->PostTask(FROM_HERE, |
356 base::Bind(result_callback_, result, choices)); | 356 base::Bind(result_callback_, result, choices)); |
357 | 357 |
358 // Self-destruct since there's nothing more to be done here. | 358 // Self-destruct since there's nothing more to be done here. |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 LOG(ERROR) << std::hex << result; | 450 LOG(ERROR) << std::hex << result; |
451 return result; | 451 return result; |
452 } | 452 } |
453 | 453 |
454 return S_OK; | 454 return S_OK; |
455 } | 455 } |
456 | 456 |
457 // Populates |choices| with the names of all invokable children of |element|. | 457 // Populates |choices| with the names of all invokable children of |element|. |
458 HRESULT UIAutomationClient::Context::GetInvokableItems( | 458 HRESULT UIAutomationClient::Context::GetInvokableItems( |
459 const base::win::ScopedComPtr<IUIAutomationElement>& element, | 459 const base::win::ScopedComPtr<IUIAutomationElement>& element, |
460 std::vector<string16>* choices) { | 460 std::vector<base::string16>* choices) { |
461 DCHECK(choices); | 461 DCHECK(choices); |
462 DCHECK(thread_checker_.CalledOnValidThread()); | 462 DCHECK(thread_checker_.CalledOnValidThread()); |
463 | 463 |
464 HRESULT result = S_OK; | 464 HRESULT result = S_OK; |
465 base::win::ScopedVariant var; | 465 base::win::ScopedVariant var; |
466 base::win::ScopedComPtr<IUIAutomationCondition> invokable_condition; | 466 base::win::ScopedComPtr<IUIAutomationCondition> invokable_condition; |
467 base::win::ScopedComPtr<IUIAutomationCondition> control_view_condition; | 467 base::win::ScopedComPtr<IUIAutomationCondition> control_view_condition; |
468 base::win::ScopedComPtr<IUIAutomationCondition> condition; | 468 base::win::ScopedComPtr<IUIAutomationCondition> condition; |
469 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; | 469 base::win::ScopedComPtr<IUIAutomationCacheRequest> cache_request; |
470 base::win::ScopedComPtr<IUIAutomationElementArray> element_array; | 470 base::win::ScopedComPtr<IUIAutomationElementArray> element_array; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 result = child_element->GetCachedPropertyValueEx(UIA_NamePropertyId, TRUE, | 538 result = child_element->GetCachedPropertyValueEx(UIA_NamePropertyId, TRUE, |
539 var.Receive()); | 539 var.Receive()); |
540 if (FAILED(result)) { | 540 if (FAILED(result)) { |
541 LOG(ERROR) << std::hex << result; | 541 LOG(ERROR) << std::hex << result; |
542 continue; | 542 continue; |
543 } | 543 } |
544 if (V_VT(&var) != VT_BSTR) { | 544 if (V_VT(&var) != VT_BSTR) { |
545 LOG(ERROR) << __FUNCTION__ " name is not a BSTR: " << V_VT(&var); | 545 LOG(ERROR) << __FUNCTION__ " name is not a BSTR: " << V_VT(&var); |
546 continue; | 546 continue; |
547 } | 547 } |
548 choices->push_back(string16(V_BSTR(&var))); | 548 choices->push_back(base::string16(V_BSTR(&var))); |
549 var.Reset(); | 549 var.Reset(); |
550 } | 550 } |
551 | 551 |
552 return result; | 552 return result; |
553 } | 553 } |
554 | 554 |
555 // Closes the element |window| by sending it an escape key. | 555 // Closes the element |window| by sending it an escape key. |
556 void UIAutomationClient::Context::CloseWindow( | 556 void UIAutomationClient::Context::CloseWindow( |
557 const base::win::ScopedComPtr<IUIAutomationElement>& window) { | 557 const base::win::ScopedComPtr<IUIAutomationElement>& window) { |
558 DCHECK(thread_checker_.CalledOnValidThread()); | 558 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 // context_ is still valid when the caller destroys the instance before the | 595 // context_ is still valid when the caller destroys the instance before the |
596 // callback(s) have fired. In this case, delete the context on the automation | 596 // callback(s) have fired. In this case, delete the context on the automation |
597 // thread before joining with it. | 597 // thread before joining with it. |
598 automation_thread_.message_loop()->PostTask( | 598 automation_thread_.message_loop()->PostTask( |
599 FROM_HERE, | 599 FROM_HERE, |
600 base::Bind(&UIAutomationClient::Context::DeleteOnAutomationThread, | 600 base::Bind(&UIAutomationClient::Context::DeleteOnAutomationThread, |
601 context_)); | 601 context_)); |
602 } | 602 } |
603 | 603 |
604 void UIAutomationClient::Begin(const wchar_t* class_name, | 604 void UIAutomationClient::Begin(const wchar_t* class_name, |
605 const string16& item_name, | 605 const base::string16& item_name, |
606 const InitializedCallback& init_callback, | 606 const InitializedCallback& init_callback, |
607 const ResultCallback& result_callback) { | 607 const ResultCallback& result_callback) { |
608 DCHECK(thread_checker_.CalledOnValidThread()); | 608 DCHECK(thread_checker_.CalledOnValidThread()); |
609 DCHECK_EQ(context_.get(), static_cast<Context*>(NULL)); | 609 DCHECK_EQ(context_.get(), static_cast<Context*>(NULL)); |
610 | 610 |
611 // Start the automation thread and initialize our automation client on it. | 611 // Start the automation thread and initialize our automation client on it. |
612 context_ = Context::Create(); | 612 context_ = Context::Create(); |
613 automation_thread_.init_com_with_mta(true); | 613 automation_thread_.init_com_with_mta(true); |
614 automation_thread_.Start(); | 614 automation_thread_.Start(); |
615 automation_thread_.message_loop()->PostTask( | 615 automation_thread_.message_loop()->PostTask( |
616 FROM_HERE, | 616 FROM_HERE, |
617 base::Bind(&UIAutomationClient::Context::Initialize, | 617 base::Bind(&UIAutomationClient::Context::Initialize, |
618 context_, | 618 context_, |
619 base::ThreadTaskRunnerHandle::Get(), | 619 base::ThreadTaskRunnerHandle::Get(), |
620 string16(class_name), | 620 base::string16(class_name), |
621 item_name, | 621 item_name, |
622 init_callback, | 622 init_callback, |
623 result_callback)); | 623 result_callback)); |
624 } | 624 } |
625 | 625 |
626 } // namespace internal | 626 } // namespace internal |
627 } // namespace win8 | 627 } // namespace win8 |
OLD | NEW |