| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/public/test/browser_test_utils.h" | 5 #include "content/public/test/browser_test_utils.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <tuple> | 8 #include <tuple> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 #include "ui/aura/test/window_event_dispatcher_test_api.h" | 85 #include "ui/aura/test/window_event_dispatcher_test_api.h" |
| 86 #include "ui/aura/window.h" | 86 #include "ui/aura/window.h" |
| 87 #include "ui/aura/window_event_dispatcher.h" | 87 #include "ui/aura/window_event_dispatcher.h" |
| 88 #include "ui/aura/window_tree_host.h" | 88 #include "ui/aura/window_tree_host.h" |
| 89 #include "ui/events/event.h" | 89 #include "ui/events/event.h" |
| 90 #endif // USE_AURA | 90 #endif // USE_AURA |
| 91 | 91 |
| 92 namespace content { | 92 namespace content { |
| 93 namespace { | 93 namespace { |
| 94 | 94 |
| 95 class DOMOperationObserver : public NotificationObserver, | |
| 96 public WebContentsObserver { | |
| 97 public: | |
| 98 explicit DOMOperationObserver(RenderFrameHost* rfh) | |
| 99 : WebContentsObserver(WebContents::FromRenderFrameHost(rfh)), | |
| 100 did_respond_(false) { | |
| 101 registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE, | |
| 102 Source<WebContents>(web_contents())); | |
| 103 message_loop_runner_ = new MessageLoopRunner; | |
| 104 } | |
| 105 | |
| 106 void Observe(int type, | |
| 107 const NotificationSource& source, | |
| 108 const NotificationDetails& details) override { | |
| 109 DCHECK(type == NOTIFICATION_DOM_OPERATION_RESPONSE); | |
| 110 Details<std::string> dom_op_result(details); | |
| 111 if (!did_respond_) { | |
| 112 response_ = *dom_op_result.ptr(); | |
| 113 did_respond_ = true; | |
| 114 message_loop_runner_->Quit(); | |
| 115 } | |
| 116 } | |
| 117 | |
| 118 // Overridden from WebContentsObserver: | |
| 119 void RenderProcessGone(base::TerminationStatus status) override { | |
| 120 message_loop_runner_->Quit(); | |
| 121 } | |
| 122 | |
| 123 bool WaitAndGetResponse(std::string* response) WARN_UNUSED_RESULT { | |
| 124 message_loop_runner_->Run(); | |
| 125 *response = response_; | |
| 126 return did_respond_; | |
| 127 } | |
| 128 | |
| 129 private: | |
| 130 NotificationRegistrar registrar_; | |
| 131 std::string response_; | |
| 132 bool did_respond_; | |
| 133 scoped_refptr<MessageLoopRunner> message_loop_runner_; | |
| 134 | |
| 135 DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver); | |
| 136 }; | |
| 137 | |
| 138 class InterstitialObserver : public content::WebContentsObserver { | 95 class InterstitialObserver : public content::WebContentsObserver { |
| 139 public: | 96 public: |
| 140 InterstitialObserver(content::WebContents* web_contents, | 97 InterstitialObserver(content::WebContents* web_contents, |
| 141 const base::Closure& attach_callback, | 98 const base::Closure& attach_callback, |
| 142 const base::Closure& detach_callback) | 99 const base::Closure& detach_callback) |
| 143 : WebContentsObserver(web_contents), | 100 : WebContentsObserver(web_contents), |
| 144 attach_callback_(attach_callback), | 101 attach_callback_(attach_callback), |
| 145 detach_callback_(detach_callback) { | 102 detach_callback_(detach_callback) { |
| 146 } | 103 } |
| 147 ~InterstitialObserver() override {} | 104 ~InterstitialObserver() override {} |
| (...skipping 18 matching lines...) Expand all Loading... |
| 166 // Executes the passed |original_script| in the frame specified by | 123 // Executes the passed |original_script| in the frame specified by |
| 167 // |render_frame_host|. If |result| is not NULL, stores the value that the | 124 // |render_frame_host|. If |result| is not NULL, stores the value that the |
| 168 // evaluation of the script in |result|. Returns true on success. | 125 // evaluation of the script in |result|. Returns true on success. |
| 169 bool ExecuteScriptHelper(RenderFrameHost* render_frame_host, | 126 bool ExecuteScriptHelper(RenderFrameHost* render_frame_host, |
| 170 const std::string& original_script, | 127 const std::string& original_script, |
| 171 std::unique_ptr<base::Value>* result) { | 128 std::unique_ptr<base::Value>* result) { |
| 172 // TODO(jcampan): we should make the domAutomationController not require an | 129 // TODO(jcampan): we should make the domAutomationController not require an |
| 173 // automation id. | 130 // automation id. |
| 174 std::string script = | 131 std::string script = |
| 175 "window.domAutomationController.setAutomationId(0);" + original_script; | 132 "window.domAutomationController.setAutomationId(0);" + original_script; |
| 176 DOMOperationObserver dom_op_observer(render_frame_host); | 133 DOMAutomationWaiter dom_op_observer( |
| 134 WebContents::FromRenderFrameHost(render_frame_host)); |
| 177 render_frame_host->ExecuteJavaScriptWithUserGestureForTests( | 135 render_frame_host->ExecuteJavaScriptWithUserGestureForTests( |
| 178 base::UTF8ToUTF16(script)); | 136 base::UTF8ToUTF16(script)); |
| 179 std::string json; | 137 std::string json; |
| 180 if (!dom_op_observer.WaitAndGetResponse(&json)) { | 138 if (!dom_op_observer.WaitAndGetResponse(result)) { |
| 181 DLOG(ERROR) << "Cannot communicate with DOMOperationObserver."; | 139 DLOG(ERROR) << "Cannot communicate with DOMAutomationWaiter."; |
| 182 return false; | 140 return false; |
| 183 } | 141 } |
| 184 | 142 |
| 185 // Nothing more to do for callers that ignore the returned JS value. | |
| 186 if (!result) | |
| 187 return true; | |
| 188 | |
| 189 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); | |
| 190 *result = reader.ReadToValue(json); | |
| 191 if (!*result) { | |
| 192 DLOG(ERROR) << reader.GetErrorMessage(); | |
| 193 return false; | |
| 194 } | |
| 195 | |
| 196 return true; | 143 return true; |
| 197 } | 144 } |
| 198 | 145 |
| 199 // Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. | 146 // Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. |
| 200 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, | 147 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, |
| 201 const int world_id, | 148 const int world_id, |
| 202 const std::string& original_script, | 149 const std::string& original_script, |
| 203 std::unique_ptr<base::Value>* result) | 150 std::unique_ptr<base::Value>* result) |
| 204 WARN_UNUSED_RESULT; | 151 WARN_UNUSED_RESULT; |
| 205 | 152 |
| 206 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, | 153 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, |
| 207 const int world_id, | 154 const int world_id, |
| 208 const std::string& original_script, | 155 const std::string& original_script, |
| 209 std::unique_ptr<base::Value>* result) { | 156 std::unique_ptr<base::Value>* result) { |
| 157 // TODO(jcampan): we should make the domAutomationController not require an |
| 158 // automation id. |
| 210 std::string script = | 159 std::string script = |
| 211 "window.domAutomationController.setAutomationId(0);" + original_script; | 160 "window.domAutomationController.setAutomationId(0);" + original_script; |
| 212 DOMOperationObserver dom_op_observer(render_frame_host); | 161 DOMAutomationWaiter dom_op_observer( |
| 162 WebContents::FromRenderFrameHost(render_frame_host)); |
| 213 render_frame_host->ExecuteJavaScriptInIsolatedWorld( | 163 render_frame_host->ExecuteJavaScriptInIsolatedWorld( |
| 214 base::UTF8ToUTF16(script), | 164 base::UTF8ToUTF16(script), |
| 215 content::RenderFrameHost::JavaScriptResultCallback(), world_id); | 165 content::RenderFrameHost::JavaScriptResultCallback(), world_id); |
| 216 std::string json; | 166 std::string json; |
| 217 if (!dom_op_observer.WaitAndGetResponse(&json)) { | 167 if (!dom_op_observer.WaitAndGetResponse(result)) { |
| 218 DLOG(ERROR) << "Cannot communicate with DOMOperationObserver."; | 168 DLOG(ERROR) << "Cannot communicate with DOMAutomationWaiter."; |
| 219 return false; | 169 return false; |
| 220 } | 170 } |
| 221 | 171 |
| 222 // Nothing more to do for callers that ignore the returned JS value. | |
| 223 if (!result) | |
| 224 return true; | |
| 225 | |
| 226 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); | |
| 227 *result = reader.ReadToValue(json); | |
| 228 if (!*result) { | |
| 229 DLOG(ERROR) << reader.GetErrorMessage(); | |
| 230 return false; | |
| 231 } | |
| 232 | |
| 233 return true; | 172 return true; |
| 234 } | 173 } |
| 235 | 174 |
| 236 void BuildSimpleWebKeyEvent(blink::WebInputEvent::Type type, | 175 void BuildSimpleWebKeyEvent(blink::WebInputEvent::Type type, |
| 237 ui::DomKey key, | 176 ui::DomKey key, |
| 238 ui::DomCode code, | 177 ui::DomCode code, |
| 239 ui::KeyboardCode key_code, | 178 ui::KeyboardCode key_code, |
| 240 int modifiers, | 179 int modifiers, |
| 241 NativeWebKeyboardEvent* event) { | 180 NativeWebKeyboardEvent* event) { |
| 242 event->domKey = key; | 181 event->domKey = key; |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 } | 728 } |
| 790 | 729 |
| 791 RenderFrameHost* ConvertToRenderFrameHost(RenderViewHost* render_view_host) { | 730 RenderFrameHost* ConvertToRenderFrameHost(RenderViewHost* render_view_host) { |
| 792 return render_view_host->GetMainFrame(); | 731 return render_view_host->GetMainFrame(); |
| 793 } | 732 } |
| 794 | 733 |
| 795 RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_frame_host) { | 734 RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_frame_host) { |
| 796 return render_frame_host; | 735 return render_frame_host; |
| 797 } | 736 } |
| 798 | 737 |
| 738 DOMAutomationWaiter::DOMAutomationWaiter(WebContents* web_contents) |
| 739 : WebContentsObserver(web_contents), |
| 740 message_loop_runner_(new MessageLoopRunner) { |
| 741 registrar_.Add(this, NOTIFICATION_DOM_OPERATION_RESPONSE, |
| 742 Source<WebContents>(web_contents)); |
| 743 } |
| 744 |
| 745 DOMAutomationWaiter::~DOMAutomationWaiter() {} |
| 746 |
| 747 bool DOMAutomationWaiter::WaitAndGetResponse( |
| 748 std::unique_ptr<base::Value>* response) { |
| 749 message_loop_runner_->Run(); |
| 750 if (!response_) |
| 751 return false; |
| 752 |
| 753 if (response) |
| 754 *response = std::move(response_); |
| 755 else |
| 756 response_.reset(); |
| 757 |
| 758 return true; |
| 759 } |
| 760 |
| 761 bool DOMAutomationWaiter::ShouldStopWaiting(const base::Value& value) { |
| 762 return true; |
| 763 } |
| 764 |
| 765 void DOMAutomationWaiter::Observe(int type, |
| 766 const NotificationSource& source, |
| 767 const NotificationDetails& details) { |
| 768 DCHECK(type == NOTIFICATION_DOM_OPERATION_RESPONSE); |
| 769 Details<std::string> dom_op_result(details); |
| 770 |
| 771 // Return if already received a response. |
| 772 if (response_) |
| 773 return; |
| 774 |
| 775 // Parse JSON from notification data into |candidate_response|. |
| 776 const std::string& json_string = *dom_op_result.ptr(); |
| 777 std::unique_ptr<base::Value> candidate_response; |
| 778 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); |
| 779 candidate_response = reader.ReadToValue(json_string); |
| 780 if (!candidate_response) { |
| 781 DLOG(ERROR) << reader.GetErrorMessage(); |
| 782 return; |
| 783 } |
| 784 |
| 785 // Allow subclasses to ignore this response and to continue waiting. |
| 786 if (!ShouldStopWaiting(*candidate_response)) |
| 787 return; |
| 788 |
| 789 // Store the response and stop waiting. |
| 790 response_ = std::move(candidate_response); |
| 791 message_loop_runner_->Quit(); |
| 792 } |
| 793 |
| 794 void DOMAutomationWaiter::RenderProcessGone(base::TerminationStatus status) { |
| 795 switch (status) { |
| 796 case base::TERMINATION_STATUS_NORMAL_TERMINATION: |
| 797 case base::TERMINATION_STATUS_STILL_RUNNING: |
| 798 break; |
| 799 default: |
| 800 message_loop_runner_->Quit(); |
| 801 break; |
| 802 } |
| 803 } |
| 804 |
| 799 bool ExecuteScript(const ToRenderFrameHost& adapter, | 805 bool ExecuteScript(const ToRenderFrameHost& adapter, |
| 800 const std::string& script) { | 806 const std::string& script) { |
| 801 std::string new_script = | 807 std::string new_script = |
| 802 script + ";window.domAutomationController.send(0);"; | 808 script + ";window.domAutomationController.send(0);"; |
| 803 return ExecuteScriptHelper(adapter.render_frame_host(), new_script, NULL); | 809 return ExecuteScriptHelper(adapter.render_frame_host(), new_script, NULL); |
| 804 } | 810 } |
| 805 | 811 |
| 806 bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, | 812 bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, |
| 807 const std::string& script, double* result) { | 813 const std::string& script, double* result) { |
| 808 DCHECK(result); | 814 DCHECK(result); |
| (...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 | 1783 |
| 1778 std::string ascii_message = base::UTF16ToASCII(message); | 1784 std::string ascii_message = base::UTF16ToASCII(message); |
| 1779 if (base::MatchPattern(ascii_message, filter_)) { | 1785 if (base::MatchPattern(ascii_message, filter_)) { |
| 1780 message_ = ascii_message; | 1786 message_ = ascii_message; |
| 1781 message_loop_runner_->Quit(); | 1787 message_loop_runner_->Quit(); |
| 1782 } | 1788 } |
| 1783 return false; | 1789 return false; |
| 1784 } | 1790 } |
| 1785 | 1791 |
| 1786 } // namespace content | 1792 } // namespace content |
| OLD | NEW |