Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: chrome/browser/devtools/devtools_window.cc

Issue 225973003: DevTools: Forward whitelisted unhandled shortcuts from inspected page into DevTools frontend (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address pfeldman's comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/devtools/devtools_window.h ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/devtools_window.h ('k') | chrome/browser/ui/browser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698