devtools_window.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_reader.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/time/time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chrome_page_zoom.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/debugger/debugger_api.h"
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/file_select_helper.h"
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/infobars/infobar_service.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/webui/devtools_ui.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/render_messages.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h"
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/browser/browser_thread.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_client_host.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_manager.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/load_notification_details.h"
58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/public/browser/native_web_keyboard_event.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/page_transition_types.h"
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/renderer_preferences.h"
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/test/test_utils.h"
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/keycodes/keyboard_codes.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using base::DictionaryValue;
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing blink::WebInputEvent;
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)using content::BrowserThread;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsConfirmInfoBarDelegate ---------------------------------------------
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // If |infobar_service| is NULL, runs |callback| with a single argument with
932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // value "false".  Otherwise, creates a dev tools confirm infobar and delegate
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // and adds the infobar to |infobar_service|.
952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  static void Create(InfoBarService* infobar_service,
962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     const DevToolsWindow::InfoBarCallback& callback,
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     const base::string16& message);
982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch private:
1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsConfirmInfoBarDelegate(
1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      const DevToolsWindow::InfoBarCallback& callback,
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& message);
1032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~DevToolsConfirmInfoBarDelegate();
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetMessageText() const OVERRIDE;
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual base::string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool Accept() OVERRIDE;
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool Cancel() OVERRIDE;
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindow::InfoBarCallback callback_;
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16 message_;
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DevToolsConfirmInfoBarDelegate);
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsConfirmInfoBarDelegate::Create(
1172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    InfoBarService* infobar_service,
1182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const DevToolsWindow::InfoBarCallback& callback,
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message) {
1202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!infobar_service) {
1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    callback.Run(false);
1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
1232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      scoped_ptr<ConfirmInfoBarDelegate>(
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          new DevToolsConfirmInfoBarDelegate(callback, message))));
1282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsConfirmInfoBarDelegate::DevToolsConfirmInfoBarDelegate(
1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const DevToolsWindow::InfoBarCallback& callback,
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message)
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : ConfirmInfoBarDelegate(),
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      callback_(callback),
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      message_(message) {
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
1392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!callback_.is_null())
1402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    callback_.Run(false);
1412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 DevToolsConfirmInfoBarDelegate::GetMessageText() const {
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return message_;
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 DevToolsConfirmInfoBarDelegate::GetButtonLabel(
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    InfoBarButton button) const {
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
152a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
153a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsConfirmInfoBarDelegate::Accept() {
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Run(true);
155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Reset();
156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsConfirmInfoBarDelegate::Cancel() {
160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Run(false);
161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Reset();
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// DevToolsEventForwarder -----------------------------------------------------
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace {
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic const char kKeyUpEventName[] = "keyup";
170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic const char kKeyDownEventName[] = "keydown";
171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace
173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass DevToolsEventForwarder {
175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  explicit DevToolsEventForwarder(DevToolsWindow* window)
177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch     : devtools_window_(window) {}
178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Registers whitelisted shortcuts with the forwarder.
180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Only registered keys will be forwarded to the DevTools frontend.
181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void SetWhitelistedShortcuts(const std::string& message);
182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Forwards a keyboard event to the DevTools frontend if it is whitelisted.
184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Returns |true| if the event has been forwarded, |false| otherwise.
185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool ForwardEvent(const content::NativeWebKeyboardEvent& event);
186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static int VirtualKeyCodeWithoutLocation(int key_code);
189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static bool KeyWhitelistingAllowed(int key_code, int modifiers);
190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  static int CombineKeyCodeAndModifiers(int key_code, int modifiers);
191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DevToolsWindow* devtools_window_;
193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::set<int> whitelisted_keys_;
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DevToolsEventForwarder);
196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid DevToolsEventForwarder::SetWhitelistedShortcuts(
199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::string& message) {
200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::ListValue* shortcut_list;
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!parsed_message->GetAsList(&shortcut_list))
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return;
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::ListValue::iterator it = shortcut_list->begin();
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (; it != shortcut_list->end(); ++it) {
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::DictionaryValue* dictionary;
207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!(*it)->GetAsDictionary(&dictionary))
208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      continue;
209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int key_code = 0;
210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    dictionary->GetInteger("keyCode", &key_code);
211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (key_code == 0)
212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      continue;
213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    int modifiers = 0;
214c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    dictionary->GetInteger("modifiers", &modifiers);
215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!KeyWhitelistingAllowed(key_code, modifiers)) {
216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      LOG(WARNING) << "Key whitelisting forbidden: "
217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                   << "(" << key_code << "," << modifiers << ")";
218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      continue;
219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    whitelisted_keys_.insert(CombineKeyCodeAndModifiers(key_code, modifiers));
221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool DevToolsEventForwarder::ForwardEvent(
225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const content::NativeWebKeyboardEvent& event) {
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::string event_type;
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  switch (event.type) {
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case WebInputEvent::KeyDown:
229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case WebInputEvent::RawKeyDown:
230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      event_type = kKeyDownEventName;
231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case WebInputEvent::KeyUp:
233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      event_type = kKeyUpEventName;
234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      break;
235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    default:
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return false;
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int key_code = VirtualKeyCodeWithoutLocation(event.windowsKeyCode);
240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int key = CombineKeyCodeAndModifiers(key_code, event.modifiers);
241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (whitelisted_keys_.find(key) == whitelisted_keys_.end())
242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
243c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::DictionaryValue event_data;
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_data.SetString("type", event_type);
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_data.SetString("keyIdentifier", event.keyIdentifier);
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_data.SetInteger("keyCode", key_code);
248c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_data.SetInteger("modifiers", event.modifiers);
249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  devtools_window_->CallClientFunction(
250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "InspectorFrontendAPI.keyEventUnhandled", &event_data, NULL, NULL);
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return true;
252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint DevToolsEventForwarder::CombineKeyCodeAndModifiers(int key_code,
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                       int modifiers) {
256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return key_code | (modifiers << 16);
257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool DevToolsEventForwarder::KeyWhitelistingAllowed(int key_code,
260c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    int modifiers) {
261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return (ui::VKEY_F1 <= key_code && key_code <= ui::VKEY_F12) ||
262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      modifiers != 0;
263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Mapping copied from Blink's KeyboardEvent.cpp.
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochint DevToolsEventForwarder::VirtualKeyCodeWithoutLocation(int key_code)
267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{
268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  switch (key_code) {
269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_LCONTROL:
270c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_RCONTROL:
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return ui::VKEY_CONTROL;
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_LSHIFT:
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_RSHIFT:
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return ui::VKEY_SHIFT;
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_LMENU:
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    case ui::VKEY_RMENU:
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return ui::VKEY_MENU;
278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    default:
279c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        return key_code;
280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow::InspectedWebContentsObserver -------------------------------
284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevToolsWindow::InspectedWebContentsObserver
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  explicit InspectedWebContentsObserver(content::WebContents* web_contents);
2892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~InspectedWebContentsObserver();
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* web_contents() {
292a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return WebContentsObserver::web_contents();
293a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
2942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch private:
2962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(InspectedWebContentsObserver);
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::InspectedWebContentsObserver::InspectedWebContentsObserver(
300a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::WebContents* web_contents)
301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : WebContentsObserver(web_contents) {
302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow::InspectedWebContentsObserver::~InspectedWebContentsObserver() {
3052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow::FrontendWebContentsObserver --------------------------------
309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DevToolsWindow::FrontendWebContentsObserver
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  explicit FrontendWebContentsObserver(DevToolsWindow* window);
3142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~FrontendWebContentsObserver();
315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
3172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // contents::WebContentsObserver:
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AboutToNavigateRenderView(
3192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::RenderViewHost* render_view_host) OVERRIDE;
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void WebContentsDestroyed(content::WebContents*) OVERRIDE;
3222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DevToolsWindow* devtools_window_;
3242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::FrontendWebContentsObserver::FrontendWebContentsObserver(
3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DevToolsWindow* devtools_window)
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : WebContentsObserver(devtools_window->web_contents()),
3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      devtools_window_(devtools_window) {
331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DevToolsWindow::FrontendWebContentsObserver::WebContentsDestroyed(
334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WebContents* contents) {
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete devtools_window_;
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow::FrontendWebContentsObserver::~FrontendWebContentsObserver() {
3392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::FrontendWebContentsObserver::AboutToNavigateRenderView(
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::RenderViewHost* render_view_host) {
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DevToolsWindow::FrontendWebContentsObserver::
3471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DocumentOnLoadCompletedInMainFrame(int32 page_id) {
3481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  devtools_window_->DocumentOnLoadCompletedInMainFrame();
3491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow -------------------------------------------------------------
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochtypedef std::vector<DevToolsWindow*> DevToolsWindows;
3562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbase::LazyInstance<DevToolsWindows>::Leaky g_instances =
3572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    LAZY_INSTANCE_INITIALIZER;
3582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostId[] = "id";
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostMethod[] = "method";
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostParams[] = "params";
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string SkColorToRGBAString(SkColor color) {
3642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // We avoid StringPrintf because it will use locale specific formatters for
3652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // the double (e.g. ',' instead of '.' in German).
3662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return "rgba(" + base::IntToString(SkColorGetR(color)) + "," +
3672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::IntToString(SkColorGetG(color)) + "," +
3682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::IntToString(SkColorGetB(color)) + "," +
3692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::DoubleToString(SkColorGetA(color) / 255.0) + ")";
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* CreateFileSystemValue(
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsFileHelper::FileSystem file_system) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue* file_system_value = new base::DictionaryValue();
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("fileSystemName", file_system.file_system_name);
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("rootURL", file_system.root_url);
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("fileSystemPath", file_system.file_system_path);
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return file_system_value;
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char DevToolsWindow::kDevToolsApp[] = "DevToolsApp";
3842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::~DevToolsWindow() {
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::DevToolsManager::GetInstance()->ClientHostClosing(
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      frontend_host_.get());
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateBrowserToolbar();
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsWindows* instances = g_instances.Pointer();
3912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindows::iterator it(
3922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      std::find(instances->begin(), instances->end(), this));
3932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(it != instances->end());
3942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  instances->erase(it);
3952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
396ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin());
397ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       jobs_it != indexing_jobs_.end(); ++jobs_it) {
3982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    jobs_it->second->Stop();
399ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
4002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.clear();
4010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (device_listener_enabled_)
4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    EnableRemoteDeviceCounter(false);
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DevToolsWindow::GetDevToolsWindowPlacementPrefKey() {
4072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return std::string(prefs::kBrowserWindowPlacement) + "_" +
4082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      std::string(kDevToolsApp);
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DevToolsWindow::RegisterProfilePrefs(
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsEditedFiles,
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsFileSystemPaths,
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registry->RegisterStringPref(
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      prefs::kDevToolsAdbKey, std::string(),
4227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetDevToolsWindowPlacementPrefKey().c_str(),
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
4272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
4282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registry->RegisterBooleanPref(
4294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kDevToolsDiscoverUsbDevicesEnabled,
4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      true,
4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterBooleanPref(
4332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingEnabled,
4342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      false,
4352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  registry->RegisterBooleanPref(
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      prefs::kDevToolsPortForwardingDefaultSet,
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      false,
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
4402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registry->RegisterDictionaryPref(
4412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingConfig,
4422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab(
4472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* inspected_web_contents) {
4480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DevToolsWindow* window = GetInstanceForInspectedRenderViewHost(
4490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      inspected_web_contents->GetRenderViewHost());
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!window)
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not yet loaded window is treated as docked, but we should not present it
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // until we decided on docking.
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool is_docked_set = window->load_state_ == kLoadCompleted ||
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      window->load_state_ == kIsDockedSet;
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return window->is_docked_ && is_docked_set ? window : NULL;
4570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
4580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// static
4600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)DevToolsWindow* DevToolsWindow::GetInstanceForInspectedRenderViewHost(
4610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      content::RenderViewHost* inspected_rvh) {
4620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (!inspected_rvh || !DevToolsAgentHost::HasFor(inspected_rvh))
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
4640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
4660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      inspected_rvh));
4670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return FindDevToolsWindow(agent.get());
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochDevToolsWindow* DevToolsWindow::GetInstanceForInspectedWebContents(
472c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    content::WebContents* inspected_web_contents) {
473c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!inspected_web_contents)
474c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return NULL;
475c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return GetInstanceForInspectedRenderViewHost(
476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      inspected_web_contents->GetRenderViewHost());
477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
478c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// static
4802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AsDevToolsWindow(window_rvh) != NULL;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker(
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsAgentHost* worker_agent) {
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(worker_agent);
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window = DevToolsWindow::CreateDevToolsWindowForWorker(profile);
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Will disconnect the current client host if there is one.
4922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
4932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        worker_agent, window->frontend_host_.get());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->ScheduleShow(DevToolsToggleAction::Show());
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::RecordAction(base::UserMetricsAction("DevTools_InspectWorker"));
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Create(profile, GURL(), NULL, true, false, false);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindow(
5082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh) {
5090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  return ToggleDevToolsWindow(
5100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      inspected_rvh, true, DevToolsToggleAction::Show());
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindow(
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderViewHost* inspected_rvh,
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const DevToolsToggleAction& action) {
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ToggleDevToolsWindow(
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      inspected_rvh, true, action);
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForTest(
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderViewHost* inspected_rvh,
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_docked) {
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsWindow* window = OpenDevToolsWindow(inspected_rvh);
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->SetIsDockedAndShowImmediatelyForTest(is_docked);
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return window;
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForTest(
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Browser* browser,
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool is_docked) {
5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OpenDevToolsWindowForTest(
5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_docked);
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
5420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const DevToolsToggleAction& action) {
5430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  if (action.type() == DevToolsToggleAction::kToggle &&
5440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      browser->is_devtools()) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->CloseAllTabs();
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return ToggleDevToolsWindow(
5502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
5510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      action.type() == DevToolsToggleAction::kInspect, action);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::OpenExternalFrontend(
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile* profile,
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& frontend_url,
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::DevToolsAgentHost* agent_host) {
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent_host);
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL,
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    false, true, false);
5632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        agent_host, window->frontend_host_.get());
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window->ScheduleShow(DevToolsToggleAction::Show());
567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
5712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh,
572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool force_open,
5730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    const DevToolsToggleAction& action) {
574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
5762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent.get());
578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool do_open = force_open;
579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!window) {
580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile = Profile::FromBrowserContext(
581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        inspected_rvh->GetProcess()->GetBrowserContext());
582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::RecordAction(
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::UserMetricsAction("DevTools_InspectRenderer"));
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window = Create(profile, GURL(), inspected_rvh, false, false, true);
585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    manager->RegisterDevToolsClientHostFor(agent.get(),
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                           window->frontend_host_.get());
587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    do_open = true;
588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Update toolbar to reflect DevTools changes.
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  window->UpdateBrowserToolbar();
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // If window is docked and visible, we hide it on toggle. If window is
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // undocked, we show (activate) it.
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!window->is_docked_ || do_open)
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window->ScheduleShow(action);
597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  else
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    window->CloseWindow();
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return window;
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
6042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh,
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    int x,
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    int y) {
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  agent->InspectElement(x, y);
6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool should_measure_time = FindDevToolsWindow(agent.get()) == NULL;
6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(loislo): we should initiate DevTools window opening from within
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // renderer. Otherwise, we still can hit a race condition here.
6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsWindow* window = OpenDevToolsWindow(inspected_rvh);
6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (should_measure_time)
6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window->inspect_element_start_time_ = start_time;
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::InspectedContentsClosing() {
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  intercepted_page_beforeunload_ = false;
6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will prevent any activity after frontend is loaded.
6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_on_load_ = DevToolsToggleAction::NoOp();
6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ignore_set_is_docked_ = true;
6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_contents_->GetRenderViewHost()->ClosePage();
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochcontent::RenderViewHost* DevToolsWindow::GetRenderViewHost() {
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return web_contents_->GetRenderViewHost();
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const DevToolsContentsResizingStrategy&
6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DevToolsWindow::GetContentsResizingStrategy() const {
6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return contents_resizing_strategy_;
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Size DevToolsWindow::GetMinimumSize() const {
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const gfx::Size kMinDevToolsSize = gfx::Size(230, 100);
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return kMinDevToolsSize;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::ScheduleShow(const DevToolsToggleAction& action) {
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ == kLoadCompleted) {
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Show(action);
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Action will be done only after load completed.
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_on_load_ = action;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!can_dock_) {
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // No harm to show always-undocked window right away.
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    is_docked_ = false;
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Show(DevToolsToggleAction::Show());
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void DevToolsWindow::Show(const DevToolsToggleAction& action) {
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (action.type() == DevToolsToggleAction::kNoOp)
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_) {
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(can_dock_);
6632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    Browser* inspected_browser = NULL;
6642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int inspected_tab_index = -1;
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FindInspectedBrowserAndTabIndex(GetInspectedWebContents(),
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    &inspected_browser,
6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                    &inspected_tab_index);
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(inspected_browser);
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(inspected_tab_index != -1);
6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Tell inspected browser to update splitter and switch to inspected panel.
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserWindow* inspected_window = inspected_browser->window();
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    web_contents_->SetDelegate(this);
6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    TabStripModel* tab_strip_model = inspected_browser->tab_strip_model();
6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_strip_model->ActivateTabAt(inspected_tab_index, true);
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    inspected_window->UpdateDevTools();
6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    web_contents_->GetView()->SetInitialFocus();
6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    inspected_window->Show();
6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // On Aura, focusing once is not enough. Do it again.
6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Note that focusing only here but not before isn't enough either. We just
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // need to focus twice.
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    web_contents_->GetView()->SetInitialFocus();
6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PrefsTabHelper::CreateForWebContents(web_contents_);
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetRenderViewHost()->SyncRendererPrefs();
6882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DoAction(action);
6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
693a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Avoid consecutive window switching if the devtools window has been opened
694a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // and the Inspect Element shortcut is pressed in the inspected tab.
695a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool should_show_window =
6960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      !browser_ || (action.type() != DevToolsToggleAction::kInspect);
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!browser_)
699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CreateDevToolsBrowser();
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
701a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (should_show_window) {
702a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    browser_->window()->Show();
703a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    web_contents_->GetView()->SetInitialFocus();
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoAction(action);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DevToolsWindow::HandleBeforeUnload(content::WebContents* frontend_contents,
711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bool proceed, bool* proceed_to_fire_unload) {
712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow* window = AsDevToolsWindow(
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      frontend_contents->GetRenderViewHost());
714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!window)
715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!window->intercepted_page_beforeunload_)
717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window->BeforeUnloadFired(frontend_contents, proceed,
719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      proceed_to_fire_unload);
720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DevToolsWindow::InterceptPageBeforeUnload(content::WebContents* contents) {
725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow* window =
726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DevToolsWindow::GetInstanceForInspectedRenderViewHost(
727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          contents->GetRenderViewHost());
728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!window || window->intercepted_page_beforeunload_)
729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Not yet loaded frontend will not handle beforeunload.
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window->load_state_ != kLoadCompleted)
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window->intercepted_page_beforeunload_ = true;
736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Handle case of devtools inspecting another devtools instance by passing
737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // the call up to the inspecting devtools instance.
738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!DevToolsWindow::InterceptPageBeforeUnload(window->web_contents())) {
739c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    window->web_contents()->DispatchBeforeUnload(false);
740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DevToolsWindow::NeedsToInterceptBeforeUnload(
746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WebContents* contents) {
747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow* window =
748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DevToolsWindow::GetInstanceForInspectedRenderViewHost(
749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          contents->GetRenderViewHost());
750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return window && !window->intercepted_page_beforeunload_;
751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(
755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Browser* browser) {
756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(browser->is_devtools());
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // When FastUnloadController is used, devtools frontend will be detached
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // from the browser window at this point which means we've already fired
759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // beforeunload.
760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (browser->tab_strip_model()->empty())
761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return true;
762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::WebContents* contents =
763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser->tab_strip_model()->GetWebContentsAt(0);
764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow* window = AsDevToolsWindow(contents->GetRenderViewHost());
765a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!window)
766a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return window->intercepted_page_beforeunload_;
768f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
769f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
771f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DevToolsWindow::OnPageCloseCanceled(content::WebContents* contents) {
772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow *window =
773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DevToolsWindow::GetInstanceForInspectedRenderViewHost(
774f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          contents->GetRenderViewHost());
775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!window)
776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window->intercepted_page_beforeunload_ = false;
778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Propagate to devtools opened on devtools if any.
779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsWindow::OnPageCloseCanceled(window->web_contents());
780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
782a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::DevToolsWindow(Profile* profile,
783a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               const GURL& url,
7842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                               content::RenderViewHost* inspected_rvh,
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               bool can_dock)
786a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : profile_(profile),
787a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser_(NULL),
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_docked_(true),
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      can_dock_(can_dock),
7900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      device_listener_enabled_(false),
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // This initialization allows external front-end to work without changes.
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // We don't wait for docking call, but instead immediately show undocked.
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Passing "dockSide=undocked" parameter ensures proper UI.
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      load_state_(can_dock ? kNotLoaded : kIsDockedSet),
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      action_on_load_(DevToolsToggleAction::NoOp()),
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ignore_set_is_docked_(false),
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      intercepted_page_beforeunload_(false),
7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
7992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_contents_ =
8002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::WebContents::Create(content::WebContents::CreateParams(profile));
8011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  frontend_contents_observer_.reset(new FrontendWebContentsObserver(this));
8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  web_contents_->GetMutableRendererPrefs()->can_accept_load_drops = false;
8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Set up delegate, so we get fully-functional window immediately.
8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // It will not appear in UI though until |load_state_ == kLoadCompleted|.
8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  web_contents_->SetDelegate(this);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
808a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  web_contents_->GetController().LoadURL(url, content::Referrer(),
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
810a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
8122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      web_contents_, this));
813a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_helper_.reset(new DevToolsFileHelper(web_contents_, profile));
8142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_system_indexer_ = new DevToolsFileSystemIndexer();
81523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  extensions::ChromeExtensionWebContentsObserver::CreateForWebContents(
81623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      web_contents_);
817a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
818a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  g_instances.Get().push_back(this);
8192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
820a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Wipe out page icon so that the default application icon is used.
8212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::NavigationEntry* entry =
8222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      web_contents_->GetController().GetActiveEntry();
823a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  entry->GetFavicon().image = gfx::Image();
824a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  entry->GetFavicon().valid = true;
825a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
826a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Register on-load actions.
827a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(
8282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
829a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::Source<ThemeService>(
830a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          ThemeServiceFactory::GetForProfile(profile_)));
8312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
832a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // There is no inspected_rvh in case of shared workers.
833a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (inspected_rvh)
834a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    inspected_contents_observer_.reset(new InspectedWebContentsObserver(
8352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        content::WebContents::FromRenderViewHost(inspected_rvh)));
83658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
83758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  embedder_message_dispatcher_.reset(
838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DevToolsEmbedderMessageDispatcher::createForDevToolsFrontend(this));
839c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_forwarder_.reset(new DevToolsEventForwarder(this));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
843a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::Create(
844a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile,
845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& frontend_url,
8462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh,
847424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool shared_worker_frontend,
848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool external_frontend,
849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    bool can_dock) {
850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (inspected_rvh) {
851a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Check for a place to dock.
852a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Browser* browser = NULL;
853a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int tab;
854a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::WebContents* inspected_web_contents =
855a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        content::WebContents::FromRenderViewHost(inspected_rvh);
856a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!FindInspectedBrowserAndTabIndex(inspected_web_contents,
857a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         &browser, &tab) ||
858a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        inspected_rvh->GetMainFrame()->IsCrossProcessSubframe() ||
859a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        browser->is_type_popup()) {
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      can_dock = false;
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
863a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
864a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Create WebContents with devtools.
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL url(GetDevToolsURL(profile, frontend_url,
866424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          shared_worker_frontend,
867a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          external_frontend,
868a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          can_dock));
8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new DevToolsWindow(profile, url, inspected_rvh, can_dock);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL DevToolsWindow::GetDevToolsURL(Profile* profile,
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    const GURL& base_url,
875424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                    bool shared_worker_frontend,
876a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    bool external_frontend,
877a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                    bool can_dock) {
8788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (base_url.SchemeIs("data"))
8798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return base_url;
8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string frontend_url(
8822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec());
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile);
8842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(tp);
8852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string url_string(
8862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      frontend_url +
8872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      ((frontend_url.find("?") == std::string::npos) ? "?" : "&") +
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "dockSide=undocked" + // TODO(dgozman): remove this support in M38.
8892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "&toolbarColor=" +
8902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
8912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "&textColor=" +
8922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)));
8932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (shared_worker_frontend)
8942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    url_string += "&isSharedWorker=true";
895424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (external_frontend)
896424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    url_string += "&remoteFrontend=true";
897a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (can_dock)
898a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    url_string += "&can_dock=true";
8992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(
9002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      switches::kEnableDevToolsExperiments))
9012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    url_string += "&experiments=true";
902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  url_string += "&updateAppcache";
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(url_string);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
906a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
907a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::FindDevToolsWindow(
908a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsAgentHost* agent_host) {
9095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsWindows* instances = g_instances.Pointer();
9102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
9112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
9122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       ++it) {
913a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (manager->GetDevToolsAgentHostFor((*it)->frontend_host_.get()) ==
914a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        agent_host)
915a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return *it;
916a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
917a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
918a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
920a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
9212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow* DevToolsWindow::AsDevToolsWindow(
9222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* window_rvh) {
923a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (g_instances == NULL)
924a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return NULL;
9255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsWindows* instances = g_instances.Pointer();
9262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
9272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       ++it) {
928a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if ((*it)->web_contents_->GetRenderViewHost() == window_rvh)
929a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return *it;
930a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
931a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
932a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
933a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
934a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::Observe(int type,
935a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             const content::NotificationSource& source,
936a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             const content::NotificationDetails& details) {
937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
938f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateTheme();
939a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
940a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochcontent::WebContents* DevToolsWindow::OpenURLFromTab(
9422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
9432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::OpenURLParams& params) {
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(source == web_contents_);
9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!params.url.SchemeIs(content::kChromeDevToolsScheme)) {
946a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::WebContents* inspected_web_contents = GetInspectedWebContents();
9472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return inspected_web_contents ?
9482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        inspected_web_contents->OpenURL(params) : NULL;
949a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
950a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
952a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent_host(
953a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      manager->GetDevToolsAgentHostFor(frontend_host_.get()));
954a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!agent_host.get())
955a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return NULL;
956a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  manager->ClientHostClosing(frontend_host_.get());
957a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  manager->RegisterDevToolsClientHostFor(agent_host.get(),
958a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         frontend_host_.get());
959a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::NavigationController::LoadURLParams load_url_params(params.url);
9615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  web_contents_->GetController().LoadURLWithParams(load_url_params);
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return web_contents_;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::AddNewContents(content::WebContents* source,
9662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    content::WebContents* new_contents,
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WindowOpenDisposition disposition,
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& initial_pos,
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool user_gesture,
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* was_blocked) {
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->GetDelegate()->AddNewContents(
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source, new_contents, disposition, initial_pos, user_gesture,
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        was_blocked);
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
979a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CloseContents(content::WebContents* source) {
9805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(is_docked_);
9815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will prevent any activity after frontend is loaded.
9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_on_load_ = DevToolsToggleAction::NoOp();
9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ignore_set_is_docked_ = true;
9844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update dev tools to reflect removed dev tools window.
9854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BrowserWindow* inspected_window = GetInspectedBrowserWindow();
9864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (inspected_window)
9874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    inspected_window->UpdateDevTools();
9884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // In case of docked web_contents_, we own it so delete here.
989f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Embedding DevTools window will be deleted as a result of
990f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // WebContentsDestroyed callback.
9914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delete web_contents_;
9924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::ContentsZoomChange(bool zoom_in) {
9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(is_docked_);
9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome_page_zoom::Zoom(web_contents(),
9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      zoom_in ? content::PAGE_ZOOM_IN : content::PAGE_ZOOM_OUT);
9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DevToolsWindow::BeforeUnloadFired(content::WebContents* tab,
10014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       bool proceed,
10024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       bool* proceed_to_fire_unload) {
1003f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!intercepted_page_beforeunload_) {
1004f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Docked devtools window closed directly.
1005f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (proceed) {
1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::DevToolsManager::GetInstance()->ClientHostClosing(
1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          frontend_host_.get());
1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *proceed_to_fire_unload = proceed;
1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Inspected page is attempting to close.
1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WebContents* inspected_web_contents = GetInspectedWebContents();
1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (proceed) {
1014c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      inspected_web_contents->DispatchBeforeUnload(false);
1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool should_proceed;
1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      inspected_web_contents->GetDelegate()->BeforeUnloadFired(
1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          inspected_web_contents, false, &should_proceed);
1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(!should_proceed);
1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *proceed_to_fire_unload = false;
10224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1023a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1024a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::PreHandleKeyboardEvent(
10262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
10272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NativeWebKeyboardEvent& event,
10282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    bool* is_keyboard_shortcut) {
10295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_) {
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
10312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (inspected_window) {
10322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return inspected_window->PreHandleKeyboardEvent(event,
10332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                      is_keyboard_shortcut);
10342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::HandleKeyboardEvent(
10402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
10412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NativeWebKeyboardEvent& event) {
10425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event.windowsKeyCode == 0x08) {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Do not navigate back in history on Windows (http://crbug.com/74156).
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->HandleKeyboardEvent(event);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1053a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager() {
1054a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
10552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return (inspected_web_contents && inspected_web_contents->GetDelegate()) ?
10562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      inspected_web_contents->GetDelegate()->GetJavaScriptDialogManager() :
10572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::WebContentsDelegate::GetJavaScriptDialogManager();
1058a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1060a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::ColorChooser* DevToolsWindow::OpenColorChooser(
10612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* web_contents,
1062a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    SkColor initial_color,
1063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<content::ColorSuggestion>& suggestions) {
1064a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return chrome::ShowColorChooser(web_contents, initial_color);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::RunFileChooser(content::WebContents* web_contents,
10682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    const content::FileChooserParams& params) {
1069a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSelectHelper::RunFileChooser(web_contents, params);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::WebContentsFocused(content::WebContents* contents) {
1073a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* inspected_browser = NULL;
1074a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int inspected_tab_index = -1;
10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_ && FindInspectedBrowserAndTabIndex(GetInspectedWebContents(),
1076a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                    &inspected_browser,
10772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                    &inspected_tab_index))
1078a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    inspected_browser->window()->WebContentsFocused(contents);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool DevToolsWindow::PreHandleGestureEvent(
10825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::WebContents* source,
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const blink::WebGestureEvent& event) {
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Disable pinch zooming.
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return event.type == blink::WebGestureEvent::GesturePinchBegin ||
10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      event.type == blink::WebGestureEvent::GesturePinchUpdate ||
10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      event.type == blink::WebGestureEvent::GesturePinchEnd;
10885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
109058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void DevToolsWindow::DispatchOnEmbedder(const std::string& message) {
10914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string method;
10924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ListValue empty_params;
10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ListValue* params = &empty_params;
10944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
10954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
10964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
10974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!parsed_message ||
10984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !parsed_message->GetAsDictionary(&dict) ||
10994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !dict->GetString(kFrontendHostMethod, &method) ||
11004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      (dict->HasKey(kFrontendHostParams) &&
11014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          !dict->GetList(kFrontendHostParams, &params))) {
11024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid message was sent to embedder: " << message;
11034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
11044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int id = 0;
11074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->GetInteger(kFrontendHostId, &id);
11084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string error;
1110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  embedder_message_dispatcher_->Dispatch(method, params, &error);
11114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (id) {
11124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id));
11134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error));
11144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       id_value.get(), error_value.get(), NULL);
11164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
111758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
111858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::ActivateWindow() {
11205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_ && GetInspectedBrowserWindow())
11212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    web_contents_->GetView()->Focus();
11225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!is_docked_ && !browser_->window()->IsActive())
11232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    browser_->window()->Activate();
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DevToolsWindow::ActivateContents(content::WebContents* contents) {
11275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_) {
11284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::WebContents* inspected_tab = this->GetInspectedWebContents();
11294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    inspected_tab->GetDelegate()->ActivateContents(inspected_tab);
11304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
11314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    browser_->window()->Activate();
11324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
11334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::CloseWindow() {
11365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(is_docked_);
11375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // This will prevent any activity after frontend is loaded.
11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_on_load_ = DevToolsToggleAction::NoOp();
11395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ignore_set_is_docked_ = true;
1140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  web_contents_->DispatchBeforeUnload(false);
11414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
11424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
11435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::SetContentsInsets(
11445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int top, int left, int bottom, int right) {
11455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Insets insets(top, left, bottom, right);
11465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetContentsResizingStrategy(insets, contents_resizing_strategy_.min_size());
11475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
11485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::SetContentsResizingStrategy(
11505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Insets& insets, const gfx::Size& min_size) {
11515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DevToolsContentsResizingStrategy strategy(insets, min_size);
11525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (contents_resizing_strategy_.Equals(strategy))
11535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
11545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  contents_resizing_strategy_.CopyFrom(strategy);
11565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_docked_) {
11575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Update inspected window.
11585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
11595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (inspected_window)
11605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      inspected_window->UpdateDevTools();
11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
11635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::InspectElementCompleted() {
11655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!inspect_element_start_time_.is_null()) {
11665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_TIMES("DevTools.InspectElement",
11675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::TimeTicks::Now() - inspect_element_start_time_);
11685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    inspect_element_start_time_ = base::TimeTicks();
11695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::MoveWindow(int x, int y) {
11735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!is_docked_) {
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect bounds = browser_->window()->GetBounds();
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.Offset(x, y);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser_->window()->SetBounds(bounds);
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::SetIsDockedAndShowImmediatelyForTest(bool is_docked) {
11815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!is_docked || can_dock_);
11825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ == kLoadCompleted) {
11835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetIsDocked(is_docked);
11845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
11855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    is_docked_ = is_docked;
11865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Load is completed when both kIsDockedSet and kOnLoadFired happened.
11875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Note that kIsDockedSet may be already set when can_dock_ is false.
11885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_state_ = load_state_ == kOnLoadFired ? kLoadCompleted : kIsDockedSet;
11895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Note that action_on_load_ will be performed after the load is actually
11905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // completed. For now, just show the window.
11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Show(DevToolsToggleAction::Show());
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (load_state_ == kLoadCompleted)
11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LoadCompleted();
11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ignore_set_is_docked_ = true;
11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::SetIsDocked(bool dock_requested) {
11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ignore_set_is_docked_)
12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(can_dock_ || !dock_requested);
12035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!can_dock_)
12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    dock_requested = false;
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool was_docked = is_docked_;
12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  is_docked_ = dock_requested;
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ != kLoadCompleted) {
12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // This is a first time call we waited for to initialize.
12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_state_ = load_state_ == kOnLoadFired ? kLoadCompleted : kIsDockedSet;
12125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (load_state_ == kLoadCompleted)
12135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LoadCompleted();
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dock_requested == was_docked)
12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (dock_requested && !was_docked) {
12212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // Detach window from the external devtools browser. It will lead to
12222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // the browser object's close and delete. Remove observer first.
12232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    TabStripModel* tab_strip_model = browser_->tab_strip_model();
12242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    tab_strip_model->DetachWebContentsAt(
12252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        tab_strip_model->GetIndexOfWebContents(web_contents_));
12262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    browser_ = NULL;
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (!dock_requested && was_docked) {
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update inspected window to hide split and reset it.
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->UpdateDevTools();
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  Show(DevToolsToggleAction::Show());
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::OpenInNewTab(const std::string& url) {
12382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::OpenURLParams params(
12392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
12402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::PAGE_TRANSITION_LINK, false);
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
12432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->OpenURL(params);
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::HostDesktopType host_desktop_type;
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_) {
12472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = browser_->host_desktop_type();
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // There should always be a browser when there are no inspected web
12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // contents.
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = chrome::GetActiveDesktop();
12532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BrowserList* browser_list =
12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BrowserList::GetInstance(host_desktop_type);
12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (BrowserList::const_iterator it = browser_list->begin();
12582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != browser_list->end(); ++it) {
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*it)->type() == Browser::TYPE_TABBED) {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*it)->OpenURL(params);
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SaveToFile(const std::string& url,
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& content,
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool save_as) {
12702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->Save(url, content, save_as,
12712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     base::Bind(&DevToolsWindow::FileSavedAs,
1272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                weak_factory_.GetWeakPtr(), url),
1273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     base::Bind(&DevToolsWindow::CanceledFileSaveAs,
12742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                weak_factory_.GetWeakPtr(), url));
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendToFile(const std::string& url,
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const std::string& content) {
12792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->Append(url, content,
12802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       base::Bind(&DevToolsWindow::AppendedTo,
12812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  weak_factory_.GetWeakPtr(), url));
12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RequestFileSystems() {
12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
12862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->RequestFileSystems(base::Bind(
12872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      &DevToolsWindow::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::AddFileSystem() {
12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->AddFileSystem(
12932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
12942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
12952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 weak_factory_.GetWeakPtr()));
12962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RemoveFileSystem(const std::string& file_system_path) {
12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->RemoveFileSystem(file_system_path);
13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue file_system_path_value(file_system_path);
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
13032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, NULL, NULL);
13042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
13052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DevToolsWindow::UpgradeDraggedFileSystemPermissions(
1307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& file_system_url) {
13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
1309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  file_helper_->UpgradeDraggedFileSystemPermissions(
1310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      file_system_url,
1311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
1312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
1313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
1314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexPath(int request_id,
13172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                               const std::string& file_system_path) {
13180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
13202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!file_helper_->IsFileSystemAdded(file_system_path)) {
13212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IndexingDone(request_id, file_system_path);
13222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
13232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1324ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  indexing_jobs_[request_id] =
1325ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
1326ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          file_system_indexer_->IndexPath(
1327ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              file_system_path,
1328ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingTotalWorkCalculated,
1329ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1331ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path),
1332ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingWorked,
1333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path),
1336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingDone,
1337ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1338ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path)));
13402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
13412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::StopIndexing(int request_id) {
13430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  IndexingJobsMap::iterator it = indexing_jobs_.find(request_id);
13452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (it == indexing_jobs_.end())
13462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
13472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  it->second->Stop();
13482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.erase(it);
13492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
13502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
13512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::SearchInPath(int request_id,
13522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& file_system_path,
13532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& query) {
13540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(content::kChromeDevToolsScheme));
13562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!file_helper_->IsFileSystemAdded(file_system_path)) {
13572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SearchCompleted(request_id, file_system_path, std::vector<std::string>());
13582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
13592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
13602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_system_indexer_->SearchInPath(file_system_path,
13612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                     query,
13622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                     Bind(&DevToolsWindow::SearchCompleted,
13632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          weak_factory_.GetWeakPtr(),
13642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          request_id,
13652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          file_system_path));
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::ZoomIn() {
13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_IN);
13705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::ZoomOut() {
13735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_OUT);
13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::ResetZoom() {
13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  chrome_page_zoom::Zoom(web_contents(), content::PAGE_ZOOM_RESET);
13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1380a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DevToolsWindow::OpenUrlOnRemoteDeviceAndInspect(
1381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& browser_id,
1382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& url) {
1383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (remote_targets_handler_)
1384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    remote_targets_handler_->OpenAndInspect(browser_id, url, profile_);
1385a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1387a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DevToolsWindow::StartRemoteDevicesListener() {
1388a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  remote_targets_handler_ = DevToolsRemoteTargetsUIHandler::CreateForAdb(
1389a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(&DevToolsWindow::PopulateRemoteDevices,
1390a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 base::Unretained(this)),
1391a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      profile_);
1392a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1394a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DevToolsWindow::StopRemoteDevicesListener() {
1395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  remote_targets_handler_.reset();
1396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
13980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid DevToolsWindow::EnableRemoteDeviceCounter(bool enable) {
13990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DevToolsAndroidBridge* adb_bridge =
14000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      DevToolsAndroidBridge::Factory::GetForProfile(profile_);
14010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!adb_bridge)
14020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
14030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
14040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(device_listener_enabled_ != enable);
14050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  device_listener_enabled_ = enable;
14060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (enable)
14070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    adb_bridge->AddDeviceCountListener(this);
14080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else
14090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    adb_bridge->RemoveDeviceCountListener(this);
14100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
14110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
14120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid DevToolsWindow::DeviceCountChanged(int count) {
14130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::FundamentalValue value(count);
14140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CallClientFunction(
14150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      "InspectorFrontendAPI.setRemoteDeviceCount", &value, NULL, NULL);
14160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
14170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1418a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DevToolsWindow::PopulateRemoteDevices(
1419a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const std::string& source,
1420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    scoped_ptr<base::ListValue> targets) {
1421a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CallClientFunction(
1422a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      "InspectorFrontendAPI.populateRemoteDevices", targets.get(), NULL, NULL);
1423a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1424a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::FileSavedAs(const std::string& url) {
14265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue url_value(url);
14272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.savedURL", &url_value, NULL, NULL);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1430a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DevToolsWindow::CanceledFileSaveAs(const std::string& url) {
14315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue url_value(url);
1432a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.canceledSaveURL",
1433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                     &url_value, NULL, NULL);
1434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendedTo(const std::string& url) {
14375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue url_value(url);
14382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value, NULL,
14392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     NULL);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemsLoaded(
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
14445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue file_systems_value;
14452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (size_t i = 0; i < file_systems.size(); ++i)
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
14482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_systems_value, NULL, NULL);
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemAdded(
14522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DevToolsFileHelper::FileSystem& file_system) {
1453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::StringValue> error_string_value(
1454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new base::StringValue(std::string()));
1455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::DictionaryValue> file_system_value;
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!file_system.file_system_path.empty())
1457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    file_system_value.reset(CreateFileSystemValue(file_system));
14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
1459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     error_string_value.get(), file_system_value.get(), NULL);
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingTotalWorkCalculated(
14632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int request_id,
14642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::string& file_system_path,
14652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int total_work) {
14660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
14685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue file_system_path_value(file_system_path);
14692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue total_work_value(total_work);
14702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
14712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &request_id_value, &file_system_path_value,
14722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &total_work_value);
14732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
14742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingWorked(int request_id,
14762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    const std::string& file_system_path,
14772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    int worked) {
14780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
14805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue file_system_path_value(file_system_path);
14812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue worked_value(worked);
14822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value,
14832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, &worked_value);
14842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
14852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingDone(int request_id,
14872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& file_system_path) {
14882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.erase(request_id);
14890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
14902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
14915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue file_system_path_value(file_system_path);
14922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value,
14932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, NULL);
14942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
14952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
14962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::SearchCompleted(
14972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int request_id,
14982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::string& file_system_path,
14992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::vector<std::string>& file_paths) {
15000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
15015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue file_paths_value;
1502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (std::vector<std::string>::const_iterator it(file_paths.begin());
1503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       it != file_paths.end(); ++it) {
15042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    file_paths_value.AppendString(*it);
15052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
15062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
15075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::StringValue file_system_path_value(file_system_path);
15082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value,
15092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, &file_paths_value);
15102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
15112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::ShowDevToolsConfirmInfoBar(
1513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& message,
15142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const InfoBarCallback& callback) {
15152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsConfirmInfoBarDelegate::Create(
15165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      is_docked_ ?
15172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          InfoBarService::FromWebContents(GetInspectedWebContents()) :
15182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          InfoBarService::FromWebContents(web_contents_),
15192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      callback, message);
1520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CreateDevToolsBrowser() {
1523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string wp_key = GetDevToolsWindowPlacementPrefKey();
1524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
15255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str());
1526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!wp_pref || wp_pref->empty()) {
1527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DictionaryPrefUpdate update(prefs, wp_key.c_str());
15285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* defaults = update.Get();
1529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("left", 100);
1530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("top", 100);
1531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("right", 740);
1532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("bottom", 740);
1533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetBoolean("maximized", false);
1534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetBoolean("always_on_top", false);
1535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1536a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  browser_ = new Browser(Browser::CreateParams::CreateForDevTools(
15382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      profile_,
15392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      chrome::GetHostDesktopTypeForNativeView(
15402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          web_contents_->GetView()->GetNativeView())));
1541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  browser_->tab_strip_model()->AddWebContents(
1542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL,
1543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      TabStripModel::ADD_ACTIVE);
1544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GetRenderViewHost()->SyncRendererPrefs();
1545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1546a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1547a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// static
1548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool DevToolsWindow::FindInspectedBrowserAndTabIndex(
1549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    content::WebContents* inspected_web_contents, Browser** browser, int* tab) {
1550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!inspected_web_contents)
1551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
1552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1554a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int tab_index = it->tab_strip_model()->GetIndexOfWebContents(
1555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        inspected_web_contents);
1556a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (tab_index != TabStripModel::kNoTab) {
1557a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *browser = *it;
1558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *tab = tab_index;
1559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return true;
1560a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return false;
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() {
1566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* browser = NULL;
1567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int tab;
1568a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return FindInspectedBrowserAndTabIndex(GetInspectedWebContents(),
1569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         &browser, &tab) ?
1570a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser->window() : NULL;
157190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
157290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::DoAction(const DevToolsToggleAction& action) {
15745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (action.type()) {
15750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case DevToolsToggleAction::kShowConsole:
15762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("InspectorFrontendAPI.showConsole", NULL, NULL, NULL);
1577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
15782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
15790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case DevToolsToggleAction::kInspect:
15802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("InspectorFrontendAPI.enterInspectElementMode", NULL,
15812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                         NULL, NULL);
15822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      break;
15832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
15840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case DevToolsToggleAction::kShow:
15850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case DevToolsToggleAction::kToggle:
1586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Do nothing.
1587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
15882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
15890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    case DevToolsToggleAction::kReveal: {
15900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      const DevToolsToggleAction::RevealParams* params =
15915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          action.params();
15920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      CHECK(params);
15930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::StringValue url_value(params->url);
15940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::FundamentalValue line_value(static_cast<int>(params->line_number));
15950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::FundamentalValue column_value(
15960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)          static_cast<int>(params->column_number));
15970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      CallClientFunction("InspectorFrontendAPI.revealSourceLine",
15980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         &url_value,
15990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         &line_value,
16000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         &column_value);
16010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      break;
16020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    }
1603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
1604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      NOTREACHED();
16052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      break;
1606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::UpdateTheme() {
1610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
16112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(tp);
16122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
16132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string command("InspectorFrontendAPI.setToolbarColors(\"" +
16142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
16152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "\", \"" +
16162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) +
16172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "\")");
1618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  web_contents_->GetMainFrame()->ExecuteJavaScript(base::ASCIIToUTF16(command));
1619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::AddDevToolsExtensionsToClient() {
1622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
1623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (inspected_web_contents) {
1624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SessionTabHelper* session_tab_helper =
1625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        SessionTabHelper::FromWebContents(inspected_web_contents);
1626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (session_tab_helper) {
1627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::FundamentalValue tabId(session_tab_helper->session_id().id());
16282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("WebInspector.setInspectedTabId", &tabId, NULL, NULL);
1629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
16312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Profile* profile =
1633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
1634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
1635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      profile->GetOriginalProfile())->extension_service();
1636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!extension_service)
1637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
16385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const extensions::ExtensionSet* extensions = extension_service->extensions();
1639a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::ListValue results;
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator extension(extensions->begin());
1642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       extension != extensions->end(); ++extension) {
1643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      continue;
16455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* extension_info = new base::DictionaryValue();
1646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extension_info->Set(
1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        "startPage",
16485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new base::StringValue(
1649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            extensions::ManifestURL::GetDevToolsPage(extension->get()).spec()));
16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    extension_info->Set("name", new base::StringValue((*extension)->name()));
16512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    extension_info->Set(
16522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        "exposeExperimentalAPIs",
16532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        new base::FundamentalValue((*extension)->HasAPIPermission(
16542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            extensions::APIPermission::kExperimental)));
1655a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    results.Append(extension_info);
1656a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
16572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("WebInspector.addExtensions", &results, NULL, NULL);
1658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1659a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1660a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CallClientFunction(const std::string& function_name,
16615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        const base::Value* arg1,
16625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        const base::Value* arg2,
16635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        const base::Value* arg3) {
1664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string params;
1665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (arg1) {
1666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string json;
1667a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::JSONWriter::Write(arg1, &json);
1668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    params.append(json);
1669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (arg2) {
1670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::JSONWriter::Write(arg2, &json);
1671a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      params.append(", " + json);
16722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      if (arg3) {
16732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        base::JSONWriter::Write(arg3, &json);
16742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        params.append(", " + json);
16752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      }
1676a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 javascript =
1679a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::UTF8ToUTF16(function_name + "(" + params + ");");
1680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  web_contents_->GetMainFrame()->ExecuteJavaScript(javascript);
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::UpdateBrowserToolbar() {
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserWindow* inspected_window = GetInspectedBrowserWindow();
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (inspected_window)
16863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    inspected_window->UpdateToolbar(NULL);
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::WebContents* DevToolsWindow::GetInspectedWebContents() {
16902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return inspected_contents_observer_ ?
16912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      inspected_contents_observer_->web_contents() : NULL;
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
16941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() {
16955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We could be in kLoadCompleted state already if frontend reloads itself.
16965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ != kLoadCompleted) {
16975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Load is completed when both kIsDockedSet and kOnLoadFired happened.
16985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Here we set kOnLoadFired.
16995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_state_ = load_state_ == kIsDockedSet ? kLoadCompleted : kOnLoadFired;
17005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
17015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ == kLoadCompleted)
17025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LoadCompleted();
17035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::LoadCompleted() {
17065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Show(action_on_load_);
17075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  action_on_load_ = DevToolsToggleAction::NoOp();
17081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  UpdateTheme();
17091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AddDevToolsExtensionsToClient();
17105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!load_completed_callback_.is_null()) {
17115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_completed_callback_.Run();
17125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    load_completed_callback_ = base::Closure();
17135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
17145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DevToolsWindow::SetLoadCompletedCallback(const base::Closure& closure) {
17175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (load_state_ == kLoadCompleted) {
17185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!closure.is_null())
17195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      closure.Run();
17205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
17215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
17225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  load_completed_callback_ = closure;
17231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1724c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1725c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid DevToolsWindow::SetWhitelistedShortcuts(
1726c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const std::string& message) {
1727c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_forwarder_->SetWhitelistedShortcuts(message);
1728c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1729c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1730c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool DevToolsWindow::ForwardKeyboardEvent(
1731c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const content::NativeWebKeyboardEvent& event) {
1732c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return event_forwarder_->ForwardEvent(event);
1733c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1734