inspect_ui.cc revision bb1529ce867d8845a77ec7cdf3e3003ef1771a40
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)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/strings/stringprintf.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "chrome/browser/ui/webui/theme_source.h"
232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/common/pref_names.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/child_process_data.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_client_host.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_manager.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui_data_source.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/worker_service.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/worker_service_observer.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/process_type.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ChildProcessData;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsClientHost;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsManager;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderProcessHost;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHostDelegate;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebUIMessageHandler;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WorkerService;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WorkerServiceObserver;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kDataFile[] = "targets-data.json";
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kAdbPages[] = "adb-pages";
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69a3f7b4e666c476898878fa745f637129375cd889Ben Murdochstatic const char kAppTargetType[] = "app";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kExtensionTargetType[]  = "extension";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kPageTargetType[]  = "page";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kWorkerTargetType[]  = "worker";
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kAdbTargetType[]  = "adb_page";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochstatic const char kInitUICommand[]  = "init-ui";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kInspectCommand[]  = "inspect";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTerminateCommand[]  = "terminate";
78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstatic const char kReloadCommand[]  = "reload";
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstatic const char kOpenCommand[]  = "open";
80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstatic const char kPortForwardingEnabledCommand[] =
822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    "set-port-forwarding-enabled";
832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochstatic const char kPortForwardingConfigCommand[] = "set-port-forwarding-config";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTargetTypeField[]  = "type";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAttachedField[]  = "attached";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kProcessIdField[]  = "processId";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kRouteIdField[]  = "routeId";
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kUrlField[]  = "url";
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kNameField[]  = "name";
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kFaviconUrlField[] = "faviconUrl";
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kPidField[]  = "pid";
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kAdbSerialField[] = "adbSerial";
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const char kAdbModelField[] = "adbModel";
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const char kAdbBrowserNameField[] = "adbBrowserName";
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstatic const char kAdbGlobalIdField[] = "adbGlobalId";
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const char kAdbBrowsersField[] = "browsers";
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)static const char kAdbPagesField[] = "pages";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* BuildTargetDescriptor(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& target_type,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool attached,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& name,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& favicon_url,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int process_id,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ProcessHandle handle = base::kNullProcessHandle) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* target_data = new DictionaryValue();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetString(kTargetTypeField, target_type);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetBoolean(kAttachedField, attached);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetInteger(kProcessIdField, process_id);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetInteger(kRouteIdField, route_id);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetString(kUrlField, url.spec());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetString(kNameField, net::EscapeForHTML(name));
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetInteger(kPidField, base::GetProcId(handle));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_data->SetString(kFaviconUrlField, favicon_url.spec());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return target_data;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HasClientHost(RenderViewHost* rvh) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!DevToolsAgentHost::HasFor(rvh))
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent(
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(rvh));
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return agent->IsAttached();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* BuildTargetDescriptor(RenderViewHost* rvh, bool is_tab) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string title;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string target_type = is_tab ? kPageTargetType : "";
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL favicon_url;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = web_contents->GetURL();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    title = UTF16ToUTF8(web_contents->GetTitle());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NavigationController& controller = web_contents->GetController();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::NavigationEntry* entry = controller.GetActiveEntry();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry != NULL && entry->GetURL().is_valid())
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      favicon_url = entry->GetFavicon().url;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile = Profile::FromBrowserContext(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        web_contents->GetBrowserContext());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (profile) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionService* extension_service = profile->GetExtensionService();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const extensions::Extension* extension = extension_service->
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extensions()->GetByID(url.host());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (extension) {
152a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        if (extension->is_hosted_app()
153a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch            || extension->is_legacy_packaged_app()
154a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch            || extension->is_platform_app())
155a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          target_type = kAppTargetType;
156a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        else
157a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          target_type = kExtensionTargetType;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        title = extension->name();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BuildTargetDescriptor(target_type,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               HasClientHost(rvh),
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               url,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               title,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               favicon_url,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               rvh->GetProcess()->GetID(),
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               rvh->GetRoutingID());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InspectMessageHandler : public WebUIMessageHandler {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
174bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  explicit InspectMessageHandler(InspectUI* inspect_ui)
175bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      : inspect_ui_(inspect_ui) {}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~InspectMessageHandler() {}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebUIMessageHandler implementation.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void RegisterMessages() OVERRIDE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void HandleInitUICommand(const ListValue* args);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleInspectCommand(const ListValue* args);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleTerminateCommand(const ListValue* args);
185bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleReloadCommand(const ListValue* args);
186bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  void HandleOpenCommand(const ListValue* args);
1872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void HandlePortForwardingEnabledCommand(const ListValue* args);
1882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  void HandlePortForwardingConfigCommand(const ListValue* args);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static bool GetProcessAndRouteId(const ListValue* args,
191bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   int* process_id,
192bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                   int* route_id);
193bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  static bool GetRemotePageId(const ListValue* args, std::string* page_id);
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
196bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  InspectUI* inspect_ui_;
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(InspectMessageHandler);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectMessageHandler::RegisterMessages() {
202bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_ui()->RegisterMessageCallback(kInitUICommand,
203bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      base::Bind(&InspectMessageHandler::HandleInitUICommand,
204bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                 base::Unretained(this)));
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kInspectCommand,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleInspectCommand,
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_ui()->RegisterMessageCallback(kTerminateCommand,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&InspectMessageHandler::HandleTerminateCommand,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
2112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->RegisterMessageCallback(kPortForwardingEnabledCommand,
2122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectMessageHandler::HandlePortForwardingEnabledCommand,
2132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
2142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->RegisterMessageCallback(kPortForwardingConfigCommand,
2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectMessageHandler::HandlePortForwardingConfigCommand,
2162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
217bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  web_ui()->RegisterMessageCallback(kReloadCommand,
218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&InspectMessageHandler::HandleReloadCommand,
219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                 base::Unretained(this)));
220bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  web_ui()->RegisterMessageCallback(kOpenCommand,
221bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      base::Bind(&InspectMessageHandler::HandleOpenCommand,
222bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                 base::Unretained(this)));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectMessageHandler::HandleInitUICommand(const ListValue*) {
226bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  inspect_ui_->InitUI();
227bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
228bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectMessageHandler::HandleInspectCommand(const ListValue* args) {
230bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
231bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (!profile)
232bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    return;
233bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
234bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string page_id;
235bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (GetRemotePageId(args, &page_id)) {
236bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    inspect_ui_->InspectRemotePage(page_id);
237bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return;
238bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
239bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id;
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!GetProcessAndRouteId(args, &process_id, &route_id) || process_id == 0
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      || route_id == 0) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rvh) {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DevToolsWindow::OpenDevToolsWindow(rvh);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent_host(
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DevToolsAgentHost::GetForWorker(process_id, route_id));
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!agent_host.get())
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host.get());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void TerminateWorker(int process_id, int route_id) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WorkerService::GetInstance()->TerminateWorker(process_id, route_id);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectMessageHandler::HandleTerminateCommand(const ListValue* args) {
266bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string page_id;
267bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (GetRemotePageId(args, &page_id)) {
268bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    inspect_ui_->CloseRemotePage(page_id);
269bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return;
270bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
271bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int process_id;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int route_id;
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!GetProcessAndRouteId(args, &process_id, &route_id))
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TerminateWorker, process_id, route_id));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid InspectMessageHandler::HandleReloadCommand(const ListValue* args) {
282bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string page_id;
283bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (GetRemotePageId(args, &page_id))
284bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    inspect_ui_->ReloadRemotePage(page_id);
285bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
286bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
287bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid InspectMessageHandler::HandleOpenCommand(const ListValue* args) {
288bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string browser_id;
289bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string url;
290bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (args->GetSize() == 2 &&
291bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      args->GetString(0, &browser_id) &&
292bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      args->GetString(1, &url)) {
293bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    inspect_ui_->OpenRemotePage(browser_id, url);
294bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
295bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
296bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool InspectMessageHandler::GetProcessAndRouteId(const ListValue* args,
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                 int* process_id,
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                 int* route_id) {
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const DictionaryValue* data;
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (args->GetSize() == 1 && args->GetDictionary(0, &data) &&
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data->GetInteger(kProcessIdField, process_id) &&
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data->GetInteger(kRouteIdField, route_id)) {
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectMessageHandler::HandlePortForwardingEnabledCommand(
3102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ListValue* args) {
3112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
3122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!profile)
3132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
3142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  bool enabled;
3162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (args->GetSize() == 1 && args->GetBoolean(0, &enabled)) {
3172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    profile->GetPrefs()->SetBoolean(
3182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch        prefs::kDevToolsPortForwardingEnabled, enabled);
3192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
3202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectMessageHandler::HandlePortForwardingConfigCommand(
3232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ListValue* args) {
3242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
3252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!profile)
3262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
3272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const DictionaryValue* dict_src;
3292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (args->GetSize() == 1 && args->GetDictionary(0, &dict_src))
3302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    profile->GetPrefs()->Set(prefs::kDevToolsPortForwardingConfig, *dict_src);
3312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
333bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochbool InspectMessageHandler::GetRemotePageId(const ListValue* args,
334bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                            std::string* page_id) {
335bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  const DictionaryValue* data;
336bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (args->GetSize() == 1 && args->GetDictionary(0, &data) &&
337bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      data->GetString(kAdbGlobalIdField, page_id)) {
338bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return true;
339bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
340bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return false;
341bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
342bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InspectUI::WorkerCreationDestructionListener
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public WorkerServiceObserver,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::RefCountedThreadSafe<WorkerCreationDestructionListener> {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  WorkerCreationDestructionListener()
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      : discovery_ui_(NULL) {}
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Init(InspectUI* workers_ui) {
3537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(workers_ui);
3547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(!discovery_ui_);
3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    discovery_ui_ = workers_ui;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::IO, FROM_HERE,
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&WorkerCreationDestructionListener::RegisterObserver,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InspectUIDestroyed() {
3637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(discovery_ui_);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    discovery_ui_ = NULL;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::IO, FROM_HERE,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&WorkerCreationDestructionListener::UnregisterObserver,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
371bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void InitUI() {
372bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    BrowserThread::PostTask(
373bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        BrowserThread::IO, FROM_HERE,
374bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        base::Bind(&WorkerCreationDestructionListener::CollectWorkersData,
375bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                   this));
376bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
377bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<WorkerCreationDestructionListener>;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WorkerCreationDestructionListener() {}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WorkerCreated(
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const string16& name,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int process_id,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int route_id) OVERRIDE {
387bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    CollectWorkersData();
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE {
391bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    CollectWorkersData();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
394bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void CollectWorkersData() {
395bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
396bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    scoped_ptr<ListValue> target_list(new ListValue());
397bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    std::vector<WorkerService::WorkerInfo> worker_info =
398bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        WorkerService::GetInstance()->GetWorkers();
399bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    for (size_t i = 0; i < worker_info.size(); ++i) {
400bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      target_list->Append(BuildTargetDescriptor(
401bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          kWorkerTargetType,
402bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          false,
403bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          worker_info[i].url,
404bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          UTF16ToUTF8(worker_info[i].name),
405bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          GURL(),
406bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          worker_info[i].process_id,
407bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          worker_info[i].route_id,
408bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          worker_info[i].handle));
409bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    }
410bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
411bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    BrowserThread::PostTask(
412bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        BrowserThread::UI, FROM_HERE,
413bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        base::Bind(&WorkerCreationDestructionListener::PopulateWorkersList,
414bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch                   this, base::Owned(target_list.release())));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterObserver() {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WorkerService::GetInstance()->AddObserver(this);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UnregisterObserver() {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WorkerService::GetInstance()->RemoveObserver(this);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  void PopulateWorkersList(ListValue* target_list) {
426bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
427bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    if (discovery_ui_) {
428bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      discovery_ui_->web_ui()->CallJavascriptFunction(
429bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch          "populateWorkersList", *target_list);
430bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    }
431bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
432bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InspectUI* discovery_ui_;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InspectUI::InspectUI(content::WebUI* web_ui)
437bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    : WebUIController(web_ui) {
438bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_ui->AddMessageHandler(new InspectMessageHandler(this));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile = Profile::FromWebUI(web_ui);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource::Add(profile, CreateInspectUIHTMLSource());
4413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
4423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // Set up the chrome://theme/ source.
4433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ThemeSource* theme = new ThemeSource(profile);
4443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  content::URLDataSource::Add(profile, theme);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InspectUI::~InspectUI() {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StopListeningNotifications();
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
451bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectUI::InitUI() {
452bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  StartListeningNotifications();
453bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  PopulateLists();
4542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  UpdatePortForwardingEnabled();
4552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  UpdatePortForwardingConfig();
456bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  observer_->InitUI();
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void InspectUI::InspectRemotePage(const std::string& id) {
460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  RemotePages::iterator it = remote_pages_.find(id);
461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (it != remote_pages_.end()) {
462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Profile* profile = Profile::FromWebUI(web_ui());
463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    it->second->Inspect(profile);
464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
467bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid InspectUI::ReloadRemotePage(const std::string& id) {
468bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  RemotePages::iterator it = remote_pages_.find(id);
469bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (it != remote_pages_.end())
470bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    it->second->Reload();
471bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
472bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
473bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid InspectUI::CloseRemotePage(const std::string& id) {
474bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  RemotePages::iterator it = remote_pages_.find(id);
475bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (it != remote_pages_.end())
476bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    it->second->Close();
477bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
478bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
479bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid InspectUI::OpenRemotePage(const std::string& browser_id,
480bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                               const std::string& url) {
481bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  GURL gurl(url);
482bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!gurl.is_valid()) {
483bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    gurl = GURL("http://" + url);
484bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    if (!gurl.is_valid())
485bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      return;
486bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
487bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  RemoteBrowsers::iterator it = remote_browsers_.find(browser_id);
488bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (it != remote_browsers_.end())
489bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    it->second->Open(gurl.spec());
490bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
491bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
492bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectUI::PopulateLists() {
493bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  std::set<RenderViewHost*> tab_rvhs;
494bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  for (TabContentsIterator it; !it.done(); it.Next())
495bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    tab_rvhs.insert(it->GetRenderViewHost());
496bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
497bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  scoped_ptr<ListValue> target_list(new ListValue());
498bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
499bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  std::vector<RenderViewHost*> rvh_vector =
500bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      DevToolsAgentHost::GetValidRenderViewHosts();
501bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
502bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  for (std::vector<RenderViewHost*>::iterator it(rvh_vector.begin());
503bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch       it != rvh_vector.end(); it++) {
504bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    bool is_tab = tab_rvhs.find(*it) != tab_rvhs.end();
505bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    target_list->Append(BuildTargetDescriptor(*it, is_tab));
506bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  }
507bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  web_ui()->CallJavascriptFunction("populateLists", *target_list.get());
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectUI::Observe(int type,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (source != content::Source<WebContents>(web_ui()->GetWebContents()))
514bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    PopulateLists();
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StopListeningNotifications();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
519bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochvoid InspectUI::StartListeningNotifications() {
520558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (observer_)
521558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
522558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
523bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  observer_ = new WorkerCreationDestructionListener();
524bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  observer_->Init(this);
525bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
526bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
527558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DevToolsAdbBridge* adb_bridge =
528558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      DevToolsAdbBridge::Factory::GetForProfile(profile);
529558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (adb_bridge)
530558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    adb_bridge->AddListener(this);
531bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.Add(this,
5332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NOTIFICATION_WEB_CONTENTS_CONNECTED,
5342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NotificationService::AllSources());
5352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.Add(this,
5362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
5372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NotificationService::AllSources());
5382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.Add(this,
5392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
5402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                              content::NotificationService::AllSources());
5412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
5422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Init(profile->GetPrefs());
5432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Add(prefs::kDevToolsPortForwardingEnabled,
5442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectUI::UpdatePortForwardingEnabled,
5452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
5462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.Add(prefs::kDevToolsPortForwardingConfig,
5472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&InspectUI::UpdatePortForwardingConfig,
5482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 base::Unretained(this)));
549bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
550bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InspectUI::StopListeningNotifications()
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!observer_.get())
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
555558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
556558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DevToolsAdbBridge* adb_bridge =
557558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      DevToolsAdbBridge::Factory::GetForProfile(profile);
558558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (adb_bridge)
559558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    adb_bridge->RemoveListener(this);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_->InspectUIDestroyed();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_ = NULL;
5622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  notification_registrar_.RemoveAll();
5632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  pref_change_registrar_.RemoveAll();
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebUIDataSource* InspectUI::CreateInspectUIHTMLSource() {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebUIDataSource* source =
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebUIDataSource::Create(chrome::kChromeUIInspectHost);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("inspect.css", IDR_INSPECT_CSS);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->AddResourcePath("inspect.js", IDR_INSPECT_JS);
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  source->SetDefaultResource(IDR_INSPECT_HTML);
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return source;
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void InspectUI::RemoteDevicesChanged(
576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DevToolsAdbBridge::RemoteDevices* devices) {
577bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  remote_browsers_.clear();
578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  remote_pages_.clear();
579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ListValue device_list;
580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (DevToolsAdbBridge::RemoteDevices::iterator dit = devices->begin();
581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       dit != devices->end(); ++dit) {
582bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DevToolsAdbBridge::RemoteDevice* device = dit->get();
583a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DictionaryValue* device_data = new DictionaryValue();
584bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    device_data->SetString(kAdbModelField, device->model());
585bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    device_data->SetString(kAdbSerialField, device->serial());
586bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    std::string device_id = base::StringPrintf(
587bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        "device:%s",
588bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        device->serial().c_str());
589bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    device_data->SetString(kAdbGlobalIdField, device_id);
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ListValue* browser_list = new ListValue();
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    device_data->Set(kAdbBrowsersField, browser_list);
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
593bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    DevToolsAdbBridge::RemoteBrowsers& browsers = device->browsers();
594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    for (DevToolsAdbBridge::RemoteBrowsers::iterator bit =
595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        browsers.begin(); bit != browsers.end(); ++bit) {
596bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DevToolsAdbBridge::RemoteBrowser* browser = bit->get();
597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      DictionaryValue* browser_data = new DictionaryValue();
598bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      browser_data->SetString(kAdbBrowserNameField, browser->name());
599bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      std::string browser_id = base::StringPrintf(
600bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          "browser:%s:%s:%s",
601bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          device->serial().c_str(),
602bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          browser->socket().c_str(),
603bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch          browser->name().c_str());
604bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      browser_data->SetString(kAdbGlobalIdField, browser_id);
605bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      remote_browsers_[browser_id] = browser;
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      ListValue* page_list = new ListValue();
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser_data->Set(kAdbPagesField, page_list);
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
609bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      DevToolsAdbBridge::RemotePages& pages = browser->pages();
610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      for (DevToolsAdbBridge::RemotePages::iterator it =
611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          pages.begin(); it != pages.end(); ++it) {
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        DevToolsAdbBridge::RemotePage* page =  it->get();
613bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        DictionaryValue* page_data = BuildTargetDescriptor(
614bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            kAdbTargetType, page->attached(),
615bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            GURL(page->url()), page->title(), GURL(page->favicon_url()),
616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            0, 0);
617bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        std::string page_id = base::StringPrintf("page:%s:%s:%s",
618bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            device->serial().c_str(),
619bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            browser->socket().c_str(),
620bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch            page->id().c_str());
621bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        page_data->SetString(kAdbGlobalIdField, page_id);
622bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        remote_pages_[page_id] = page;
623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        page_list->Append(page_data);
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      browser_list->Append(browser_data);
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    device_list.Append(device_data);
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  web_ui()->CallJavascriptFunction("populateDeviceLists", device_list);
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectUI::UpdatePortForwardingEnabled() {
6332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
6342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const base::Value* value = profile->GetPrefs()->FindPreference(
6352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingEnabled)->GetValue();
6362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->CallJavascriptFunction("updatePortForwardingEnabled", *value);
6372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
6392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
6402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid InspectUI::UpdatePortForwardingConfig() {
6412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  Profile* profile = Profile::FromWebUI(web_ui());
6422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  const base::Value* value = profile->GetPrefs()->FindPreference(
6432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      prefs::kDevToolsPortForwardingConfig)->GetValue();
6442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  web_ui()->CallJavascriptFunction("updatePortForwardingConfig", *value);
6452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
646