devtools_window.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/json/json_reader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/debugger/debugger_api.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/extension_web_contents_observer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/file_select_helper.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_tab_helper.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/webui/devtools_ui.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/render_messages.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/browser/browser_thread.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_client_host.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_manager.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/load_notification_details.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/page_transition_types.h"
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsConfirmInfoBarDelegate ---------------------------------------------
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // If |infobar_service| is NULL, runs |callback| with a single argument with
752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // value "false".  Otherwise, creates a dev tools confirm infobar and delegate
762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // and adds the inofbar to |infobar_service|.
772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  static void Create(InfoBarService* infobar_service,
782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     const DevToolsWindow::InfoBarCallback& callback,
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     const string16& message);
802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch private:
822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsConfirmInfoBarDelegate(
832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      InfoBarService* infobar_service,
842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      const DevToolsWindow::InfoBarCallback& callback,
852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      const string16& message);
862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~DevToolsConfirmInfoBarDelegate();
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual string16 GetMessageText() const OVERRIDE;
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool Accept() OVERRIDE;
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual bool Cancel() OVERRIDE;
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindow::InfoBarCallback callback_;
942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const string16 message_;
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(DevToolsConfirmInfoBarDelegate);
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsConfirmInfoBarDelegate::Create(
1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    InfoBarService* infobar_service,
1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const DevToolsWindow::InfoBarCallback& callback,
1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const string16& message) {
1032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!infobar_service) {
1042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    callback.Run(false);
1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
1062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
1092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      new DevToolsConfirmInfoBarDelegate(infobar_service, callback, message)));
1102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsConfirmInfoBarDelegate::DevToolsConfirmInfoBarDelegate(
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    InfoBarService* infobar_service,
1142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const DevToolsWindow::InfoBarCallback& callback,
1152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const string16& message)
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : ConfirmInfoBarDelegate(infobar_service),
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      callback_(callback),
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      message_(message) {
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsConfirmInfoBarDelegate::~DevToolsConfirmInfoBarDelegate() {
1222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!callback_.is_null())
1232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    callback_.Run(false);
1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)string16 DevToolsConfirmInfoBarDelegate::GetMessageText() const {
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return message_;
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)string16 DevToolsConfirmInfoBarDelegate::GetButtonLabel(
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    InfoBarButton button) const {
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsConfirmInfoBarDelegate::Accept() {
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Run(true);
138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Reset();
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsConfirmInfoBarDelegate::Cancel() {
143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Run(false);
144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback_.Reset();
145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow::InspectedWebContentsObserver -------------------------------
150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevToolsWindow::InspectedWebContentsObserver
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  explicit InspectedWebContentsObserver(content::WebContents* web_contents);
1552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~InspectedWebContentsObserver();
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* web_contents() {
158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return WebContentsObserver::web_contents();
159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch private:
1622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(InspectedWebContentsObserver);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::InspectedWebContentsObserver::InspectedWebContentsObserver(
166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::WebContents* web_contents)
167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : WebContentsObserver(web_contents) {
168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow::InspectedWebContentsObserver::~InspectedWebContentsObserver() {
1712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow::FrontendWebContentsObserver --------------------------------
175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DevToolsWindow::FrontendWebContentsObserver
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  explicit FrontendWebContentsObserver(DevToolsWindow* window);
1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  virtual ~FrontendWebContentsObserver();
181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // contents::WebContentsObserver:
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AboutToNavigateRenderView(
1852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::RenderViewHost* render_view_host) OVERRIDE;
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void DocumentOnLoadCompletedInMainFrame(int32 page_id) OVERRIDE;
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DevToolsWindow* devtools_window_;
1892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DISALLOW_COPY_AND_ASSIGN(FrontendWebContentsObserver);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::FrontendWebContentsObserver::FrontendWebContentsObserver(
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DevToolsWindow* devtools_window)
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : WebContentsObserver(devtools_window->web_contents()),
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      devtools_window_(devtools_window) {
196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow::FrontendWebContentsObserver::~FrontendWebContentsObserver() {
1992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::FrontendWebContentsObserver::AboutToNavigateRenderView(
202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::RenderViewHost* render_view_host) {
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DevToolsWindow::FrontendWebContentsObserver::
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DocumentOnLoadCompletedInMainFrame(int32 page_id) {
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  devtools_window_->DocumentOnLoadCompletedInMainFrame();
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// DevToolsWindow -------------------------------------------------------------
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochtypedef std::vector<DevToolsWindow*> DevToolsWindows;
2162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbase::LazyInstance<DevToolsWindows>::Leaky g_instances =
2172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    LAZY_INSTANCE_INITIALIZER;
2182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrefBottom[] = "dock_bottom";
2202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrefRight[] = "dock_right";
2212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kPrefUndocked[] = "undocked";
2222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kDockSideBottom[] = "bottom";
2242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kDockSideRight[] = "right";
2252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kDockSideUndocked[] = "undocked";
2262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char kDockSideMinimized[] = "minimized";
2272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostId[] = "id";
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostMethod[] = "method";
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static const char kFrontendHostParams[] = "params";
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst int kMinContentsSize = 50;
2332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string SkColorToRGBAString(SkColor color) {
2352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // We avoid StringPrintf because it will use locale specific formatters for
2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // the double (e.g. ',' instead of '.' in German).
2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return "rgba(" + base::IntToString(SkColorGetR(color)) + "," +
2382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::IntToString(SkColorGetG(color)) + "," +
2392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::IntToString(SkColorGetB(color)) + "," +
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::DoubleToString(SkColorGetA(color) / 255.0) + ")";
241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DictionaryValue* CreateFileSystemValue(
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsFileHelper::FileSystem file_system) {
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DictionaryValue* file_system_value = new DictionaryValue();
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("fileSystemName", file_system.file_system_name);
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("rootURL", file_system.root_url);
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_system_value->SetString("fileSystemPath", file_system.file_system_path);
249a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return file_system_value;
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochconst char DevToolsWindow::kDevToolsApp[] = "DevToolsApp";
2552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::~DevToolsWindow() {
2572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindows* instances = &g_instances.Get();
2582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindows::iterator it(
2592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      std::find(instances->begin(), instances->end(), this));
2602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(it != instances->end());
2612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  instances->erase(it);
2622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
263ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (IndexingJobsMap::const_iterator jobs_it(indexing_jobs_.begin());
264ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       jobs_it != indexing_jobs_.end(); ++jobs_it) {
2652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    jobs_it->second->Stop();
266ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
2672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.clear();
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DevToolsWindow::GetDevToolsWindowPlacementPrefKey() {
2722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return std::string(prefs::kBrowserWindowPlacement) + "_" +
2732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      std::string(kDevToolsApp);
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DevToolsWindow::RegisterProfilePrefs(
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterBooleanPref(
2802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsOpenDocked, true,
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterStringPref(
2832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsDockSide, kDockSideBottom,
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsEditedFiles,
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsFileSystemPaths,
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registry->RegisterStringPref(
2922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsAdbKey, std::string(),
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetDevToolsWindowPlacementPrefKey().c_str(),
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registry->RegisterBooleanPref(
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      prefs::kDevToolsDiscoverUsbDevicesEnabled,
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      false,
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  registry->RegisterBooleanPref(
3042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingEnabled,
3052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      false,
3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  registry->RegisterBooleanPref(
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      prefs::kDevToolsPortForwardingDefaultSet,
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      false,
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registry->RegisterDictionaryPref(
3122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingConfig,
3132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab(
3182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* inspected_web_contents) {
3192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!inspected_web_contents ||
3202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      !DevToolsAgentHost::HasFor(inspected_web_contents->GetRenderViewHost()))
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inspected_web_contents->GetRenderViewHost()));
324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent.get());
3252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return (window && window->IsDocked()) ? window : NULL;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochbool DevToolsWindow::IsDevToolsWindow(content::RenderViewHost* window_rvh) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AsDevToolsWindow(window_rvh) != NULL;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker(
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsAgentHost* worker_agent) {
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(worker_agent);
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window = DevToolsWindow::CreateDevToolsWindowForWorker(profile);
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Will disconnect the current client host if there is one.
3412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
3422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        worker_agent, window->frontend_host_.get());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return Create(profile, GURL(), NULL, DEVTOOLS_DOCK_SIDE_UNDOCKED, true,
352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                false);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindow(
3572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ToggleDevToolsWindow(inspected_rvh, true,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DEVTOOLS_TOGGLE_ACTION_SHOW);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsToggleAction action) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (action == DEVTOOLS_TOGGLE_ACTION_TOGGLE && browser->is_devtools()) {
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->CloseAllTabs();
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return ToggleDevToolsWindow(
3722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost(),
3732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      action == DEVTOOLS_TOGGLE_ACTION_INSPECT, action);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::OpenExternalFrontend(
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile* profile,
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& frontend_url,
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::DevToolsAgentHost* agent_host) {
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent_host);
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL,
384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                    DEVTOOLS_DOCK_SIDE_UNDOCKED, false, true);
3852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        agent_host, window->frontend_host_.get());
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
3932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh,
394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    bool force_open,
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsToggleAction action) {
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
3982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent.get());
400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool do_open = force_open;
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!window) {
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile = Profile::FromBrowserContext(
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        inspected_rvh->GetProcess()->GetBrowserContext());
404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsDockSide dock_side = GetDockSideFromPrefs(profile);
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    window = Create(profile, GURL(), inspected_rvh, dock_side, false, false);
406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    manager->RegisterDevToolsClientHostFor(agent.get(),
407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                           window->frontend_host_.get());
408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    do_open = true;
409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Update toolbar to reflect DevTools changes.
412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  window->UpdateBrowserToolbar();
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // If window is docked and visible, we hide it on toggle. If window is
415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // undocked, we show (activate) it. If window is minimized, we maximize it.
416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (window->dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED)
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    window->Restore();
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  else if (!window->IsDocked() || do_open)
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    window->Show(action);
420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  else
421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    window->CloseWindow();
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return window;
424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
4272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::InspectElement(content::RenderViewHost* inspected_rvh,
428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    int x,
429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                    int y) {
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  agent->InspectElement(x, y);
433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // TODO(loislo): we should initiate DevTools window opening from within
434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // renderer. Otherwise, we still can hit a race condition here.
435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  OpenDevToolsWindow(inspected_rvh);
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int DevToolsWindow::GetMinimumWidth() {
4402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const int kMinDevToolsWidth = 150;
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return kMinDevToolsWidth;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int DevToolsWindow::GetMinimumHeight() {
4462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Minimal height of devtools pane or content pane when devtools are docked
4472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // to the browser window.
4482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const int kMinDevToolsHeight = 50;
449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return kMinDevToolsHeight;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int DevToolsWindow::GetMinimizedHeight() {
4542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const int kMinimizedDevToolsHeight = 24;
455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return kMinimizedDevToolsHeight;
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::InspectedContentsClosing() {
4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_contents_->GetRenderViewHost()->ClosePage();
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochcontent::RenderViewHost* DevToolsWindow::GetRenderViewHost() {
463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return web_contents_->GetRenderViewHost();
464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochcontent::DevToolsClientHost* DevToolsWindow::GetDevToolsClientHostForTest() {
467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return frontend_host_.get();
468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int DevToolsWindow::GetWidth(int container_width) {
471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (width_ == -1) {
472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    width_ = profile_->GetPrefs()->
473a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        GetInteger(prefs::kDevToolsVSplitLocation);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
476a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // By default, size devtools as 1/3 of the browser window.
477a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (width_ == -1)
478a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    width_ = container_width / 3;
479a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
480a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Respect the minimum devtools width preset.
4812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  width_ = std::max(GetMinimumWidth(), width_);
482a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
483a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // But it should never compromise the content window size unless the entire
484a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // window is tiny.
485a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  width_ = std::min(container_width - kMinContentsSize, width_);
486a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return width_;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DevToolsWindow::GetHeight(int container_height) {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height_ == -1) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = profile_->GetPrefs()->
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetInteger(prefs::kDevToolsHSplitLocation);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default, size devtools as 1/3 of the browser window.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height_ == -1)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = container_height / 3;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respect the minimum devtools width preset.
5002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  height_ = std::max(GetMinimumHeight(), height_);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But it should never compromise the content window size.
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = std::min(container_height - kMinContentsSize, height_);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return height_;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetWidth(int width) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = width;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetInteger(prefs::kDevToolsVSplitLocation, width);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetHeight(int height) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = height;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetInteger(prefs::kDevToolsHSplitLocation, height);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::Show(DevToolsToggleAction action) {
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (IsDocked()) {
5192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    Browser* inspected_browser = NULL;
5202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int inspected_tab_index = -1;
521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Tell inspected browser to update splitter and switch to inspected panel.
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!IsInspectedBrowserPopup() &&
523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FindInspectedBrowserAndTabIndex(&inspected_browser,
524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                        &inspected_tab_index)) {
525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      BrowserWindow* inspected_window = inspected_browser->window();
526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      web_contents_->SetDelegate(this);
527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      inspected_window->UpdateDevTools();
528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      web_contents_->GetView()->SetInitialFocus();
529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      inspected_window->Show();
530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      TabStripModel* tab_strip_model = inspected_browser->tab_strip_model();
531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      tab_strip_model->ActivateTabAt(inspected_tab_index, true);
532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      PrefsTabHelper::CreateForWebContents(web_contents_);
533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GetRenderViewHost()->SyncRendererPrefs();
534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ScheduleAction(action);
535a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // Sometimes we don't know where to dock. Stay undocked.
5392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    dock_side_ = DEVTOOLS_DOCK_SIDE_UNDOCKED;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Avoid consecutive window switching if the devtools window has been opened
543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // and the Inspect Element shortcut is pressed in the inspected tab.
544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool should_show_window =
5452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      !browser_ || (action != DEVTOOLS_TOGGLE_ACTION_INSPECT);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
547a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!browser_)
548a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    CreateDevToolsBrowser();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
550a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (should_show_window) {
551a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    browser_->window()->Show();
552a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    web_contents_->GetView()->SetInitialFocus();
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ScheduleAction(action);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow::DevToolsWindow(Profile* profile,
559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               const GURL& url,
5602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                               content::RenderViewHost* inspected_rvh,
561a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                               DevToolsDockSide dock_side)
562a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : profile_(profile),
563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser_(NULL),
564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      dock_side_(dock_side),
565a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      is_loaded_(false),
566a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      action_on_load_(DEVTOOLS_TOGGLE_ACTION_SHOW),
567a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      width_(-1),
568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      height_(-1),
5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      dock_side_before_minimized_(dock_side),
5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      weak_factory_(this) {
5712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_contents_ =
5722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::WebContents::Create(content::WebContents::CreateParams(profile));
5731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  frontend_contents_observer_.reset(new FrontendWebContentsObserver(this));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  web_contents_->GetController().LoadURL(url, content::Referrer(),
576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  frontend_host_.reset(content::DevToolsClientHost::CreateDevToolsFrontendHost(
5792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      web_contents_, this));
580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_helper_.reset(new DevToolsFileHelper(web_contents_, profile));
5812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_system_indexer_ = new DevToolsFileSystemIndexer();
5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  extensions::ExtensionWebContentsObserver::CreateForWebContents(web_contents_);
583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  g_instances.Get().push_back(this);
5852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
586a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Wipe out page icon so that the default application icon is used.
5872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::NavigationEntry* entry =
5882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      web_contents_->GetController().GetActiveEntry();
589a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  entry->GetFavicon().image = gfx::Image();
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  entry->GetFavicon().valid = true;
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Register on-load actions.
5932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::Source<content::NavigationController> nav_controller_source(
5942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      &web_contents_->GetController());
5952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registrar_.Add(this, chrome::NOTIFICATION_TAB_CLOSING, nav_controller_source);
596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(
5972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      content::Source<ThemeService>(
599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          ThemeServiceFactory::GetForProfile(profile_)));
6002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // There is no inspected_rvh in case of shared workers.
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (inspected_rvh)
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    inspected_contents_observer_.reset(new InspectedWebContentsObserver(
6042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        content::WebContents::FromRenderViewHost(inspected_rvh)));
60558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  embedder_message_dispatcher_.reset(
60758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new DevToolsEmbedderMessageDispatcher(this));
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::Create(
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile,
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& frontend_url,
6142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* inspected_rvh,
615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsDockSide dock_side,
616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool shared_worker_frontend,
617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool external_frontend) {
618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Create WebContents with devtools.
6192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  GURL url(GetDevToolsURL(profile, frontend_url, dock_side,
620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          shared_worker_frontend,
621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                          external_frontend));
622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return new DevToolsWindow(profile, url, inspected_rvh, dock_side);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL DevToolsWindow::GetDevToolsURL(Profile* profile,
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    const GURL& base_url,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    DevToolsDockSide dock_side,
629424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                    bool shared_worker_frontend,
630424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                    bool external_frontend) {
6318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (base_url.SchemeIs("data"))
6328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return base_url;
6338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string frontend_url(
6352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base_url.is_empty() ? chrome::kChromeUIDevToolsURL : base_url.spec());
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile);
6372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(tp);
6382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string url_string(
6392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      frontend_url +
6402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      ((frontend_url.find("?") == std::string::npos) ? "?" : "&") +
6412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "dockSide=" + SideToString(dock_side) +
6422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "&toolbarColor=" +
6432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
6442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "&textColor=" +
6452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)));
6462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (shared_worker_frontend)
6472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    url_string += "&isSharedWorker=true";
648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (external_frontend)
649424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    url_string += "&remoteFrontend=true";
6502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (CommandLine::ForCurrentProcess()->HasSwitch(
6512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      switches::kEnableDevToolsExperiments))
6522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    url_string += "&experiments=true";
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(url_string);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
656a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
657a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsWindow* DevToolsWindow::FindDevToolsWindow(
658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsAgentHost* agent_host) {
6592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindows* instances = &g_instances.Get();
6602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
6612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
6622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       ++it) {
663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (manager->GetDevToolsAgentHostFor((*it)->frontend_host_.get()) ==
664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        agent_host)
665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return *it;
666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
667a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
670a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
6712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochDevToolsWindow* DevToolsWindow::AsDevToolsWindow(
6722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::RenderViewHost* window_rvh) {
673a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (g_instances == NULL)
674a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return NULL;
6752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsWindows* instances = &g_instances.Get();
6762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (DevToolsWindows::iterator it(instances->begin()); it != instances->end();
6772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       ++it) {
678a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if ((*it)->web_contents_->GetRenderViewHost() == window_rvh)
679a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return *it;
680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
681a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return NULL;
682a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
683a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
684a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
685a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsDockSide DevToolsWindow::GetDockSideFromPrefs(Profile* profile) {
686a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string dock_side =
687a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      profile->GetPrefs()->GetString(prefs::kDevToolsDockSide);
688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Migrate prefs.
6902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const char kOldPrefBottom[] = "bottom";
6912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const char kOldPrefRight[] = "right";
6922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if ((dock_side == kOldPrefBottom) || (dock_side == kOldPrefRight)) {
6932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (!profile->GetPrefs()->GetBoolean(prefs::kDevToolsOpenDocked))
6942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return DEVTOOLS_DOCK_SIDE_UNDOCKED;
6952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return (dock_side == kOldPrefBottom) ?
6962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        DEVTOOLS_DOCK_SIDE_BOTTOM : DEVTOOLS_DOCK_SIDE_RIGHT;
697a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (dock_side == kPrefUndocked)
700a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_UNDOCKED;
7012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (dock_side == kPrefRight)
702a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_RIGHT;
7032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  // Default to docked to bottom.
704a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return DEVTOOLS_DOCK_SIDE_BOTTOM;
705a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
706a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
707a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
708a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string DevToolsWindow::SideToString(DevToolsDockSide dock_side) {
709a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch (dock_side) {
7102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case DEVTOOLS_DOCK_SIDE_UNDOCKED:  return kDockSideUndocked;
7112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case DEVTOOLS_DOCK_SIDE_RIGHT:     return kDockSideRight;
7122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case DEVTOOLS_DOCK_SIDE_BOTTOM:    return kDockSideBottom;
713a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case DEVTOOLS_DOCK_SIDE_MINIMIZED: return kDockSideMinimized;
7142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    default:                           return kDockSideUndocked;
715a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)DevToolsDockSide DevToolsWindow::SideFromString(
720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::string& dock_side) {
721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (dock_side == kDockSideRight)
722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_RIGHT;
723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (dock_side == kDockSideBottom)
724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_BOTTOM;
7252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return (dock_side == kDockSideMinimized) ?
7262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      DEVTOOLS_DOCK_SIDE_MINIMIZED : DEVTOOLS_DOCK_SIDE_UNDOCKED;
727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::Observe(int type,
730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             const content::NotificationSource& source,
731a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                             const content::NotificationDetails& details) {
7321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (type == chrome::NOTIFICATION_TAB_CLOSING) {
7332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (content::Source<content::NavigationController>(source).ptr() ==
7342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        &web_contents_->GetController()) {
735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // This happens when browser closes all of its tabs as a result
736a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // of window.Close event.
737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Notify manager that this DevToolsClientHost no longer exists and
738a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // initiate self-destuct here.
7392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::DevToolsManager::GetInstance()->ClientHostClosing(
7402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          frontend_host_.get());
741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      UpdateBrowserToolbar();
742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      delete this;
743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
7442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  } else {
7452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    UpdateTheme();
747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochcontent::WebContents* DevToolsWindow::OpenURLFromTab(
7512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
7522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::OpenURLParams& params) {
753a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!params.url.SchemeIs(chrome::kChromeDevToolsScheme)) {
754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::WebContents* inspected_web_contents = GetInspectedWebContents();
7552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return inspected_web_contents ?
7562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        inspected_web_contents->OpenURL(params) : NULL;
757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::DevToolsManager* manager = content::DevToolsManager::GetInstance();
760a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent_host(
761a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      manager->GetDevToolsAgentHostFor(frontend_host_.get()));
762a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!agent_host.get())
763a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return NULL;
764a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  manager->ClientHostClosing(frontend_host_.get());
765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  manager->RegisterDevToolsClientHostFor(agent_host.get(),
766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                         frontend_host_.get());
767a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
768a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  chrome::NavigateParams nav_params(profile_, params.url, params.transition);
769a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FillNavigateParamsFromOpenURLParams(&nav_params, params);
770a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params.source_contents = source;
771a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
772a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
773a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  nav_params.user_gesture = params.user_gesture;
774a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  chrome::Navigate(&nav_params);
775a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return nav_params.target_contents;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::AddNewContents(content::WebContents* source,
7792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    content::WebContents* new_contents,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WindowOpenDisposition disposition,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& initial_pos,
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool user_gesture,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* was_blocked) {
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->GetDelegate()->AddNewContents(
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source, new_contents, disposition, initial_pos, user_gesture,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        was_blocked);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CloseContents(content::WebContents* source) {
7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(IsDocked());
7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Update dev tools to reflect removed dev tools window.
7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  BrowserWindow* inspected_window = GetInspectedBrowserWindow();
7964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (inspected_window)
7974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    inspected_window->UpdateDevTools();
7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // In case of docked web_contents_, we own it so delete here.
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delete web_contents_;
8004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delete this;
8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DevToolsWindow::BeforeUnloadFired(content::WebContents* tab,
8054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       bool proceed,
8064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       bool* proceed_to_fire_unload) {
8074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (proceed) {
8084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::DevToolsManager::GetInstance()->ClientHostClosing(
8094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        frontend_host_.get());
8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  *proceed_to_fire_unload = proceed;
812a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
813a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::PreHandleKeyboardEvent(
8152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
8162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NativeWebKeyboardEvent& event,
8172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    bool* is_keyboard_shortcut) {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
8202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (inspected_window) {
8212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return inspected_window->PreHandleKeyboardEvent(event,
8222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                      is_keyboard_shortcut);
8232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    }
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::HandleKeyboardEvent(
8292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* source,
8302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NativeWebKeyboardEvent& event) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event.windowsKeyCode == 0x08) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Do not navigate back in history on Windows (http://crbug.com/74156).
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->HandleKeyboardEvent(event);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
842a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager() {
843a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
8442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return (inspected_web_contents && inspected_web_contents->GetDelegate()) ?
8452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      inspected_web_contents->GetDelegate()->GetJavaScriptDialogManager() :
8462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::WebContentsDelegate::GetJavaScriptDialogManager();
847a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
849a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::ColorChooser* DevToolsWindow::OpenColorChooser(
8502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    content::WebContents* web_contents,
8512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SkColor initial_color) {
852a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return chrome::ShowColorChooser(web_contents, initial_color);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::RunFileChooser(content::WebContents* web_contents,
8562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    const content::FileChooserParams& params) {
857a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSelectHelper::RunFileChooser(web_contents, params);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::WebContentsFocused(content::WebContents* contents) {
861a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* inspected_browser = NULL;
862a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int inspected_tab_index = -1;
863a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (IsDocked() && FindInspectedBrowserAndTabIndex(&inspected_browser,
8642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                                    &inspected_tab_index))
865a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    inspected_browser->window()->WebContentsFocused(contents);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void DevToolsWindow::DispatchOnEmbedder(const std::string& message) {
8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string method;
8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ListValue empty_params;
8714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::ListValue* params = &empty_params;
8724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::DictionaryValue* dict = NULL;
8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
8754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!parsed_message ||
8764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !parsed_message->GetAsDictionary(&dict) ||
8774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      !dict->GetString(kFrontendHostMethod, &method) ||
8784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      (dict->HasKey(kFrontendHostParams) &&
8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          !dict->GetList(kFrontendHostParams, &params))) {
8804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    LOG(ERROR) << "Invalid message was sent to embedder: " << message;
8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
8834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int id = 0;
8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  dict->GetInteger(kFrontendHostId, &id);
8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string error = embedder_message_dispatcher_->Dispatch(method, params);
8884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (id) {
8894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<base::Value> id_value(base::Value::CreateIntegerValue(id));
8904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_ptr<base::Value> error_value(base::Value::CreateStringValue(error));
8914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CallClientFunction("InspectorFrontendAPI.embedderMessageAck",
8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       id_value.get(), error_value.get(), NULL);
8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
89458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
89558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::ActivateWindow() {
8972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (IsDocked() && GetInspectedBrowserWindow())
8982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    web_contents_->GetView()->Focus();
8992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  else if (!IsDocked() && !browser_->window()->IsActive())
9002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    browser_->window()->Activate();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DevToolsWindow::ActivateContents(content::WebContents* contents) {
9044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (IsDocked()) {
9054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    content::WebContents* inspected_tab = this->GetInspectedWebContents();
9064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    inspected_tab->GetDelegate()->ActivateContents(inspected_tab);
9074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
9084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    browser_->window()->Activate();
9094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
9104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::CloseWindow() {
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsDocked());
9144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_contents_->GetRenderViewHost()->FirePageBeforeUnload(false);
9154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
9164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
9174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void DevToolsWindow::SetWindowBounds(int x, int y, int width, int height) {
9184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!IsDocked())
9194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    browser_->window()->SetBounds(gfx::Rect(x, y, width, height));
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::MoveWindow(int x, int y) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsDocked()) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect bounds = browser_->window()->GetBounds();
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.Offset(x, y);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser_->window()->SetBounds(bounds);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetDockSide(const std::string& side) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsDockSide requested_side = SideFromString(side);
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dock_requested = requested_side != DEVTOOLS_DOCK_SIDE_UNDOCKED;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_docked = IsDocked();
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (dock_requested &&
9362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      (!GetInspectedWebContents() || !GetInspectedBrowserWindow() ||
9372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch       IsInspectedBrowserPopup())) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Cannot dock, avoid window flashing due to close-reopen cycle.
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if ((dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED) &&
9432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      (requested_side == DEVTOOLS_DOCK_SIDE_MINIMIZED))
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dock_side_before_minimized_ = dock_side_;
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dock_side_ = requested_side;
9472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (dock_requested && !is_docked) {
9482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // Detach window from the external devtools browser. It will lead to
9492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    // the browser object's close and delete. Remove observer first.
9502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    TabStripModel* tab_strip_model = browser_->tab_strip_model();
9512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    tab_strip_model->DetachWebContentsAt(
9522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        tab_strip_model->GetIndexOfWebContents(web_contents_));
9532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    browser_ = NULL;
9542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  } else if (!dock_requested && is_docked) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update inspected window to hide split and reset it.
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->UpdateDevTools();
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED) {
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string pref_value = kPrefBottom;
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (dock_side_) {
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_UNDOCKED:
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefUndocked;
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_RIGHT:
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefRight;
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_BOTTOM:
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefBottom;
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_MINIMIZED:
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          // We don't persist minimized state.
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetPrefs()->SetString(prefs::kDevToolsDockSide, pref_value);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::OpenInNewTab(const std::string& url) {
9842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  content::OpenURLParams params(
9852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      GURL(url), content::Referrer(), NEW_FOREGROUND_TAB,
9862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      content::PAGE_TRANSITION_LINK, false);
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->OpenURL(params);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::HostDesktopType host_desktop_type;
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_) {
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = browser_->host_desktop_type();
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // There should always be a browser when there are no inspected web
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // contents.
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = chrome::GetActiveDesktop();
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BrowserList* browser_list =
10022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BrowserList::GetInstance(host_desktop_type);
10032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (BrowserList::const_iterator it = browser_list->begin();
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != browser_list->end(); ++it) {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*it)->type() == Browser::TYPE_TABBED) {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*it)->OpenURL(params);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SaveToFile(const std::string& url,
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& content,
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool save_as) {
10162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->Save(url, content, save_as,
10172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     base::Bind(&DevToolsWindow::FileSavedAs,
10182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                weak_factory_.GetWeakPtr(), url));
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendToFile(const std::string& url,
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const std::string& content) {
10232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->Append(url, content,
10242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                       base::Bind(&DevToolsWindow::AppendedTo,
10252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  weak_factory_.GetWeakPtr(), url));
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RequestFileSystems() {
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_helper_->RequestFileSystems(base::Bind(
10312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      &DevToolsWindow::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::AddFileSystem() {
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->AddFileSystem(
10372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
10382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
10392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 weak_factory_.GetWeakPtr()));
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RemoveFileSystem(const std::string& file_system_path) {
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->RemoveFileSystem(file_system_path);
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringValue file_system_path_value(file_system_path);
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
10472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, NULL, NULL);
10482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
10492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
10502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexPath(int request_id,
10512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                               const std::string& file_system_path) {
1052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
10532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!file_helper_->IsFileSystemAdded(file_system_path)) {
10552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    IndexingDone(request_id, file_system_path);
10562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
10572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  indexing_jobs_[request_id] =
1059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      scoped_refptr<DevToolsFileSystemIndexer::FileSystemIndexingJob>(
1060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch          file_system_indexer_->IndexPath(
1061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              file_system_path,
1062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingTotalWorkCalculated,
1063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path),
1066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingWorked,
1067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path),
1070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              Bind(&DevToolsWindow::IndexingDone,
1071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   weak_factory_.GetWeakPtr(),
1072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   request_id,
1073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                   file_system_path)));
10742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
10752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
10762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::StopIndexing(int request_id) {
1077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
10782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  IndexingJobsMap::iterator it = indexing_jobs_.find(request_id);
10792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (it == indexing_jobs_.end())
10802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
10812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  it->second->Stop();
10822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.erase(it);
10832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
10842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
10852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::SearchInPath(int request_id,
10862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& file_system_path,
10872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& query) {
1088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
10892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!file_helper_->IsFileSystemAdded(file_system_path)) {
10912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SearchCompleted(request_id, file_system_path, std::vector<std::string>());
10922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
10932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
10942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  file_system_indexer_->SearchInPath(file_system_path,
10952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                     query,
10962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                     Bind(&DevToolsWindow::SearchCompleted,
10972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          weak_factory_.GetWeakPtr(),
10982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          request_id,
10992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                          file_system_path));
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::FileSavedAs(const std::string& url) {
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringValue url_value(url);
11042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.savedURL", &url_value, NULL, NULL);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendedTo(const std::string& url) {
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringValue url_value(url);
11092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value, NULL,
11102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     NULL);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemsLoaded(
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ListValue file_systems_value;
11162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (size_t i = 0; i < file_systems.size(); ++i)
11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
11192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_systems_value, NULL, NULL);
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemAdded(
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DevToolsFileHelper::FileSystem& file_system) {
11242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringValue error_string_value((std::string()));
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryValue* file_system_value = NULL;
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!file_system.file_system_path.empty())
11272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_value = CreateFileSystemValue(file_system);
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
11292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &error_string_value, file_system_value, NULL);
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (file_system_value)
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete file_system_value;
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingTotalWorkCalculated(
11352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int request_id,
11362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::string& file_system_path,
11372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int total_work) {
1138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
11402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringValue file_system_path_value(file_system_path);
11412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue total_work_value(total_work);
11422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingTotalWorkCalculated",
11432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &request_id_value, &file_system_path_value,
11442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &total_work_value);
11452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
11462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
11472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingWorked(int request_id,
11482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    const std::string& file_system_path,
11492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                    int worked) {
1150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
11522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringValue file_system_path_value(file_system_path);
11532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue worked_value(worked);
11542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingWorked", &request_id_value,
11552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, &worked_value);
11562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
11572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
11582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::IndexingDone(int request_id,
11592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                  const std::string& file_system_path) {
11602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  indexing_jobs_.erase(request_id);
1161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
11632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringValue file_system_path_value(file_system_path);
11642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.indexingDone", &request_id_value,
11652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, NULL);
11662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
11672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
11682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid DevToolsWindow::SearchCompleted(
11692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int request_id,
11702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::string& file_system_path,
11712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const std::vector<std::string>& file_paths) {
1172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ListValue file_paths_value;
1174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  for (std::vector<std::string>::const_iterator it(file_paths.begin());
1175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch       it != file_paths.end(); ++it) {
11762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    file_paths_value.AppendString(*it);
11772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
11782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  base::FundamentalValue request_id_value(request_id);
11792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  StringValue file_system_path_value(file_system_path);
11802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.searchCompleted", &request_id_value,
11812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     &file_system_path_value, &file_paths_value);
11822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
11832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::ShowDevToolsConfirmInfoBar(
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const string16& message,
11862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const InfoBarCallback& callback) {
11872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DevToolsConfirmInfoBarDelegate::Create(
11882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      IsDocked() ?
11892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          InfoBarService::FromWebContents(GetInspectedWebContents()) :
11902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          InfoBarService::FromWebContents(web_contents_),
11912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      callback, message);
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CreateDevToolsBrowser() {
1195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string wp_key = GetDevToolsWindowPlacementPrefKey();
1196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
1197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str());
1198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!wp_pref || wp_pref->empty()) {
1199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DictionaryPrefUpdate update(prefs, wp_key.c_str());
1200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DictionaryValue* defaults = update.Get();
1201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("left", 100);
1202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("top", 100);
1203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("right", 740);
1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetInteger("bottom", 740);
1205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetBoolean("maximized", false);
1206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    defaults->SetBoolean("always_on_top", false);
1207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  browser_ = new Browser(Browser::CreateParams::CreateForDevTools(
12102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      profile_,
12112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      chrome::GetHostDesktopTypeForNativeView(
12122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          web_contents_->GetView()->GetNativeView())));
1213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  browser_->tab_strip_model()->AddWebContents(
1214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL,
1215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      TabStripModel::ADD_ACTIVE);
1216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GetRenderViewHost()->SyncRendererPrefs();
1217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsWindow::FindInspectedBrowserAndTabIndex(Browser** browser,
1220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                     int* tab) {
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
1222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!inspected_web_contents)
1223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
1224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
1226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int tab_index = it->tab_strip_model()->GetIndexOfWebContents(
1227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        inspected_web_contents);
1228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (tab_index != TabStripModel::kNoTab) {
1229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *browser = *it;
1230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      *tab = tab_index;
1231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return true;
1232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return false;
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() {
1238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* browser = NULL;
1239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int tab;
1240a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return FindInspectedBrowserAndTabIndex(&browser, &tab) ?
1241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser->window() : NULL;
124290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
124390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool DevToolsWindow::IsInspectedBrowserPopup() {
1245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Browser* browser = NULL;
1246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int tab;
12472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return FindInspectedBrowserAndTabIndex(&browser, &tab) &&
12482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      browser->is_type_popup();
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::UpdateFrontendDockSide() {
1252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::StringValue dock_side(SideToString(dock_side_));
12532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.setDockSide", &dock_side, NULL,
12542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     NULL);
1255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FundamentalValue docked(IsDocked());
12562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("InspectorFrontendAPI.setAttachedWindow", &docked, NULL,
12572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                     NULL);
1258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::ScheduleAction(DevToolsToggleAction action) {
1261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  action_on_load_ = action;
1262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_loaded_)
1263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DoAction();
1264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::DoAction() {
1267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UpdateFrontendDockSide();
1268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch (action_on_load_) {
1269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
12702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("InspectorFrontendAPI.showConsole", NULL, NULL, NULL);
1271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
12722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_INSPECT:
12742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("InspectorFrontendAPI.enterInspectElementMode", NULL,
12752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                         NULL, NULL);
12762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      break;
12772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_SHOW:
1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_TOGGLE:
1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Do nothing.
1281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
12822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
1284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      NOTREACHED();
12852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      break;
1286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
1287a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  action_on_load_ = DEVTOOLS_TOGGLE_ACTION_SHOW;
1288a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1289a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1290a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::UpdateTheme() {
1291a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
12922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(tp);
12932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
12942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  std::string command("InspectorFrontendAPI.setToolbarColors(\"" +
12952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_TOOLBAR)) +
12962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "\", \"" +
12972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      SkColorToRGBAString(tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)) +
12982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      "\")");
12992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_contents_->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
13002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      string16(), ASCIIToUTF16(command));
1301a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1302a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1303a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::AddDevToolsExtensionsToClient() {
1304a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
1305a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (inspected_web_contents) {
1306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SessionTabHelper* session_tab_helper =
1307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        SessionTabHelper::FromWebContents(inspected_web_contents);
1308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (session_tab_helper) {
1309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::FundamentalValue tabId(session_tab_helper->session_id().id());
13102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      CallClientFunction("WebInspector.setInspectedTabId", &tabId, NULL, NULL);
1311a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
1312a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
13132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1314a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Profile* profile =
1315a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
1316a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
1317a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      profile->GetOriginalProfile())->extension_service();
1318a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!extension_service)
1319a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
1320a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const ExtensionSet* extensions = extension_service->extensions();
1321a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ListValue results;
13232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  for (ExtensionSet::const_iterator extension(extensions->begin());
1324a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       extension != extensions->end(); ++extension) {
1325a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
1326a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      continue;
1327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DictionaryValue* extension_info = new DictionaryValue();
1328a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extension_info->Set(
1329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        "startPage",
1330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        new StringValue(
1331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            extensions::ManifestURL::GetDevToolsPage(extension->get()).spec()));
1332a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    extension_info->Set("name", new StringValue((*extension)->name()));
13332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    extension_info->Set(
13342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        "exposeExperimentalAPIs",
13352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        new base::FundamentalValue((*extension)->HasAPIPermission(
13362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            extensions::APIPermission::kExperimental)));
1337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    results.Append(extension_info);
1338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
13392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  CallClientFunction("WebInspector.addExtensions", &results, NULL, NULL);
1340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::CallClientFunction(const std::string& function_name,
1343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                        const Value* arg1,
13442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                        const Value* arg2,
13452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                        const Value* arg3) {
1346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string params;
1347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (arg1) {
1348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::string json;
1349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    base::JSONWriter::Write(arg1, &json);
1350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    params.append(json);
1351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (arg2) {
1352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::JSONWriter::Write(arg2, &json);
1353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      params.append(", " + json);
13542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      if (arg3) {
13552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        base::JSONWriter::Write(arg3, &json);
13562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        params.append(", " + json);
13572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      }
1358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  string16 javascript = ASCIIToUTF16(function_name + "(" + params + ");");
1361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  web_contents_->GetRenderViewHost()->
1362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ExecuteJavascriptInWebFrame(string16(), javascript);
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::UpdateBrowserToolbar() {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserWindow* inspected_window = GetInspectedBrowserWindow();
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (inspected_window)
13683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    inspected_window->UpdateToolbar(NULL);
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::IsDocked() {
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dock_side_ != DEVTOOLS_DOCK_SIDE_UNDOCKED;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DevToolsWindow::Restore() {
1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED)
1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    SetDockSide(SideToString(dock_side_before_minimized_));
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)content::WebContents* DevToolsWindow::GetInspectedWebContents() {
13812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return inspected_contents_observer_ ?
13822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      inspected_contents_observer_->web_contents() : NULL;
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
13851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DevToolsWindow::DocumentOnLoadCompletedInMainFrame() {
13861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  is_loaded_ = true;
13871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  UpdateTheme();
13881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DoAction();
13891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  AddDevToolsExtensionsToClient();
13901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1391