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 "chrome/browser/devtools/devtools_window.h" | 5 #include "chrome/browser/devtools/devtools_window.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "chrome/common/render_messages.h" | 48 #include "chrome/common/render_messages.h" |
49 #include "chrome/common/url_constants.h" | 49 #include "chrome/common/url_constants.h" |
50 #include "components/user_prefs/pref_registry_syncable.h" | 50 #include "components/user_prefs/pref_registry_syncable.h" |
51 #include "content/public/browser/browser_thread.h" | 51 #include "content/public/browser/browser_thread.h" |
52 #include "content/public/browser/child_process_security_policy.h" | 52 #include "content/public/browser/child_process_security_policy.h" |
53 #include "content/public/browser/devtools_agent_host.h" | 53 #include "content/public/browser/devtools_agent_host.h" |
54 #include "content/public/browser/devtools_client_host.h" | 54 #include "content/public/browser/devtools_client_host.h" |
55 #include "content/public/browser/devtools_manager.h" | 55 #include "content/public/browser/devtools_manager.h" |
56 #include "content/public/browser/favicon_status.h" | 56 #include "content/public/browser/favicon_status.h" |
57 #include "content/public/browser/load_notification_details.h" | 57 #include "content/public/browser/load_notification_details.h" |
| 58 #include "content/public/browser/native_web_keyboard_event.h" |
58 #include "content/public/browser/navigation_controller.h" | 59 #include "content/public/browser/navigation_controller.h" |
59 #include "content/public/browser/navigation_entry.h" | 60 #include "content/public/browser/navigation_entry.h" |
60 #include "content/public/browser/notification_source.h" | 61 #include "content/public/browser/notification_source.h" |
61 #include "content/public/browser/render_frame_host.h" | 62 #include "content/public/browser/render_frame_host.h" |
62 #include "content/public/browser/render_process_host.h" | 63 #include "content/public/browser/render_process_host.h" |
63 #include "content/public/browser/render_view_host.h" | 64 #include "content/public/browser/render_view_host.h" |
64 #include "content/public/browser/user_metrics.h" | 65 #include "content/public/browser/user_metrics.h" |
65 #include "content/public/browser/web_contents.h" | 66 #include "content/public/browser/web_contents.h" |
66 #include "content/public/browser/web_contents_observer.h" | 67 #include "content/public/browser/web_contents_observer.h" |
67 #include "content/public/browser/web_contents_view.h" | 68 #include "content/public/browser/web_contents_view.h" |
68 #include "content/public/common/bindings_policy.h" | 69 #include "content/public/common/bindings_policy.h" |
69 #include "content/public/common/content_client.h" | 70 #include "content/public/common/content_client.h" |
70 #include "content/public/common/page_transition_types.h" | 71 #include "content/public/common/page_transition_types.h" |
71 #include "content/public/common/renderer_preferences.h" | 72 #include "content/public/common/renderer_preferences.h" |
72 #include "content/public/common/url_constants.h" | 73 #include "content/public/common/url_constants.h" |
73 #include "content/public/test/test_utils.h" | 74 #include "content/public/test/test_utils.h" |
74 #include "extensions/browser/extension_system.h" | 75 #include "extensions/browser/extension_system.h" |
75 #include "extensions/common/extension_set.h" | 76 #include "extensions/common/extension_set.h" |
76 #include "grit/generated_resources.h" | 77 #include "grit/generated_resources.h" |
77 #include "third_party/WebKit/public/web/WebInputEvent.h" | 78 #include "third_party/WebKit/public/web/WebInputEvent.h" |
78 #include "ui/base/l10n/l10n_util.h" | 79 #include "ui/base/l10n/l10n_util.h" |
| 80 #include "ui/events/keycodes/keyboard_codes.h" |
79 | 81 |
80 using base::DictionaryValue; | 82 using base::DictionaryValue; |
| 83 using blink::WebInputEvent; |
81 using content::BrowserThread; | 84 using content::BrowserThread; |
82 using content::DevToolsAgentHost; | 85 using content::DevToolsAgentHost; |
83 | 86 |
84 | 87 |
85 // DevToolsConfirmInfoBarDelegate --------------------------------------------- | 88 // DevToolsConfirmInfoBarDelegate --------------------------------------------- |
86 | 89 |
87 class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { | 90 class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { |
88 public: | 91 public: |
89 // If |infobar_service| is NULL, runs |callback| with a single argument with | 92 // If |infobar_service| is NULL, runs |callback| with a single argument with |
90 // value "false". Otherwise, creates a dev tools confirm infobar and delegate | 93 // value "false". Otherwise, creates a dev tools confirm infobar and delegate |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 callback_.Reset(); | 155 callback_.Reset(); |
153 return true; | 156 return true; |
154 } | 157 } |
155 | 158 |
156 bool DevToolsConfirmInfoBarDelegate::Cancel() { | 159 bool DevToolsConfirmInfoBarDelegate::Cancel() { |
157 callback_.Run(false); | 160 callback_.Run(false); |
158 callback_.Reset(); | 161 callback_.Reset(); |
159 return true; | 162 return true; |
160 } | 163 } |
161 | 164 |
| 165 // DevToolsEventForwarder ----------------------------------------------------- |
| 166 |
| 167 namespace { |
| 168 |
| 169 static const char kKeyUpEventName[] = "keyup"; |
| 170 static const char kKeyDownEventName[] = "keydown"; |
| 171 |
| 172 } // namespace |
| 173 |
| 174 class DevToolsEventForwarder { |
| 175 public: |
| 176 explicit DevToolsEventForwarder(DevToolsWindow* window) |
| 177 : devtools_window_(window) {} |
| 178 |
| 179 // Registers whitelisted shortcuts with the forwarder. |
| 180 // Only registered keys will be forwarded to the DevTools frontend. |
| 181 void SetWhitelistedShortcuts(const std::string& message); |
| 182 |
| 183 // Forwards a keyboard event to the DevTools frontend if it is whitelisted. |
| 184 // Returns |true| if the event has been forwarded, |false| otherwise. |
| 185 bool ForwardEvent(const content::NativeWebKeyboardEvent& event); |
| 186 |
| 187 private: |
| 188 static int VirtualKeyCodeWithoutLocation(int key_code); |
| 189 static bool KeyWhitelistingAllowed(int key_code, int modifiers); |
| 190 static int CombineKeyCodeAndModifiers(int key_code, int modifiers); |
| 191 |
| 192 DevToolsWindow* devtools_window_; |
| 193 std::set<int> whitelisted_keys_; |
| 194 |
| 195 DISALLOW_COPY_AND_ASSIGN(DevToolsEventForwarder); |
| 196 }; |
| 197 |
| 198 void DevToolsEventForwarder::SetWhitelistedShortcuts( |
| 199 const std::string& message) { |
| 200 scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message)); |
| 201 base::ListValue* shortcut_list; |
| 202 if (!parsed_message->GetAsList(&shortcut_list)) |
| 203 return; |
| 204 base::ListValue::iterator it = shortcut_list->begin(); |
| 205 for (; it != shortcut_list->end(); ++it) { |
| 206 base::DictionaryValue* dictionary; |
| 207 if (!(*it)->GetAsDictionary(&dictionary)) |
| 208 continue; |
| 209 int key_code = 0; |
| 210 dictionary->GetInteger("keyCode", &key_code); |
| 211 if (key_code == 0) |
| 212 continue; |
| 213 int modifiers = 0; |
| 214 dictionary->GetInteger("modifiers", &modifiers); |
| 215 if (!KeyWhitelistingAllowed(key_code, modifiers)) { |
| 216 LOG(WARNING) << "Key whitelisting forbidden: " |
| 217 << "(" << key_code << "," << modifiers << ")"; |
| 218 continue; |
| 219 } |
| 220 whitelisted_keys_.insert(CombineKeyCodeAndModifiers(key_code, modifiers)); |
| 221 } |
| 222 } |
| 223 |
| 224 bool DevToolsEventForwarder::ForwardEvent( |
| 225 const content::NativeWebKeyboardEvent& event) { |
| 226 std::string event_type; |
| 227 switch (event.type) { |
| 228 case WebInputEvent::KeyDown: |
| 229 case WebInputEvent::RawKeyDown: |
| 230 event_type = kKeyDownEventName; |
| 231 break; |
| 232 case WebInputEvent::KeyUp: |
| 233 event_type = kKeyUpEventName; |
| 234 break; |
| 235 default: |
| 236 return false; |
| 237 } |
| 238 |
| 239 int key_code = VirtualKeyCodeWithoutLocation(event.windowsKeyCode); |
| 240 int key = CombineKeyCodeAndModifiers(key_code, event.modifiers); |
| 241 if (whitelisted_keys_.find(key) == whitelisted_keys_.end()) |
| 242 return false; |
| 243 |
| 244 base::DictionaryValue event_data; |
| 245 event_data.SetString("type", event_type); |
| 246 event_data.SetString("keyIdentifier", event.keyIdentifier); |
| 247 event_data.SetInteger("keyCode", key_code); |
| 248 event_data.SetInteger("modifiers", event.modifiers); |
| 249 devtools_window_->CallClientFunction( |
| 250 "InspectorFrontendAPI.keyEventUnhandled", &event_data, NULL, NULL); |
| 251 return true; |
| 252 } |
| 253 |
| 254 int DevToolsEventForwarder::CombineKeyCodeAndModifiers(int key_code, |
| 255 int modifiers) { |
| 256 return key_code | (modifiers << 16); |
| 257 } |
| 258 |
| 259 bool DevToolsEventForwarder::KeyWhitelistingAllowed(int key_code, |
| 260 int modifiers) { |
| 261 return (ui::VKEY_F1 <= key_code && key_code <= ui::VKEY_F12) || |
| 262 modifiers != 0; |
| 263 } |
| 264 |
| 265 // Mapping copied from Blink's KeyboardEvent.cpp. |
| 266 int DevToolsEventForwarder::VirtualKeyCodeWithoutLocation(int key_code) |
| 267 { |
| 268 switch (key_code) { |
| 269 case ui::VKEY_LCONTROL: |
| 270 case ui::VKEY_RCONTROL: |
| 271 return ui::VKEY_CONTROL; |
| 272 case ui::VKEY_LSHIFT: |
| 273 case ui::VKEY_RSHIFT: |
| 274 return ui::VKEY_SHIFT; |
| 275 case ui::VKEY_LMENU: |
| 276 case ui::VKEY_RMENU: |
| 277 return ui::VKEY_MENU; |
| 278 default: |
| 279 return key_code; |
| 280 } |
| 281 } |
162 | 282 |
163 // DevToolsWindow::InspectedWebContentsObserver ------------------------------- | 283 // DevToolsWindow::InspectedWebContentsObserver ------------------------------- |
164 | 284 |
165 class DevToolsWindow::InspectedWebContentsObserver | 285 class DevToolsWindow::InspectedWebContentsObserver |
166 : public content::WebContentsObserver { | 286 : public content::WebContentsObserver { |
167 public: | 287 public: |
168 explicit InspectedWebContentsObserver(content::WebContents* web_contents); | 288 explicit InspectedWebContentsObserver(content::WebContents* web_contents); |
169 virtual ~InspectedWebContentsObserver(); | 289 virtual ~InspectedWebContentsObserver(); |
170 | 290 |
171 content::WebContents* web_contents() { | 291 content::WebContents* web_contents() { |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 content::RenderViewHost* inspected_rvh) { | 459 content::RenderViewHost* inspected_rvh) { |
340 if (!inspected_rvh || !DevToolsAgentHost::HasFor(inspected_rvh)) | 460 if (!inspected_rvh || !DevToolsAgentHost::HasFor(inspected_rvh)) |
341 return NULL; | 461 return NULL; |
342 | 462 |
343 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( | 463 scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor( |
344 inspected_rvh)); | 464 inspected_rvh)); |
345 return FindDevToolsWindow(agent.get()); | 465 return FindDevToolsWindow(agent.get()); |
346 } | 466 } |
347 | 467 |
348 // static | 468 // static |
| 469 DevToolsWindow* DevToolsWindow::GetInstanceForInspectedWebContents( |
| 470 content::WebContents* inspected_web_contents) { |
| 471 if (!inspected_web_contents) |
| 472 return NULL; |
| 473 return GetInstanceForInspectedRenderViewHost( |
| 474 inspected_web_contents->GetRenderViewHost()); |
| 475 } |
| 476 |
| 477 // static |
349 bool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) { | 478 bool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) { |
350 return AsDevToolsWindow(window_rvh) != NULL; | 479 return AsDevToolsWindow(window_rvh) != NULL; |
351 } | 480 } |
352 | 481 |
353 // static | 482 // static |
354 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker( | 483 DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker( |
355 Profile* profile, | 484 Profile* profile, |
356 DevToolsAgentHost* worker_agent) { | 485 DevToolsAgentHost* worker_agent) { |
357 DevToolsWindow* window = FindDevToolsWindow(worker_agent); | 486 DevToolsWindow* window = FindDevToolsWindow(worker_agent); |
358 if (!window) { | 487 if (!window) { |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 content::Source<ThemeService>( | 826 content::Source<ThemeService>( |
698 ThemeServiceFactory::GetForProfile(profile_))); | 827 ThemeServiceFactory::GetForProfile(profile_))); |
699 | 828 |
700 // There is no inspected_rvh in case of shared workers. | 829 // There is no inspected_rvh in case of shared workers. |
701 if (inspected_rvh) | 830 if (inspected_rvh) |
702 inspected_contents_observer_.reset(new InspectedWebContentsObserver( | 831 inspected_contents_observer_.reset(new InspectedWebContentsObserver( |
703 content::WebContents::FromRenderViewHost(inspected_rvh))); | 832 content::WebContents::FromRenderViewHost(inspected_rvh))); |
704 | 833 |
705 embedder_message_dispatcher_.reset( | 834 embedder_message_dispatcher_.reset( |
706 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this)); | 835 DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this)); |
| 836 event_forwarder_.reset(new DevToolsEventForwarder(this)); |
707 } | 837 } |
708 | 838 |
709 // static | 839 // static |
710 DevToolsWindow* DevToolsWindow::Create( | 840 DevToolsWindow* DevToolsWindow::Create( |
711 Profile* profile, | 841 Profile* profile, |
712 const GURL& frontend_url, | 842 const GURL& frontend_url, |
713 content::RenderViewHost* inspected_rvh, | 843 content::RenderViewHost* inspected_rvh, |
714 bool shared_worker_frontend, | 844 bool shared_worker_frontend, |
715 bool external_frontend, | 845 bool external_frontend, |
716 bool can_dock) { | 846 bool can_dock) { |
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 } | 1666 } |
1537 | 1667 |
1538 void DevToolsWindow::SetLoadCompletedCallback(const base::Closure& closure) { | 1668 void DevToolsWindow::SetLoadCompletedCallback(const base::Closure& closure) { |
1539 if (load_state_ == kLoadCompleted) { | 1669 if (load_state_ == kLoadCompleted) { |
1540 if (!closure.is_null()) | 1670 if (!closure.is_null()) |
1541 closure.Run(); | 1671 closure.Run(); |
1542 return; | 1672 return; |
1543 } | 1673 } |
1544 load_completed_callback_ = closure; | 1674 load_completed_callback_ = closure; |
1545 } | 1675 } |
| 1676 |
| 1677 void DevToolsWindow::SetWhitelistedShortcuts( |
| 1678 const std::string& message) { |
| 1679 event_forwarder_->SetWhitelistedShortcuts(message); |
| 1680 } |
| 1681 |
| 1682 bool DevToolsWindow::ForwardKeyboardEvent( |
| 1683 const content::NativeWebKeyboardEvent& event) { |
| 1684 return event_forwarder_->ForwardEvent(event); |
| 1685 } |
OLD | NEW |