devtools_window.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.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"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/file_select_helper.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/infobars/confirm_infobar_delegate.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.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"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/child_process_security_policy.h"
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_client_host.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_manager.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/load_notification_details.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/bindings_policy.h"
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_client.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/page_transition_types.h"
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<DevToolsWindow*> DevToolsWindowList;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::LazyInstance<DevToolsWindowList>::Leaky
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     g_instances = LAZY_INSTANCE_INITIALIZER;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::Bind;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using base::Callback;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsClientHost;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsManager;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::FileChooserParams;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NativeWebKeyboardEvent;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char DevToolsWindow::kDevToolsApp[] = "DevToolsApp";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOldPrefBottom[] = "bottom";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOldPrefRight[] = "right";
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefBottom[] = "dock_bottom";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefRight[] = "dock_right";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPrefUndocked[] = "undocked";
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDockSideBottom[] = "bottom";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDockSideRight[] = "right";
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDockSideUndocked[] = "undocked";
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kDockSideMinimized[] = "minimized";
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimal height of devtools pane or content pane when devtools are docked
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the browser window.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinDevToolsHeight = 50;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinDevToolsWidth = 150;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinContentsSize = 50;
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kMinimizedDevToolsHeight = 24;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DevToolsWindow::InspectedWebContentsObserver
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit InspectedWebContentsObserver(content::WebContents* web_contents)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : WebContentsObserver(web_contents) {
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* Get() { return web_contents(); }
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DevToolsWindow::FrontendWebContentsObserver
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : public content::WebContentsObserver {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit FrontendWebContentsObserver(content::WebContents* web_contents)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : WebContentsObserver(web_contents) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Overriden from contents::WebContentsObserver.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void AboutToNavigateRenderView(
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      RenderViewHost* render_view_host) OVERRIDE {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::DevToolsClientHost::SetupDevToolsFrontendClient(render_view_host);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)typedef Callback<void(bool)> ConfirmInfoBarCallback;
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class DevToolsConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsConfirmInfoBarDelegate(
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      InfoBarService* infobar_service,
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const ConfirmInfoBarCallback& callback,
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      string16 message)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : ConfirmInfoBarDelegate(infobar_service),
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        callback_(callback),
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        message_(message) {
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetMessageText() const OVERRIDE { return message_; }
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool Accept() OVERRIDE {
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Run(true);
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Reset();
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool Cancel() OVERRIDE {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Run(false);
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback_.Reset();
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE {
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16((button == BUTTON_OK)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         ? IDS_DEV_TOOLS_CONFIRM_ALLOW_BUTTON
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         : IDS_DEV_TOOLS_CONFIRM_DENY_BUTTON);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~DevToolsConfirmInfoBarDelegate() {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!callback_.is_null()) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      callback_.Run(false);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ConfirmInfoBarCallback callback_;
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string16 message_;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string DevToolsWindow::GetDevToolsWindowPlacementPrefKey() {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string wp_key;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wp_key.append(prefs::kBrowserWindowPlacement);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wp_key.append("_");
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wp_key.append(kDevToolsApp);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return wp_key;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DevToolsWindow::RegisterProfilePrefs(
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* registry) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterBooleanPref(
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsOpenDocked,
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      true,
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterStringPref(
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsDockSide,
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kDockSideBottom,
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsEditedFiles,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      prefs::kDevToolsFileSystemPaths,
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registry->RegisterStringPref(
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      prefs::kDevToolsAdbKey,
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      std::string(),
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  registry->RegisterDictionaryPref(
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetDevToolsWindowPlacementPrefKey().c_str(),
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::GetDockedInstanceForInspectedTab(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* inspected_web_contents) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!inspected_web_contents)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!DevToolsAgentHost::HasFor(inspected_web_contents->GetRenderViewHost()))
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(DevToolsAgentHost::GetOrCreateFor(
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      inspected_web_contents->GetRenderViewHost()));
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent.get());
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window && window->IsDocked() ? window : NULL;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::IsDevToolsWindow(RenderViewHost* window_rvh) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AsDevToolsWindow(window_rvh) != NULL;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindowForWorker(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsAgentHost* worker_agent) {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(worker_agent);
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window = DevToolsWindow::CreateDevToolsWindowForWorker(profile);
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Will disconnect the current client host if there is one.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        worker_agent,
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        window->frontend_host_.get());
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile) {
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return Create(profile, GURL(), NULL, DEVTOOLS_DOCK_SIDE_UNDOCKED, true);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::OpenDevToolsWindow(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHost* inspected_rvh) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ToggleDevToolsWindow(inspected_rvh, true,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              DEVTOOLS_TOGGLE_ACTION_SHOW);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsToggleAction action) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (action == DEVTOOLS_TOGGLE_ACTION_TOGGLE && browser->is_devtools()) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->CloseAllTabs();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* inspected_rvh =
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ToggleDevToolsWindow(inspected_rvh,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       action == DEVTOOLS_TOGGLE_ACTION_INSPECT,
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       action);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::InspectElement(RenderViewHost* inspected_rvh,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int y) {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  agent->InspectElement(x, y);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(loislo): we should initiate DevTools window opening from within
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // renderer. Otherwise, we still can hit a race condition here.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenDevToolsWindow(inspected_rvh);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::OpenExternalFrontend(
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Profile* profile,
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& frontend_url,
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::DevToolsAgentHost* agent_host) {
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent_host);
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!window) {
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window = Create(profile, DevToolsUI::GetProxyURL(frontend_url), NULL,
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    DEVTOOLS_DOCK_SIDE_UNDOCKED, false);
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        agent_host, window->frontend_host_.get());
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window->Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::Create(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const GURL& frontend_url,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHost* inspected_rvh,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsDockSide dock_side,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool shared_worker_frontend) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create WebContents with devtools.
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GURL url = GetDevToolsURL(profile, frontend_url, dock_side,
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            shared_worker_frontend);
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return new DevToolsWindow(profile, url, inspected_rvh, dock_side);
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DevToolsWindow::DevToolsWindow(Profile* profile,
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               const GURL& url,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               RenderViewHost* inspected_rvh,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               DevToolsDockSide dock_side)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile),
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_(NULL),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dock_side_(dock_side),
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_loaded_(false),
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      action_on_load_(DEVTOOLS_TOGGLE_ACTION_SHOW),
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width_(-1),
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      height_(-1),
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      dock_side_before_minimized_(dock_side) {
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_contents_ = WebContents::Create(WebContents::CreateParams(profile));
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  frontend_contents_observer_.reset(
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new FrontendWebContentsObserver(web_contents_));
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  web_contents_->GetController().LoadURL(url, content::Referrer(),
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::PAGE_TRANSITION_AUTO_TOPLEVEL, std::string());
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  frontend_host_.reset(
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DevToolsClientHost::CreateDevToolsFrontendHost(web_contents_, this));
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  file_helper_.reset(new DevToolsFileHelper(web_contents_, profile));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_instances.Get().push_back(this);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wipe out page icon so that the default application icon is used.
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NavigationEntry* entry = web_contents_->GetController().GetActiveEntry();
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->GetFavicon().image = gfx::Image();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->GetFavicon().valid = true;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Register on-load actions.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_LOAD_STOP,
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::Source<NavigationController>(&web_contents_->GetController()));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_CLOSING,
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      content::Source<NavigationController>(&web_contents_->GetController()));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<ThemeService>(
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ThemeServiceFactory::GetForProfile(profile_)));
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no inspected_rvh in case of shared workers.
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_rvh)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_contents_observer_.reset(new InspectedWebContentsObserver(
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        WebContents::FromRenderViewHost(inspected_rvh)));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow::~DevToolsWindow() {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsWindowList& instances = g_instances.Get();
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsWindowList::iterator it = std::find(instances.begin(),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              instances.end(),
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              this);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(it != instances.end());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instances.erase(it);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebContents* DevToolsWindow::GetInspectedWebContents() {
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!inspected_contents_observer_)
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return inspected_contents_observer_->Get();
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::InspectedContentsClosing() {
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Hide();
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::Hide() {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update dev tools to reflect removed dev tools window.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->UpdateDevTools();
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In case of docked web_contents_, we own it so delete here.
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete web_contents_;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete this;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First, initiate self-destruct to free all the registrars.
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Then close all tabs. Browser will take care of deleting web_contents_
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for us.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser = browser_;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete this;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    browser->tab_strip_model()->CloseAllTabs();
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::Show(DevToolsToggleAction action) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* inspected_browser;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int inspected_tab_index;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell inspected browser to update splitter and switch to inspected panel.
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!IsInspectedBrowserPopup() &&
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FindInspectedBrowserAndTabIndex(&inspected_browser,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        &inspected_tab_index)) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserWindow* inspected_window = inspected_browser->window();
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_->SetDelegate(this);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->UpdateDevTools();
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_->GetView()->SetInitialFocus();
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->Show();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStripModel* tab_strip_model = inspected_browser->tab_strip_model();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_strip_model->ActivateTabAt(inspected_tab_index, true);
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      PrefsTabHelper::CreateForWebContents(web_contents_);
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetRenderViewHost()->SyncRendererPrefs();
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ScheduleAction(action);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Sometimes we don't know where to dock. Stay undocked.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dock_side_ = DEVTOOLS_DOCK_SIDE_UNDOCKED;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid consecutive window switching if the devtools window has been opened
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the Inspect Element shortcut is pressed in the inspected tab.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_show_window =
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !browser_ || action != DEVTOOLS_TOGGLE_ACTION_INSPECT;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!browser_)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateDevToolsBrowser();
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (should_show_window) {
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser_->window()->Show();
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents_->GetView()->SetInitialFocus();
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAction(action);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsClientHost* DevToolsWindow::GetDevToolsClientHostForTest() {
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return frontend_host_.get();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DevToolsWindow::GetWidth(int container_width) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (width_ == -1) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width_ = profile_->GetPrefs()->
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetInteger(prefs::kDevToolsVSplitLocation);
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default, size devtools as 1/3 of the browser window.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (width_ == -1)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    width_ = container_width / 3;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respect the minimum devtools width preset.
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = std::max(kMinDevToolsWidth, width_);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But it should never compromise the content window size unless the entire
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window is tiny.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = std::min(container_width - kMinContentsSize, width_);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return width_;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int DevToolsWindow::GetHeight(int container_height) {
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height_ == -1) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = profile_->GetPrefs()->
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetInteger(prefs::kDevToolsHSplitLocation);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default, size devtools as 1/3 of the browser window.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height_ == -1)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height_ = container_height / 3;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respect the minimum devtools width preset.
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = std::max(kMinDevToolsHeight, height_);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But it should never compromise the content window size.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = std::min(container_height - kMinContentsSize, height_);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return height_;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int DevToolsWindow::GetMinimumWidth() {
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMinDevToolsWidth;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int DevToolsWindow::GetMinimumHeight() {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return kMinDevToolsHeight;
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetWidth(int width) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width_ = width;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetInteger(prefs::kDevToolsVSplitLocation, width);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetHeight(int height) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height_ = height;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_->GetPrefs()->SetInteger(prefs::kDevToolsHSplitLocation, height);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int DevToolsWindow::GetMinimizedHeight() {
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return kMinimizedDevToolsHeight;
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewHost* DevToolsWindow::GetRenderViewHost() {
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return web_contents_->GetRenderViewHost();
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::CreateDevToolsBrowser() {
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string wp_key = GetDevToolsWindowPlacementPrefKey();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DictionaryValue* wp_pref = prefs->GetDictionary(wp_key.c_str());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!wp_pref || wp_pref->empty()) {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryPrefUpdate update(prefs, wp_key.c_str());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* defaults = update.Get();
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetInteger("left", 100);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetInteger("top", 100);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetInteger("right", 740);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetInteger("bottom", 740);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetBoolean("maximized", false);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defaults->SetBoolean("always_on_top", false);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::HostDesktopType host_desktop_type =
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::GetHostDesktopTypeForNativeView(
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          web_contents_->GetView()->GetNativeView());
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_ = new Browser(Browser::CreateParams::CreateForDevTools(
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             profile_, host_desktop_type));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  browser_->tab_strip_model()->AddWebContents(
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_, -1, content::PAGE_TRANSITION_AUTO_TOPLEVEL,
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStripModel::ADD_ACTIVE);
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetRenderViewHost()->SyncRendererPrefs();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::FindInspectedBrowserAndTabIndex(Browser** browser,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     int* tab) {
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!inspected_web_contents)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int tab_index = it->tab_strip_model()->GetIndexOfWebContents(
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        inspected_web_contents);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tab_index != TabStripModel::kNoTab) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *browser = *it;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *tab = tab_index;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserWindow* DevToolsWindow::GetInspectedBrowserWindow() {
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser = NULL;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FindInspectedBrowserAndTabIndex(&browser, &tab) ?
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->window() : NULL;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool DevToolsWindow::IsInspectedBrowserPopup() {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser = NULL;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int tab;
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!FindInspectedBrowserAndTabIndex(&browser, &tab))
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return browser->is_type_popup();
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::UpdateFrontendDockSide() {
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::StringValue dock_side(SideToString(dock_side_));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.setDockSide", &dock_side);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::FundamentalValue docked(IsDocked());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.setAttachedWindow", &docked);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AddDevToolsExtensionsToClient() {
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SessionTabHelper* session_tab_helper =
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SessionTabHelper::FromWebContents(inspected_web_contents);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (session_tab_helper) {
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FundamentalValue tabId(session_tab_helper->session_id().id());
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CallClientFunction("WebInspector.setInspectedTabId", &tabId);
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ListValue results;
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* profile =
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ExtensionService* extension_service = extensions::ExtensionSystem::Get(
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile->GetOriginalProfile())->extension_service();
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!extension_service)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ExtensionSet* extensions = extension_service->extensions();
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ExtensionSet::const_iterator extension = extensions->begin();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       extension != extensions->end(); ++extension) {
6027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (extensions::ManifestURL::GetDevToolsPage(extension->get()).is_empty())
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* extension_info = new DictionaryValue();
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    extension_info->Set(
6067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "startPage",
6077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        new StringValue(
6087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            extensions::ManifestURL::GetDevToolsPage(extension->get()).spec()));
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_info->Set("name", new StringValue((*extension)->name()));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool allow_experimental = (*extension)->HasAPIPermission(
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        extensions::APIPermission::kExperimental);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_info->Set("exposeExperimentalAPIs",
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new base::FundamentalValue(allow_experimental));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.Append(extension_info);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallClientFunction("WebInspector.addExtensions", &results);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContents* DevToolsWindow::OpenURLFromTab(WebContents* source,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const OpenURLParams& params) {
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!params.url.SchemeIs(chrome::kChromeDevToolsScheme)) {
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* inspected_web_contents = GetInspectedWebContents();
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (inspected_web_contents)
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return inspected_web_contents->OpenURL(params);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DevToolsManager* manager = DevToolsManager::GetInstance();
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent_host(
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager->GetDevToolsAgentHostFor(frontend_host_.get()));
631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!agent_host.get())
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager->ClientHostClosing(frontend_host_.get());
634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manager->RegisterDevToolsClientHostFor(agent_host.get(),
635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                         frontend_host_.get());
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::NavigateParams nav_params(profile_, params.url, params.transition);
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillNavigateParamsFromOpenURLParams(&nav_params, params);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params.source_contents = source;
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params.tabstrip_add_types = TabStripModel::ADD_NONE;
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nav_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
6427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  nav_params.user_gesture = params.user_gesture;
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::Navigate(&nav_params);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return nav_params.target_contents;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::CallClientFunction(const std::string& function_name,
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const Value* arg1,
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const Value* arg2) {
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string params;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (arg1) {
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string json;
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONWriter::Write(arg1, &json);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    params.append(json);
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (arg2) {
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::JSONWriter::Write(arg2, &json);
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params.append(", " + json);
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 javascript = ASCIIToUTF16(function_name + "(" + params + ");");
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_contents_->GetRenderViewHost()->
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExecuteJavascriptInWebFrame(string16(), javascript);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::Observe(int type,
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationSource& source,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const content::NotificationDetails& details) {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == content::NOTIFICATION_LOAD_STOP && !is_loaded_) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    is_loaded_ = true;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateTheme();
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoAction();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddDevToolsExtensionsToClient();
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == chrome::NOTIFICATION_TAB_CLOSING) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (content::Source<NavigationController>(source).ptr() ==
6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &web_contents_->GetController()) {
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This happens when browser closes all of its tabs as a result
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // of window.Close event.
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Notify manager that this DevToolsClientHost no longer exists and
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // initiate self-destuct here.
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DevToolsManager::GetInstance()->ClientHostClosing(frontend_host_.get());
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UpdateBrowserToolbar();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete this;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED) {
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateTheme();
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::ScheduleAction(DevToolsToggleAction action) {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_on_load_ = action;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_loaded_)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DoAction();
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::DoAction() {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateFrontendDockSide();
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (action_on_load_) {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE:
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CallClientFunction("InspectorFrontendAPI.showConsole", NULL);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_INSPECT:
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CallClientFunction("InspectorFrontendAPI.enterInspectElementMode", NULL);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_SHOW:
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_TOGGLE_ACTION_TOGGLE:
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Do nothing.
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  action_on_load_ = DEVTOOLS_TOGGLE_ACTION_SHOW;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string SkColorToRGBAString(SkColor color) {
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We convert the alpha using DoubleToString because StringPrintf will use
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // locale specific formatters (e.g., use , instead of . in German).
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::StringPrintf("rgba(%d,%d,%d,%s)", SkColorGetR(color),
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColorGetG(color), SkColorGetB(color),
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::DoubleToString(SkColorGetA(color) / 255.0).c_str());
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)GURL DevToolsWindow::GetDevToolsURL(Profile* profile,
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                    const GURL& base_url,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    DevToolsDockSide dock_side,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool shared_worker_frontend) {
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(tp);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color_toolbar =
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color_tab_text =
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool experiments_enabled =
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command_line.HasSwitch(switches::kEnableDevToolsExperiments);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string frontend_url = base_url.is_empty() ?
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chrome::kChromeUIDevToolsURL : base_url.spec();
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string params_separator =
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frontend_url.find("?") == std::string::npos ? "?" : "&";
742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string url_string = base::StringPrintf("%s%s"
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "dockSide=%s&toolbarColor=%s&textColor=%s%s%s",
744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      frontend_url.c_str(),
745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      params_separator.c_str(),
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SideToString(dock_side).c_str(),
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColorToRGBAString(color_toolbar).c_str(),
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColorToRGBAString(color_tab_text).c_str(),
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shared_worker_frontend ? "&isSharedWorker=true" : "",
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      experiments_enabled ? "&experiments=true" : "");
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL(url_string);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::UpdateTheme() {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ThemeService* tp = ThemeServiceFactory::GetForProfile(profile_);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(tp);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color_toolbar =
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tp->GetColor(ThemeProperties::COLOR_TOOLBAR);
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor color_tab_text =
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tp->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT);
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string command = base::StringPrintf(
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "InspectorFrontendAPI.setToolbarColors(\"%s\", \"%s\")",
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColorToRGBAString(color_toolbar).c_str(),
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColorToRGBAString(color_tab_text).c_str());
7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_contents_->GetRenderViewHost()->
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(command));
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AddNewContents(WebContents* source,
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WebContents* new_contents,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    WindowOpenDisposition disposition,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& initial_pos,
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool user_gesture,
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* was_blocked) {
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->GetDelegate()->AddNewContents(
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        source, new_contents, disposition, initial_pos, user_gesture,
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        was_blocked);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::PreHandleKeyboardEvent(
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* source,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return inspected_window->PreHandleKeyboardEvent(
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          event, is_keyboard_shortcut);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::HandleKeyboardEvent(WebContents* source,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const NativeWebKeyboardEvent& event) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked()) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event.windowsKeyCode == 0x08) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Do not navigate back in history on Windows (http://crbug.com/74156).
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->HandleKeyboardEvent(event);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::ToggleDevToolsWindow(
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewHost* inspected_rvh,
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool force_open,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsToggleAction action) {
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(inspected_rvh));
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsManager* manager = DevToolsManager::GetInstance();
817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DevToolsWindow* window = FindDevToolsWindow(agent.get());
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool do_open = force_open;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window) {
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile = Profile::FromBrowserContext(
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inspected_rvh->GetProcess()->GetBrowserContext());
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsDockSide dock_side = GetDockSideFromPrefs(profile);
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window = Create(profile, GURL(), inspected_rvh, dock_side, false);
824868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    manager->RegisterDevToolsClientHostFor(agent.get(),
825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                           window->frontend_host_.get());
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do_open = true;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update toolbar to reflect DevTools changes.
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window->UpdateBrowserToolbar();
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If window is docked and visible, we hide it on toggle. If window is
833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // undocked, we show (activate) it. If window is minimized, we maximize it.
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (window->dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED)
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window->Restore();
836c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else if (!window->IsDocked() || do_open)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window->Show(action);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    window->CloseWindow();
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DevToolsWindow* DevToolsWindow::FindDevToolsWindow(
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DevToolsAgentHost* agent_host) {
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DevToolsManager* manager = DevToolsManager::GetInstance();
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsWindowList& instances = g_instances.Get();
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (DevToolsWindowList::iterator it = instances.begin();
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != instances.end(); ++it) {
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (manager->GetDevToolsAgentHostFor((*it)->frontend_host_.get()) ==
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        agent_host)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return *it;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsWindow* DevToolsWindow::AsDevToolsWindow(RenderViewHost* window_rvh) {
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_instances == NULL)
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsWindowList& instances = g_instances.Get();
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (DevToolsWindowList::iterator it = instances.begin();
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != instances.end(); ++it) {
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*it)->web_contents_->GetRenderViewHost() == window_rvh)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return *it;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::ActivateWindow() {
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsDocked()) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!browser_->window()->IsActive()) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_->window()->Activate();
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_->GetView()->Focus();
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::ChangeAttachedWindowHeight(unsigned height) {
884b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  NOTREACHED(); // TODO(dgozman). This is not used anymore, remove.
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::CloseWindow() {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(IsDocked());
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DevToolsManager::GetInstance()->ClientHostClosing(frontend_host_.get());
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Hide();
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::MoveWindow(int x, int y) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsDocked()) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect bounds = browser_->window()->GetBounds();
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bounds.Offset(x, y);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser_->window()->SetBounds(bounds);
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SetDockSide(const std::string& side) {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsDockSide requested_side = SideFromString(side);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool dock_requested = requested_side != DEVTOOLS_DOCK_SIDE_UNDOCKED;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_docked = IsDocked();
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (dock_requested && (!inspected_web_contents ||
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !GetInspectedBrowserWindow() || IsInspectedBrowserPopup())) {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Cannot dock, avoid window flashing due to close-reopen cycle.
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED &&
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      requested_side == DEVTOOLS_DOCK_SIDE_MINIMIZED) {
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    dock_side_before_minimized_ = dock_side_;
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dock_side_ = requested_side;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dock_requested) {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_docked) {
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Detach window from the external devtools browser. It will lead to
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the browser object's close and delete. Remove observer first.
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TabStripModel* tab_strip_model = browser_->tab_strip_model();
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab_strip_model->DetachWebContentsAt(
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          tab_strip_model->GetIndexOfWebContents(web_contents_));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_ = NULL;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (is_docked) {
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Update inspected window to hide split and reset it.
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserWindow* inspected_window = GetInspectedBrowserWindow();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inspected_window)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inspected_window->UpdateDevTools();
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dock_side_ != DEVTOOLS_DOCK_SIDE_MINIMIZED) {
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string pref_value = kPrefBottom;
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (dock_side_) {
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_UNDOCKED:
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefUndocked;
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_RIGHT:
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefRight;
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_BOTTOM:
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          pref_value = kPrefBottom;
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case DEVTOOLS_DOCK_SIDE_MINIMIZED:
948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          // We don't persist minimized state.
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          break;
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetPrefs()->SetString(prefs::kDevToolsDockSide, pref_value);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Show(DEVTOOLS_TOGGLE_ACTION_SHOW);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::Restore() {
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dock_side_ == DEVTOOLS_DOCK_SIDE_MINIMIZED)
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetDockSide(SideToString(dock_side_before_minimized_));
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::OpenInNewTab(const std::string& url) {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenURLParams params(GURL(url),
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::Referrer(),
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NEW_FOREGROUND_TAB,
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       content::PAGE_TRANSITION_LINK,
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       false /* is_renderer_initiated */);
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents) {
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_web_contents->OpenURL(params);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chrome::HostDesktopType host_desktop_type;
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (browser_) {
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = browser_->host_desktop_type();
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // There should always be a browser when there are no inspected web
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // contents.
9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NOTREACHED();
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_desktop_type = chrome::GetActiveDesktop();
9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const BrowserList* browser_list =
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        BrowserList::GetInstance(host_desktop_type);
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (BrowserList::const_iterator it = browser_list->begin();
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != browser_list->end(); ++it) {
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*it)->type() == Browser::TYPE_TABBED) {
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (*it)->OpenURL(params);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::SaveToFile(const std::string& url,
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& content,
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                bool save_as) {
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->Save(url, content, save_as, Bind(&DevToolsWindow::FileSavedAs,
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 weak_factory_.GetWeakPtr(),
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 url));
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendToFile(const std::string& url,
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const std::string& content) {
10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->Append(url, content, Bind(&DevToolsWindow::AppendedTo,
10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          weak_factory_.GetWeakPtr(),
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          url));
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
10102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DictionaryValue* CreateFileSystemValue(
10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DevToolsFileHelper::FileSystem file_system) {
10132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryValue* file_system_value = new DictionaryValue();
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_value->SetString("fileSystemName", file_system.file_system_name);
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_value->SetString("rootURL", file_system.root_url);
10162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_system_value->SetString("fileSystemPath", file_system.file_system_path);
10172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return file_system_value;
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RequestFileSystems() {
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->RequestFileSystems(
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Bind(&DevToolsWindow::FileSystemsLoaded, weak_factory_.GetWeakPtr()));
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::AddFileSystem() {
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->AddFileSystem(
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Bind(&DevToolsWindow::FileSystemAdded, weak_factory_.GetWeakPtr()),
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      Bind(&DevToolsWindow::ShowDevToolsConfirmInfoBar,
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           weak_factory_.GetWeakPtr()));
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::RemoveFileSystem(const std::string& file_system_path) {
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(web_contents_->GetURL().SchemeIs(chrome::kChromeDevToolsScheme));
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_helper_->RemoveFileSystem(file_system_path);
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringValue file_system_path_value(file_system_path);
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemRemoved",
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &file_system_path_value);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::FileSavedAs(const std::string& url) {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringValue url_value(url);
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.savedURL", &url_value);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::AppendedTo(const std::string& url) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StringValue url_value(url);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.appendedToURL", &url_value);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemsLoaded(
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<DevToolsFileHelper::FileSystem>& file_systems) {
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ListValue file_systems_value;
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < file_systems.size(); ++i) {
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_systems_value.Append(CreateFileSystemValue(file_systems[i]));
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemsLoaded",
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &file_systems_value);
10622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DevToolsWindow::FileSystemAdded(
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DevToolsFileHelper::FileSystem& file_system) {
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  StringValue error_string_value("");
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryValue* file_system_value = NULL;
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!file_system.file_system_path.empty())
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    file_system_value = CreateFileSystemValue(file_system);
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CallClientFunction("InspectorFrontendAPI.fileSystemAdded",
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     &error_string_value,
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     file_system_value);
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (file_system_value)
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete file_system_value;
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DevToolsWindow::ShowDevToolsConfirmInfoBar(
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const string16& message,
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ConfirmInfoBarCallback& callback) {
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  InfoBarService* infobar_service = IsDocked() ?
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      InfoBarService::FromWebContents(GetInspectedWebContents()) :
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      InfoBarService::FromWebContents(web_contents_);
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (infobar_service) {
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        new DevToolsConfirmInfoBarDelegate(
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            infobar_service,
1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            callback,
1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            message)));
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    callback.Run(false);
1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::JavaScriptDialogManager* DevToolsWindow::GetJavaScriptDialogManager() {
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (inspected_web_contents && inspected_web_contents->GetDelegate()) {
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return inspected_web_contents->GetDelegate()->
10992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetJavaScriptDialogManager();
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return content::WebContentsDelegate::GetJavaScriptDialogManager();
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)content::ColorChooser* DevToolsWindow::OpenColorChooser(
110590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    WebContents* web_contents, SkColor initial_color) {
110690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return chrome::ShowColorChooser(web_contents, initial_color);
110790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
110890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::RunFileChooser(WebContents* web_contents,
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const FileChooserParams& params) {
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileSelectHelper::RunFileChooser(web_contents, params);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::WebContentsFocused(WebContents* contents) {
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* inspected_browser = NULL;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int inspected_tab_index = -1;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsDocked() && FindInspectedBrowserAndTabIndex(&inspected_browser,
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    &inspected_tab_index)) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inspected_browser->window()->WebContentsFocused(contents);
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsWindow::UpdateBrowserToolbar() {
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* inspected_web_contents = GetInspectedWebContents();
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!inspected_web_contents)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserWindow* inspected_window = GetInspectedBrowserWindow();
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (inspected_window)
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    inspected_window->UpdateToolbar(inspected_web_contents, false);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsWindow::IsDocked() {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return dock_side_ != DEVTOOLS_DOCK_SIDE_UNDOCKED;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsDockSide DevToolsWindow::GetDockSideFromPrefs(Profile* profile) {
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string dock_side =
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile->GetPrefs()->GetString(prefs::kDevToolsDockSide);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Migrate prefs
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dock_side == kOldPrefBottom || dock_side == kOldPrefRight) {
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool docked = profile->GetPrefs()->GetBoolean(prefs::kDevToolsOpenDocked);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dock_side == kOldPrefBottom)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return docked ? DEVTOOLS_DOCK_SIDE_BOTTOM : DEVTOOLS_DOCK_SIDE_UNDOCKED;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return docked ? DEVTOOLS_DOCK_SIDE_RIGHT : DEVTOOLS_DOCK_SIDE_UNDOCKED;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dock_side == kPrefUndocked)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_UNDOCKED;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (dock_side == kPrefRight)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_RIGHT;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default to docked to bottom
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DEVTOOLS_DOCK_SIDE_BOTTOM;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DevToolsWindow::SideToString(DevToolsDockSide dock_side) {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string dock_side_string;
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (dock_side) {
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_DOCK_SIDE_UNDOCKED: return kDockSideUndocked;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_DOCK_SIDE_RIGHT: return kDockSideRight;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVTOOLS_DOCK_SIDE_BOTTOM: return kDockSideBottom;
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case DEVTOOLS_DOCK_SIDE_MINIMIZED: return kDockSideMinimized;
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kDockSideUndocked;
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsDockSide DevToolsWindow::SideFromString(
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& dock_side) {
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dock_side == kDockSideRight)
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_RIGHT;
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dock_side == kDockSideBottom)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_BOTTOM;
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dock_side == kDockSideMinimized)
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return DEVTOOLS_DOCK_SIDE_MINIMIZED;
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DEVTOOLS_DOCK_SIDE_UNDOCKED;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1182