Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/automation/testing_automation_provider.h" | 5 #include "chrome/browser/automation/testing_automation_provider.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2135 handler_map["CloseTab"] = | 2135 handler_map["CloseTab"] = |
| 2136 &TestingAutomationProvider::CloseTabJSON; | 2136 &TestingAutomationProvider::CloseTabJSON; |
| 2137 handler_map["WebkitMouseMove"] = | 2137 handler_map["WebkitMouseMove"] = |
| 2138 &TestingAutomationProvider::WebkitMouseMove; | 2138 &TestingAutomationProvider::WebkitMouseMove; |
| 2139 handler_map["WebkitMouseClick"] = | 2139 handler_map["WebkitMouseClick"] = |
| 2140 &TestingAutomationProvider::WebkitMouseClick; | 2140 &TestingAutomationProvider::WebkitMouseClick; |
| 2141 handler_map["WebkitMouseDrag"] = | 2141 handler_map["WebkitMouseDrag"] = |
| 2142 &TestingAutomationProvider::WebkitMouseDrag; | 2142 &TestingAutomationProvider::WebkitMouseDrag; |
| 2143 handler_map["SendWebkitKeyEvent"] = | 2143 handler_map["SendWebkitKeyEvent"] = |
| 2144 &TestingAutomationProvider::SendWebkitKeyEvent; | 2144 &TestingAutomationProvider::SendWebkitKeyEvent; |
| 2145 handler_map["SendOSLevelKeyEvent"] = | |
| 2146 &TestingAutomationProvider::SendOSLevelKeyEvent; | |
| 2145 handler_map["ActivateTab"] = | 2147 handler_map["ActivateTab"] = |
| 2146 &TestingAutomationProvider::ActivateTabJSON; | 2148 &TestingAutomationProvider::ActivateTabJSON; |
| 2147 #if defined(OS_CHROMEOS) | 2149 #if defined(OS_CHROMEOS) |
| 2148 handler_map["LoginAsGuest"] = &TestingAutomationProvider::LoginAsGuest; | 2150 handler_map["LoginAsGuest"] = &TestingAutomationProvider::LoginAsGuest; |
| 2149 handler_map["Login"] = &TestingAutomationProvider::Login; | 2151 handler_map["Login"] = &TestingAutomationProvider::Login; |
| 2150 handler_map["Logout"] = &TestingAutomationProvider::Logout; | 2152 handler_map["Logout"] = &TestingAutomationProvider::Logout; |
| 2151 handler_map["ScreenLock"] = &TestingAutomationProvider::ScreenLock; | 2153 handler_map["ScreenLock"] = &TestingAutomationProvider::ScreenLock; |
| 2152 handler_map["ScreenUnlock"] = &TestingAutomationProvider::ScreenUnlock; | 2154 handler_map["ScreenUnlock"] = &TestingAutomationProvider::ScreenUnlock; |
| 2153 | 2155 |
| 2154 handler_map["GetNetworkInfo"] = &TestingAutomationProvider::GetNetworkInfo; | 2156 handler_map["GetNetworkInfo"] = &TestingAutomationProvider::GetNetworkInfo; |
| (...skipping 2425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4580 if (!base::OpenProcessHandle(static_cast<base::ProcessId>(pid), &process)) { | 4582 if (!base::OpenProcessHandle(static_cast<base::ProcessId>(pid), &process)) { |
| 4581 AutomationJSONReply(this, reply_message).SendError(base::StringPrintf( | 4583 AutomationJSONReply(this, reply_message).SendError(base::StringPrintf( |
| 4582 "Failed to open process handle for pid %d", pid)); | 4584 "Failed to open process handle for pid %d", pid)); |
| 4583 return; | 4585 return; |
| 4584 } | 4586 } |
| 4585 new RendererProcessClosedObserver(this, reply_message); | 4587 new RendererProcessClosedObserver(this, reply_message); |
| 4586 base::KillProcess(process, 0, false); | 4588 base::KillProcess(process, 0, false); |
| 4587 base::CloseProcessHandle(process); | 4589 base::CloseProcessHandle(process); |
| 4588 } | 4590 } |
| 4589 | 4591 |
| 4592 bool TestingAutomationProvider::BuildNativeWebKeyEventFromArgs( | |
| 4593 DictionaryValue* args, | |
| 4594 IPC::Message* reply_message, | |
| 4595 NativeWebKeyboardEvent* event) { | |
| 4596 int type, modifiers; | |
| 4597 string16 unmodified_text, text; | |
| 4598 std::string key_identifier; | |
| 4599 if (!args->GetInteger("type", &type)) { | |
| 4600 AutomationJSONReply(this, reply_message) | |
| 4601 .SendError("'type' missing or invalid."); | |
| 4602 return false; | |
| 4603 } | |
| 4604 if (!args->GetInteger("nativeKeyCode", &event->nativeKeyCode)) { | |
| 4605 AutomationJSONReply(this, reply_message) | |
| 4606 .SendError("'nativeKeyCode' missing or invalid."); | |
| 4607 return false; | |
| 4608 } | |
| 4609 if (!args->GetInteger("windowsKeyCode", &event->windowsKeyCode)) { | |
| 4610 AutomationJSONReply(this, reply_message) | |
| 4611 .SendError("'windowsKeyCode' missing or invalid."); | |
| 4612 return false; | |
| 4613 } | |
| 4614 if (!args->GetInteger("modifiers", &modifiers)) { | |
| 4615 AutomationJSONReply(this, reply_message) | |
| 4616 .SendError("'modifiers' missing or invalid."); | |
| 4617 return false; | |
| 4618 } | |
| 4619 | |
| 4620 if (type == automation::kRawKeyDownType) { | |
| 4621 event->type = WebKit::WebInputEvent::RawKeyDown; | |
| 4622 } else if (type == automation::kKeyDownType) { | |
| 4623 event->type = WebKit::WebInputEvent::KeyDown; | |
| 4624 } else if (type == automation::kKeyUpType) { | |
| 4625 event->type = WebKit::WebInputEvent::KeyUp; | |
| 4626 } else if (type == automation::kCharType) { | |
| 4627 event->type = WebKit::WebInputEvent::Char; | |
| 4628 } else { | |
| 4629 AutomationJSONReply(this, reply_message) | |
| 4630 .SendError("'type' refers to an unrecognized keyboard event type"); | |
| 4631 return false; | |
| 4632 } | |
| 4633 | |
| 4634 event->modifiers = 0; | |
| 4635 if (modifiers & automation::kShiftKeyMask) | |
| 4636 event->modifiers |= WebKit::WebInputEvent::ShiftKey; | |
| 4637 if (modifiers & automation::kControlKeyMask) | |
| 4638 event->modifiers |= WebKit::WebInputEvent::ControlKey; | |
| 4639 if (modifiers & automation::kAltKeyMask) | |
| 4640 event->modifiers |= WebKit::WebInputEvent::AltKey; | |
| 4641 if (modifiers & automation::kMetaKeyMask) | |
| 4642 event->modifiers |= WebKit::WebInputEvent::MetaKey; | |
| 4643 | |
| 4644 event->isSystemKey = false; | |
| 4645 event->timeStampSeconds = base::Time::Now().ToDoubleT(); | |
| 4646 event->skip_in_browser = true; | |
| 4647 return true; | |
| 4648 } | |
| 4649 | |
| 4650 bool TestingAutomationProvider::BuildWebKeyEventFromArgs( | |
| 4651 DictionaryValue* args, | |
| 4652 IPC::Message* reply_message, | |
| 4653 NativeWebKeyboardEvent* event) { | |
| 4654 | |
| 4655 int type, modifiers; | |
| 4656 bool is_system_key; | |
| 4657 string16 unmodified_text, text; | |
| 4658 std::string key_identifier; | |
| 4659 if (!args->GetInteger("type", &type)) { | |
| 4660 AutomationJSONReply(this, reply_message) | |
| 4661 .SendError("'type' missing or invalid."); | |
| 4662 return false; | |
| 4663 } | |
| 4664 if (!args->GetBoolean("isSystemKey", &is_system_key)) { | |
| 4665 AutomationJSONReply(this, reply_message) | |
| 4666 .SendError("'isSystemKey' missing or invalid."); | |
| 4667 return false; | |
| 4668 } | |
| 4669 if (!args->GetString("unmodifiedText", &unmodified_text)) { | |
| 4670 AutomationJSONReply(this, reply_message) | |
| 4671 .SendError("'unmodifiedText' missing or invalid."); | |
| 4672 return false; | |
| 4673 } | |
| 4674 if (!args->GetString("text", &text)) { | |
| 4675 AutomationJSONReply(this, reply_message) | |
| 4676 .SendError("'text' missing or invalid."); | |
| 4677 return false; | |
| 4678 } | |
| 4679 if (!args->GetInteger("nativeKeyCode", &event->nativeKeyCode)) { | |
| 4680 AutomationJSONReply(this, reply_message) | |
| 4681 .SendError("'nativeKeyCode' missing or invalid."); | |
| 4682 return false; | |
| 4683 } | |
| 4684 if (!args->GetInteger("windowsKeyCode", &event->windowsKeyCode)) { | |
| 4685 AutomationJSONReply(this, reply_message) | |
| 4686 .SendError("'windowsKeyCode' missing or invalid."); | |
| 4687 return false; | |
| 4688 } | |
| 4689 if (!args->GetInteger("modifiers", &modifiers)) { | |
| 4690 AutomationJSONReply(this, reply_message) | |
| 4691 .SendError("'modifiers' missing or invalid."); | |
| 4692 return false; | |
| 4693 } | |
| 4694 if (args->GetString("keyIdentifier", &key_identifier)) { | |
| 4695 base::strlcpy(event->keyIdentifier, | |
| 4696 key_identifier.c_str(), | |
| 4697 WebKit::WebKeyboardEvent::keyIdentifierLengthCap); | |
| 4698 } else { | |
| 4699 event->setKeyIdentifierFromWindowsKeyCode(); | |
| 4700 } | |
| 4701 | |
| 4702 if (type == automation::kRawKeyDownType) { | |
| 4703 event->type = WebKit::WebInputEvent::RawKeyDown; | |
| 4704 } else if (type == automation::kKeyDownType) { | |
| 4705 event->type = WebKit::WebInputEvent::KeyDown; | |
| 4706 } else if (type == automation::kKeyUpType) { | |
| 4707 event->type = WebKit::WebInputEvent::KeyUp; | |
| 4708 } else if (type == automation::kCharType) { | |
| 4709 event->type = WebKit::WebInputEvent::Char; | |
| 4710 } else { | |
| 4711 AutomationJSONReply(this, reply_message) | |
| 4712 .SendError("'type' refers to an unrecognized keyboard event type"); | |
| 4713 return false; | |
| 4714 } | |
| 4715 | |
| 4716 string16 unmodified_text_truncated = unmodified_text.substr( | |
| 4717 0, WebKit::WebKeyboardEvent::textLengthCap - 1); | |
| 4718 memcpy(event->unmodifiedText, | |
| 4719 unmodified_text_truncated.c_str(), | |
| 4720 unmodified_text_truncated.length() + 1); | |
| 4721 string16 text_truncated = text.substr( | |
| 4722 0, WebKit::WebKeyboardEvent::textLengthCap - 1); | |
| 4723 memcpy(event->text, text_truncated.c_str(), text_truncated.length() + 1); | |
| 4724 | |
| 4725 event->modifiers = 0; | |
| 4726 if (modifiers & automation::kShiftKeyMask) | |
| 4727 event->modifiers |= WebKit::WebInputEvent::ShiftKey; | |
| 4728 if (modifiers & automation::kControlKeyMask) | |
| 4729 event->modifiers |= WebKit::WebInputEvent::ControlKey; | |
| 4730 if (modifiers & automation::kAltKeyMask) | |
| 4731 event->modifiers |= WebKit::WebInputEvent::AltKey; | |
| 4732 if (modifiers & automation::kMetaKeyMask) | |
| 4733 event->modifiers |= WebKit::WebInputEvent::MetaKey; | |
| 4734 | |
| 4735 event->isSystemKey = is_system_key; | |
| 4736 event->timeStampSeconds = base::Time::Now().ToDoubleT(); | |
| 4737 event->skip_in_browser = true; | |
| 4738 return true; | |
| 4739 } | |
| 4740 | |
| 4590 void TestingAutomationProvider::SendWebkitKeyEvent( | 4741 void TestingAutomationProvider::SendWebkitKeyEvent( |
| 4591 DictionaryValue* args, | 4742 DictionaryValue* args, |
| 4592 IPC::Message* reply_message) { | 4743 IPC::Message* reply_message) { |
| 4744 NativeWebKeyboardEvent event; | |
| 4745 // BuildWebKeyEventFromArgs handles telling what when wrong and sending | |
| 4746 // the reply message, if it failed we just have to stop here. | |
| 4747 if (!BuildWebKeyEventFromArgs(args, reply_message, &event)) | |
| 4748 return; | |
| 4749 | |
| 4593 TabContents* tab_contents; | 4750 TabContents* tab_contents; |
| 4594 std::string error; | 4751 std::string error; |
| 4595 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) { | 4752 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) { |
| 4596 AutomationJSONReply(this, reply_message).SendError(error); | 4753 AutomationJSONReply(this, reply_message).SendError(error); |
| 4597 return; | 4754 return; |
| 4598 } | 4755 } |
| 4599 | 4756 LOG(INFO) << "reply_message:" << reply_message; |
| 4600 int type, modifiers; | |
| 4601 bool is_system_key; | |
| 4602 string16 unmodified_text, text; | |
| 4603 std::string key_identifier; | |
| 4604 NativeWebKeyboardEvent event; | |
| 4605 if (!args->GetInteger("type", &type)) { | |
| 4606 AutomationJSONReply reply(this, reply_message); | |
| 4607 reply.SendError("'type' missing or invalid."); | |
| 4608 return; | |
| 4609 } | |
| 4610 if (!args->GetBoolean("isSystemKey", &is_system_key)) { | |
| 4611 AutomationJSONReply reply(this, reply_message); | |
| 4612 reply.SendError("'isSystemKey' missing or invalid."); | |
| 4613 return; | |
| 4614 } | |
| 4615 if (!args->GetString("unmodifiedText", &unmodified_text)) { | |
| 4616 AutomationJSONReply reply(this, reply_message); | |
| 4617 reply.SendError("'unmodifiedText' missing or invalid."); | |
| 4618 return; | |
| 4619 } | |
| 4620 if (!args->GetString("text", &text)) { | |
| 4621 AutomationJSONReply reply(this, reply_message); | |
| 4622 reply.SendError("'text' missing or invalid."); | |
| 4623 return; | |
| 4624 } | |
| 4625 if (!args->GetInteger("nativeKeyCode", &event.nativeKeyCode)) { | |
| 4626 AutomationJSONReply reply(this, reply_message); | |
| 4627 reply.SendError("'nativeKeyCode' missing or invalid."); | |
| 4628 return; | |
| 4629 } | |
| 4630 if (!args->GetInteger("windowsKeyCode", &event.windowsKeyCode)) { | |
| 4631 AutomationJSONReply reply(this, reply_message); | |
| 4632 reply.SendError("'windowsKeyCode' missing or invalid."); | |
| 4633 return; | |
| 4634 } | |
| 4635 if (!args->GetInteger("modifiers", &modifiers)) { | |
| 4636 AutomationJSONReply reply(this, reply_message); | |
| 4637 reply.SendError("'modifiers' missing or invalid."); | |
| 4638 return; | |
| 4639 } | |
| 4640 if (args->GetString("keyIdentifier", &key_identifier)) { | |
| 4641 base::strlcpy(event.keyIdentifier, | |
| 4642 key_identifier.c_str(), | |
| 4643 WebKit::WebKeyboardEvent::keyIdentifierLengthCap); | |
| 4644 } else { | |
| 4645 event.setKeyIdentifierFromWindowsKeyCode(); | |
| 4646 } | |
| 4647 | |
| 4648 if (type == automation::kRawKeyDownType) { | |
| 4649 event.type = WebKit::WebInputEvent::RawKeyDown; | |
| 4650 } else if (type == automation::kKeyDownType) { | |
| 4651 event.type = WebKit::WebInputEvent::KeyDown; | |
| 4652 } else if (type == automation::kKeyUpType) { | |
| 4653 event.type = WebKit::WebInputEvent::KeyUp; | |
| 4654 } else if (type == automation::kCharType) { | |
| 4655 event.type = WebKit::WebInputEvent::Char; | |
| 4656 } else { | |
| 4657 AutomationJSONReply reply(this, reply_message); | |
| 4658 reply.SendError("'type' refers to an unrecognized keyboard event type"); | |
| 4659 return; | |
| 4660 } | |
| 4661 | |
| 4662 string16 unmodified_text_truncated = unmodified_text.substr( | |
| 4663 0, WebKit::WebKeyboardEvent::textLengthCap - 1); | |
| 4664 memcpy(event.unmodifiedText, | |
| 4665 unmodified_text_truncated.c_str(), | |
| 4666 unmodified_text_truncated.length() + 1); | |
| 4667 string16 text_truncated = text.substr( | |
| 4668 0, WebKit::WebKeyboardEvent::textLengthCap - 1); | |
| 4669 memcpy(event.text, text_truncated.c_str(), text_truncated.length() + 1); | |
| 4670 | |
| 4671 event.modifiers = 0; | |
| 4672 if (modifiers & automation::kShiftKeyMask) | |
| 4673 event.modifiers |= WebKit::WebInputEvent::ShiftKey; | |
| 4674 if (modifiers & automation::kControlKeyMask) | |
| 4675 event.modifiers |= WebKit::WebInputEvent::ControlKey; | |
| 4676 if (modifiers & automation::kAltKeyMask) | |
| 4677 event.modifiers |= WebKit::WebInputEvent::AltKey; | |
| 4678 if (modifiers & automation::kMetaKeyMask) | |
| 4679 event.modifiers |= WebKit::WebInputEvent::MetaKey; | |
| 4680 | |
| 4681 event.isSystemKey = is_system_key; | |
| 4682 event.timeStampSeconds = base::Time::Now().ToDoubleT(); | |
| 4683 event.skip_in_browser = true; | |
| 4684 new InputEventAckNotificationObserver(this, reply_message, event.type); | 4757 new InputEventAckNotificationObserver(this, reply_message, event.type); |
| 4685 tab_contents->render_view_host()->ForwardKeyboardEvent(event); | 4758 tab_contents->render_view_host()->ForwardKeyboardEvent(event); |
| 4686 } | 4759 } |
| 4687 | 4760 |
| 4761 void TestingAutomationProvider::SendOSLevelKeyEvent( | |
| 4762 DictionaryValue* args, | |
| 4763 IPC::Message* reply_message) { | |
| 4764 NativeWebKeyboardEvent event; | |
| 4765 // BuildNativeWebKeyEventFromArgs handles telling what when wrong and sending | |
| 4766 // the reply message, if it failed we just have to stop here. | |
| 4767 if (!BuildNativeWebKeyEventFromArgs(args, reply_message, &event)) | |
|
kkania
2011/03/10 17:00:47
it seems a bit strange to me how we are building a
timothe faudot
2011/03/11 03:32:08
Done.
| |
| 4768 return; | |
| 4769 | |
| 4770 Browser* browser; | |
| 4771 std::string error; | |
| 4772 if (!GetBrowserFromJSONArgs(args, &browser, &error)) { | |
| 4773 AutomationJSONReply(this, reply_message) | |
|
kkania
2011/03/10 17:00:47
Since you send a reply synchronously in this func,
timothe faudot
2011/03/11 03:32:08
Done.
| |
| 4774 .SendError("Could not get the browser handle"); | |
|
kkania
2011/03/10 17:00:47
you can just .SendError(error) here
timothe faudot
2011/03/11 03:32:08
Done.
| |
| 4775 return; | |
| 4776 } | |
| 4777 // The ui_controls::SendKeyPress function will generate up and down events | |
|
kkania
2011/03/10 17:00:47
instead of having a strange interface where we don
timothe faudot
2011/03/11 03:32:08
Done.
| |
| 4778 // from one keycode for us so we only need to send one event to it. | |
| 4779 // Filtering is done via the RawKeyDown type because it is the one sent by | |
| 4780 // the current webdriver implementation of WebElement.SendKeys(...). | |
| 4781 DictionaryValue* reply_details = new DictionaryValue; | |
|
kkania
2011/03/10 17:00:47
reply.SendSuccess does not take ownership of the v
timothe faudot
2011/03/11 03:32:08
Done.
Due to the changes up, the return dict isn't
| |
| 4782 if (event.type != WebKit::WebInputEvent::RawKeyDown) { | |
| 4783 AutomationJSONReply reply(this, reply_message); | |
| 4784 reply_details->SetBoolean("processed", false); | |
| 4785 reply.SendSuccess(reply_details); | |
| 4786 return; | |
| 4787 } | |
| 4788 BrowserWindow* browser_window = browser->window(); | |
| 4789 if (!browser_window) { | |
| 4790 AutomationJSONReply(this, reply_message) | |
| 4791 .SendError("Could not get the browser window"); | |
| 4792 return; | |
| 4793 } | |
| 4794 gfx::NativeWindow window = browser_window->GetNativeHandle(); | |
| 4795 if (!window) { | |
| 4796 AutomationJSONReply(this, reply_message) | |
| 4797 .SendError("Could not get the browser window handle"); | |
| 4798 return; | |
| 4799 } | |
| 4800 bool control = !!(event.modifiers & WebKit::WebInputEvent::ControlKey); | |
|
kkania
2011/03/10 17:00:47
I am a bit surprised you need this !! dance. What
timothe faudot
2011/03/11 03:32:08
There is now warning, it's just a common method to
| |
| 4801 bool shift = !!(event.modifiers & WebKit::WebInputEvent::ShiftKey); | |
| 4802 bool alt = !!(event.modifiers & WebKit::WebInputEvent::AltKey); | |
| 4803 bool meta = !!(event.modifiers & WebKit::WebInputEvent::MetaKey); | |
| 4804 if (!ui_controls::SendKeyPress( | |
| 4805 window, static_cast<ui::KeyboardCode>(event.nativeKeyCode), | |
| 4806 control, shift, alt, meta)) { | |
| 4807 AutomationJSONReply(this, reply_message) | |
| 4808 .SendError("Could not send the native key event"); | |
| 4809 } else { | |
| 4810 AutomationJSONReply reply(this, reply_message); | |
| 4811 reply_details->SetBoolean("processed", true); | |
| 4812 reply.SendSuccess(reply_details); | |
| 4813 } | |
| 4814 } | |
| 4815 | |
| 4688 // Sample JSON input: { "command": "GetNTPThumbnailMode" } | 4816 // Sample JSON input: { "command": "GetNTPThumbnailMode" } |
| 4689 // For output, refer to GetNTPThumbnailMode() in | 4817 // For output, refer to GetNTPThumbnailMode() in |
| 4690 // chrome/test/pyautolib/pyauto.py. | 4818 // chrome/test/pyautolib/pyauto.py. |
| 4691 void TestingAutomationProvider::GetNTPThumbnailMode( | 4819 void TestingAutomationProvider::GetNTPThumbnailMode( |
| 4692 Browser* browser, | 4820 Browser* browser, |
| 4693 DictionaryValue* args, | 4821 DictionaryValue* args, |
| 4694 IPC::Message* reply_message) { | 4822 IPC::Message* reply_message) { |
| 4695 const int shown_sections = ShownSectionsHandler::GetShownSections( | 4823 const int shown_sections = ShownSectionsHandler::GetShownSections( |
| 4696 browser->profile()->GetPrefs()); | 4824 browser->profile()->GetPrefs()); |
| 4697 | 4825 |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5362 // If you change this, update Observer for NotificationType::SESSION_END | 5490 // If you change this, update Observer for NotificationType::SESSION_END |
| 5363 // below. | 5491 // below. |
| 5364 MessageLoop::current()->PostTask(FROM_HERE, | 5492 MessageLoop::current()->PostTask(FROM_HERE, |
| 5365 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider)); | 5493 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider)); |
| 5366 } | 5494 } |
| 5367 } | 5495 } |
| 5368 | 5496 |
| 5369 void TestingAutomationProvider::OnRemoveProvider() { | 5497 void TestingAutomationProvider::OnRemoveProvider() { |
| 5370 AutomationProviderList::GetInstance()->RemoveProvider(this); | 5498 AutomationProviderList::GetInstance()->RemoveProvider(this); |
| 5371 } | 5499 } |
| OLD | NEW |