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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/inspect_ui.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/pref_service.h"
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/stl_util.h"
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/devtools/devtools_target_impl.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/devtools/devtools_targets_ui.h"
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/devtools/devtools_ui_bindings.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/ui/singleton_tabs.h"
153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/ui/webui/theme_source.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/common/pref_names.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/devtools_manager.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIMessageHandler;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kInitUICommand[]  = "init-ui";
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kInspectCommand[]  = "inspect";
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kActivateCommand[]  = "activate";
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char kCloseCommand[]  = "close";
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kReloadCommand[]  = "reload";
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kOpenCommand[]  = "open";
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kInspectBrowser[] = "inspect-browser";
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kLocalHost[] = "localhost";
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kDiscoverUsbDevicesEnabledCommand[] =
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "set-discover-usb-devices-enabled";
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kPortForwardingEnabledCommand[] =
482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    "set-port-forwarding-enabled";
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kPortForwardingConfigCommand[] = "set-port-forwarding-config";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kPortForwardingDefaultPort[] = "8080";
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kPortForwardingDefaultLocation[] = "localhost:8080";
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InspectMessageHandler : public WebUIMessageHandler {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
56bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  explicit InspectMessageHandler(InspectUI* inspect_ui)
57bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      : inspect_ui_(inspect_ui) {}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~InspectMessageHandler() {}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIMessageHandler implementation.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleInitUICommand(const base::ListValue* args);
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleInspectCommand(const base::ListValue* args);
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleActivateCommand(const base::ListValue* args);
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleCloseCommand(const base::ListValue* args);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleReloadCommand(const base::ListValue* args);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleOpenCommand(const base::ListValue* args);
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void HandleInspectBrowserCommand(const base::ListValue* args);
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void HandleBooleanPrefChanged(const char* pref_name,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                const base::ListValue* args);
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandlePortForwardingConfigCommand(const base::ListValue* args);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  InspectUI* inspect_ui_;
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InspectMessageHandler);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectMessageHandler::RegisterMessages() {
81bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_ui()->RegisterMessageCallback(kInitUICommand,
82bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      base::Bind(&InspectMessageHandler::HandleInitUICommand,
83bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                 base::Unretained(this)));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kInspectCommand,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleInspectCommand,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
87424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kActivateCommand,
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleActivateCommand,
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 base::Unretained(this)));
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kCloseCommand,
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleCloseCommand,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  web_ui()->RegisterMessageCallback(kDiscoverUsbDevicesEnabledCommand,
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleBooleanPrefChanged,
954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::Unretained(this),
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  &prefs::kDevToolsDiscoverUsbDevicesEnabled[0]));
972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->RegisterMessageCallback(kPortForwardingEnabledCommand,
984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleBooleanPrefChanged,
994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 base::Unretained(this),
1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 &prefs::kDevToolsPortForwardingEnabled[0]));
1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->RegisterMessageCallback(kPortForwardingConfigCommand,
1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectMessageHandler::HandlePortForwardingConfigCommand,
1032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  web_ui()->RegisterMessageCallback(kReloadCommand,
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&InspectMessageHandler::HandleReloadCommand,
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                 base::Unretained(this)));
107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  web_ui()->RegisterMessageCallback(kOpenCommand,
108bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&InspectMessageHandler::HandleOpenCommand,
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                 base::Unretained(this)));
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kInspectBrowser,
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleInspectBrowserCommand,
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                 base::Unretained(this)));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleInitUICommand(const base::ListValue*) {
116bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  inspect_ui_->InitUI();
117bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
118bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static bool ParseStringArgs(const base::ListValue* args,
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            std::string* arg0,
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            std::string* arg1,
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            std::string* arg2 = 0) {
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int arg_size = args->GetSize();
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (!arg0 || (arg_size > 0 && args->GetString(0, arg0))) &&
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         (!arg1 || (arg_size > 1 && args->GetString(1, arg1))) &&
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)         (!arg2 || (arg_size > 2 && args->GetString(2, arg2)));
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleInspectCommand(const base::ListValue* args) {
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string source;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string id;
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ParseStringArgs(args, &source, &id))
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    inspect_ui_->Inspect(source, id);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleActivateCommand(const base::ListValue* args) {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string source;
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string id;
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ParseStringArgs(args, &source, &id))
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    inspect_ui_->Activate(source, id);
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleCloseCommand(const base::ListValue* args) {
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string source;
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string id;
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ParseStringArgs(args, &source, &id))
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    inspect_ui_->Close(source, id);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleReloadCommand(const base::ListValue* args) {
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string source;
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string id;
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ParseStringArgs(args, &source, &id))
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    inspect_ui_->Reload(source, id);
155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
156bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InspectMessageHandler::HandleOpenCommand(const base::ListValue* args) {
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string source_id;
159bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string browser_id;
160bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string url;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (ParseStringArgs(args, &source_id, &browser_id, &url))
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    inspect_ui_->Open(source_id, browser_id, url);
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void InspectMessageHandler::HandleInspectBrowserCommand(
166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const base::ListValue* args) {
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string source_id;
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string browser_id;
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string front_end;
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (ParseStringArgs(args, &source_id, &browser_id, &front_end)) {
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    inspect_ui_->InspectBrowserWithCustomFrontend(
172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        source_id, browser_id, GURL(front_end));
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void InspectMessageHandler::HandleBooleanPrefChanged(
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const char* pref_name,
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::ListValue* args) {
1792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
1802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!profile)
1812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
1822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  bool enabled;
1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (args->GetSize() == 1 && args->GetBoolean(0, &enabled))
1854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    profile->GetPrefs()->SetBoolean(pref_name, enabled);
1862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectMessageHandler::HandlePortForwardingConfigCommand(
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::ListValue* args) {
1902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
1912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!profile)
1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dict_src;
1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (args->GetSize() == 1 && args->GetDictionary(0, &dict_src))
1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    profile->GetPrefs()->Set(prefs::kDevToolsPortForwardingConfig, *dict_src);
1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InspectUI::InspectUI(content::WebUI* web_ui)
202bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    : WebUIController(web_ui) {
203bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_ui->AddMessageHandler(new InspectMessageHandler(this));
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource::Add(profile, CreateInspectUIHTMLSource());
2063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set up the chrome://theme/ source.
2083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ThemeSource* theme = new ThemeSource(profile);
2093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  content::URLDataSource::Add(profile, theme);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InspectUI::~InspectUI() {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopListeningNotifications();
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectUI::InitUI() {
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SetPortForwardingDefaults();
218bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  StartListeningNotifications();
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UpdateDiscoverUsbDevicesEnabled();
2202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  UpdatePortForwardingEnabled();
2212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  UpdatePortForwardingConfig();
222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::Inspect(const std::string& source_id,
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        const std::string& target_id) {
2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DevToolsTargetImpl* target = FindTarget(source_id, target_id);
2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (target)
2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target->Inspect(Profile::FromWebUI(web_ui()));
229bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
230bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::Activate(const std::string& source_id,
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                         const std::string& target_id) {
2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DevToolsTargetImpl* target = FindTarget(source_id, target_id);
2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (target)
2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target->Activate();
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::Close(const std::string& source_id,
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                      const std::string& target_id) {
2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DevToolsTargetImpl* target = FindTarget(source_id, target_id);
2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (target)
2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target->Close();
2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::Reload(const std::string& source_id,
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       const std::string& target_id) {
2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DevToolsTargetImpl* target = FindTarget(source_id, target_id);
2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (target)
2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    target->Reload();
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic void NoOp(DevToolsTargetImpl*) {}
2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::Open(const std::string& source_id,
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     const std::string& browser_id,
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     const std::string& url) {
2575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DevToolsTargetsUIHandler* handler = FindTargetHandler(source_id);
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (handler)
2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    handler->Open(browser_id, url, base::Bind(&NoOp));
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
2611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void InspectUI::InspectBrowserWithCustomFrontend(
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& source_id,
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::string& browser_id,
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const GURL& frontend_url) {
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!frontend_url.SchemeIs(content::kChromeUIScheme) &&
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      !frontend_url.SchemeIs(content::kChromeDevToolsScheme) &&
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      frontend_url.host() != kLocalHost) {
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DevToolsTargetsUIHandler* handler = FindTargetHandler(source_id);
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!handler)
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Fetch agent host from remote browser.
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<content::DevToolsAgentHost> agent_host =
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      handler->GetBrowserAgentHost(browser_id);
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (agent_host->IsAttached())
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return;
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create web contents for the front-end.
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebContents* inspect_ui = web_ui()->GetWebContents();
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  WebContents* front_end = inspect_ui->GetDelegate()->OpenURLFromTab(
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      inspect_ui,
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      content::OpenURLParams(GURL(url::kAboutBlankURL),
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             content::Referrer(),
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             NEW_FOREGROUND_TAB,
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             content::PAGE_TRANSITION_AUTO_TOPLEVEL,
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             false));
291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Install devtools bindings.
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DevToolsUIBindings* bindings = new DevToolsUIBindings(front_end,
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                                        frontend_url);
295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Engage remote debugging between front-end and agent host.
297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  content::DevToolsManager::GetInstance()->RegisterDevToolsClientHostFor(
298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      agent_host, bindings->frontend_host());
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::InspectDevices(Browser* browser) {
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::RecordAction(base::UserMetricsAction("InspectDevices"));
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::NavigateParams params(chrome::GetSingletonTabNavigateParams(
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser, GURL(chrome::kChromeUIInspectURL)));
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  params.path_behavior = chrome::NavigateParams::IGNORE_AND_NAVIGATE;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ShowSingletonTabOverwritingNTP(browser, params);
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectUI::Observe(int type,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (source == content::Source<WebContents>(web_ui()->GetWebContents()))
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopListeningNotifications();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
316bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectUI::StartListeningNotifications() {
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!target_handlers_.empty())  // Possible when reloading the page.
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    StopListeningNotifications();
319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
320bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
321bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsTargetsUIHandler::Callback callback =
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&InspectUI::PopulateTargets, base::Unretained(this));
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AddTargetUIHandler(
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DevToolsTargetsUIHandler::CreateForRenderers(callback));
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  AddTargetUIHandler(
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DevToolsTargetsUIHandler::CreateForWorkers(callback));
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (profile->IsOffTheRecord()) {
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ShowIncognitoWarning();
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } else {
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    AddTargetUIHandler(
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        DevToolsTargetsUIHandler::CreateForAdb(callback, profile));
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
336a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  port_status_serializer_.reset(
337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      new PortForwardingStatusSerializer(
338a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          base::Bind(&InspectUI::PopulatePortStatus, base::Unretained(this)),
339a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          profile));
340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.Add(this,
3422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
3432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NotificationService::AllSources());
3442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Init(profile->GetPrefs());
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::Bind(&InspectUI::UpdateDiscoverUsbDevicesEnabled,
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                 base::Unretained(this)));
3492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Add(prefs::kDevToolsPortForwardingEnabled,
3502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectUI::UpdatePortForwardingEnabled,
3512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
3522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Add(prefs::kDevToolsPortForwardingConfig,
3532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectUI::UpdatePortForwardingConfig,
3542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
355bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
356bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::StopListeningNotifications() {
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (target_handlers_.empty())
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  STLDeleteValues(&target_handlers_);
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  port_status_serializer_.reset();
364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
3652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.RemoveAll();
3662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.RemoveAll();
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebUIDataSource* InspectUI::CreateInspectUIHTMLSource() {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource* source =
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebUIDataSource::Create(chrome::kChromeUIInspectHost);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("inspect.css", IDR_INSPECT_CSS);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("inspect.js", IDR_INSPECT_JS);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetDefaultResource(IDR_INSPECT_HTML);
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  source->OverrideContentSecurityPolicyFrameSrc(
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      "frame-src chrome://serviceworker-internals;");
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  serviceworker_webui_.reset(web_ui()->GetWebContents()->CreateWebUI(
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GURL(content::kChromeUIServiceWorkerInternalsURL)));
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  serviceworker_webui_->OverrideJavaScriptFrame(
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      content::kChromeUIServiceWorkerInternalsHost);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return source;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void InspectUI::RenderViewCreated(content::RenderViewHost* render_view_host) {
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  serviceworker_webui_->GetController()->RenderViewCreated(render_view_host);
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
387cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
388cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void InspectUI::RenderViewReused(content::RenderViewHost* render_view_host) {
389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  serviceworker_webui_->GetController()->RenderViewReused(render_view_host);
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool InspectUI::OverrideHandleWebUIMessage(const GURL& source_url,
393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           const std::string& message,
394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                           const base::ListValue& args) {
395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (source_url.SchemeIs(content::kChromeUIScheme) &&
396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      source_url.host() == content::kChromeUIServiceWorkerInternalsHost) {
397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    serviceworker_webui_->ProcessWebUIMessage(source_url, message, args);
398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return false;
401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void InspectUI::UpdateDiscoverUsbDevicesEnabled() {
404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  web_ui()->CallJavascriptFunction(
405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "updateDiscoverUsbDevicesEnabled",
406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      *GetPrefValue(prefs::kDevToolsDiscoverUsbDevicesEnabled));
4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
4092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectUI::UpdatePortForwardingEnabled() {
410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  web_ui()->CallJavascriptFunction(
411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "updatePortForwardingEnabled",
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      *GetPrefValue(prefs::kDevToolsPortForwardingEnabled));
4132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
4142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
4152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectUI::UpdatePortForwardingConfig() {
416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  web_ui()->CallJavascriptFunction(
417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      "updatePortForwardingConfig",
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      *GetPrefValue(prefs::kDevToolsPortForwardingConfig));
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void InspectUI::SetPortForwardingDefaults() {
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui());
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  PrefService* prefs = profile->GetPrefs();
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool default_set;
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!GetPrefValue(prefs::kDevToolsPortForwardingDefaultSet)->
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetAsBoolean(&default_set) || default_set) {
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // This is the first chrome://inspect invocation on a fresh profile or after
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // upgrade from a version that did not have kDevToolsPortForwardingDefaultSet.
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  prefs->SetBoolean(prefs::kDevToolsPortForwardingDefaultSet, true);
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool enabled;
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const base::DictionaryValue* config;
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!GetPrefValue(prefs::kDevToolsPortForwardingEnabled)->
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        GetAsBoolean(&enabled) ||
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      !GetPrefValue(prefs::kDevToolsPortForwardingConfig)->
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        GetAsDictionary(&config)) {
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Do nothing if user already took explicit action.
44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (enabled || config->size() != 0)
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue default_config;
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  default_config.SetString(
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      kPortForwardingDefaultPort, kPortForwardingDefaultLocation);
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  prefs->Set(prefs::kDevToolsPortForwardingConfig, default_config);
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const base::Value* InspectUI::GetPrefValue(const char* name) {
4552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return profile->GetPrefs()->FindPreference(name)->GetValue();
4572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::AddTargetUIHandler(
460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<DevToolsTargetsUIHandler> handler) {
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DevToolsTargetsUIHandler* handler_ptr = handler.release();
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target_handlers_[handler_ptr->source_id()] = handler_ptr;
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DevToolsTargetsUIHandler* InspectUI::FindTargetHandler(
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const std::string& source_id) {
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  TargetHandlerMap::iterator it = target_handlers_.find(source_id);
4685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu     return it != target_handlers_.end() ? it->second : NULL;
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuDevToolsTargetImpl* InspectUI::FindTarget(
4725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const std::string& source_id, const std::string& target_id) {
4735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  TargetHandlerMap::iterator it = target_handlers_.find(source_id);
4745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return it != target_handlers_.end() ?
4755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         it->second->GetTarget(target_id) : NULL;
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InspectUI::PopulateTargets(const std::string& source,
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                scoped_ptr<base::ListValue> targets) {
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::Value> source_value(base::Value::CreateStringValue(source));
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  web_ui()->CallJavascriptFunction(
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      "populateTargets",
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      *source_value.get(),
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      *targets.get());
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
486a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
487a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid InspectUI::PopulatePortStatus(const base::Value& status) {
488a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  web_ui()->CallJavascriptFunction("populatePortStatus", status);
489a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
490f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
491f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InspectUI::ShowIncognitoWarning() {
492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  web_ui()->CallJavascriptFunction("showIncognitoWarning");
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
494