inspect_ui.cc revision 3240926e260ce088908e02ac07a6cf7b0c0cbf44
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> 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind_helpers.h" 11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/json/json_writer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted_memory.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_util.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/values.h" 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/devtools/devtools_window.h" 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/theme_source.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/url_constants.h" 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/child_process_data.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_agent_host.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_client_host.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_manager.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/favicon_status.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_data_source.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_ui_message_handler.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/worker_service.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/worker_service_observer.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/process_type.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::ChildProcessData; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsClientHost; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsManager; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderProcessHost; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHostDelegate; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using content::WebUIMessageHandler; 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using content::WorkerService; 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using content::WorkerServiceObserver; 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kDataFile[] = "targets-data.json"; 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbPages[] = "adb-pages"; 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kAppTargetType[] = "app"; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static const char kExtensionTargetType[] = "extension"; 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static const char kPageTargetType[] = "page"; 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static const char kWorkerTargetType[] = "worker"; 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)static const char kAdbTargetType[] = "adb_page"; 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kInitUICommand[] = "init-ui"; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kInspectCommand[] = "inspect"; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kTerminateCommand[] = "terminate"; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kPortForwardingEnabledCommand[] = 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "set-port-forwarding-enabled"; 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kPortForwardingConfigCommand[] = "set-port-forwarding-config"; 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kTargetTypeField[] = "type"; 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAttachedField[] = "attached"; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kProcessIdField[] = "processId"; 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kRouteIdField[] = "routeId"; 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kUrlField[] = "url"; 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kNameField[] = "name"; 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kFaviconUrlField[] = "faviconUrl"; 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kPidField[] = "pid"; 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbSerialField[] = "adbSerial"; 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbModelField[] = "adbModel"; 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbBrowserNameField[] = "adbBrowserName"; 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbPageIdField[] = "adbPageId"; 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbBrowsersField[] = "browsers"; 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAdbPagesField[] = "pages"; 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 96116680a4aac90f2aa7413d9095a592090648e557Ben MurdochDictionaryValue* BuildTargetDescriptor( 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& target_type, 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool attached, 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url, 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& name, 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const GURL& favicon_url, 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int process_id, 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int route_id, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle handle = base::kNullProcessHandle) { 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryValue* target_data = new DictionaryValue(); 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target_data->SetString(kTargetTypeField, target_type); 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch target_data->SetBoolean(kAttachedField, attached); 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetInteger(kProcessIdField, process_id); 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetInteger(kRouteIdField, route_id); 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetString(kUrlField, url.spec()); 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetString(kNameField, net::EscapeForHTML(name)); 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetInteger(kPidField, base::GetProcId(handle)); 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) target_data->SetString(kFaviconUrlField, favicon_url.spec()); 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return target_data; 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool HasClientHost(RenderViewHost* rvh) { 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!DevToolsAgentHost::HasFor(rvh)) 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<DevToolsAgentHost> agent( 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DevToolsAgentHost::GetOrCreateFor(rvh)); 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return agent->IsAttached(); 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* BuildTargetDescriptor(RenderViewHost* rvh, bool is_tab) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* web_contents = WebContents::FromRenderViewHost(rvh); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string title; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string target_type = is_tab ? kPageTargetType : ""; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url; 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GURL favicon_url; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (web_contents) { 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch url = web_contents->GetURL(); 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) title = UTF16ToUTF8(web_contents->GetTitle()); 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) content::NavigationController& controller = web_contents->GetController(); 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) content::NavigationEntry* entry = controller.GetActiveEntry(); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entry != NULL && entry->GetURL().is_valid()) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) favicon_url = entry->GetFavicon().url; 1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Profile* profile = Profile::FromBrowserContext( 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_contents->GetBrowserContext()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile) { 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ExtensionService* extension_service = profile->GetExtensionService(); 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const extensions::Extension* extension = extension_service-> 1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) extensions()->GetByID(url.host()); 1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (extension) { 1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (extension->is_hosted_app() 1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || extension->is_legacy_packaged_app() 1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) || extension->is_platform_app()) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_type = kAppTargetType; 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) target_type = kExtensionTargetType; 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch title = extension->name(); 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return BuildTargetDescriptor(target_type, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HasClientHost(rvh), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url, 1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) title, 1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) favicon_url, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rvh->GetProcess()->GetID(), 1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) rvh->GetRoutingID()); 1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class InspectMessageHandler : public WebUIMessageHandler { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit InspectMessageHandler(InspectUI* inspect_ui) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : inspect_ui_(inspect_ui) {} 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~InspectMessageHandler() {} 1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private: 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // WebUIMessageHandler implementation. 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RegisterMessages() OVERRIDE; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void HandleInitUICommand(const ListValue* args); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void HandleInspectCommand(const ListValue* args); 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void HandleTerminateCommand(const ListValue* args); 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void HandlePortForwardingEnabledCommand(const ListValue* args); 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void HandlePortForwardingConfigCommand(const ListValue* args); 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool GetProcessAndRouteId(const ListValue* args, 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int* process_id, 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int* route_id); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 188116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch InspectUI* inspect_ui_; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DISALLOW_COPY_AND_ASSIGN(InspectMessageHandler); 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InspectMessageHandler::RegisterMessages() { 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_ui()->RegisterMessageCallback(kInitUICommand, 1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&InspectMessageHandler::HandleInitUICommand, 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Unretained(this))); 1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) web_ui()->RegisterMessageCallback(kInspectCommand, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&InspectMessageHandler::HandleInspectCommand, 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Unretained(this))); 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch web_ui()->RegisterMessageCallback(kTerminateCommand, 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&InspectMessageHandler::HandleTerminateCommand, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) web_ui()->RegisterMessageCallback(kPortForwardingEnabledCommand, 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&InspectMessageHandler::HandlePortForwardingEnabledCommand, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_ui()->RegisterMessageCallback(kPortForwardingConfigCommand, 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&InspectMessageHandler::HandlePortForwardingConfigCommand, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InspectMessageHandler::HandleInitUICommand(const ListValue*) { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) inspect_ui_->InitUI(); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InspectMessageHandler::HandleInspectCommand(const ListValue* args) { 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!profile) 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int process_id; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int route_id; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetProcessAndRouteId(args, &process_id, &route_id) || process_id == 0 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) || route_id == 0) { 2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Check for ADB page id 2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const DictionaryValue* data; 2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::string page_id; 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (args->GetSize() == 1 && args->GetDictionary(0, &data) && 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) data->GetString(kAdbPageIdField, &page_id)) { 2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) inspect_ui_->InspectRemotePage(page_id); 2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RenderViewHost* rvh = RenderViewHost::FromID(process_id, route_id); 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (rvh) { 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DevToolsWindow::OpenDevToolsWindow(rvh); 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<DevToolsAgentHost> agent_host( 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DevToolsAgentHost::GetForWorker(process_id, route_id)); 2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!agent_host.get()) 2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host.get()); 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static void TerminateWorker(int process_id, int route_id) { 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) WorkerService::GetInstance()->TerminateWorker(process_id, route_id); 2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void InspectMessageHandler::HandleTerminateCommand(const ListValue* args) { 2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int process_id; 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int route_id; 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!GetProcessAndRouteId(args, &process_id, &route_id)) 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&TerminateWorker, process_id, route_id)); 2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool InspectMessageHandler::GetProcessAndRouteId(const ListValue* args, 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int* process_id, 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int* route_id) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DictionaryValue* data; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args->GetSize() == 1 && args->GetDictionary(0, &data) && 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->GetInteger(kProcessIdField, process_id) && 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->GetInteger(kRouteIdField, route_id)) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void InspectMessageHandler::HandlePortForwardingEnabledCommand( 2756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const ListValue* args) { 2766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 2776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!profile) 2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool enabled; 2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (args->GetSize() == 1 && args->GetBoolean(0, &enabled)) { 2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) profile->GetPrefs()->SetBoolean( 2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) prefs::kDevToolsPortForwardingEnabled, enabled); 2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void InspectMessageHandler::HandlePortForwardingConfigCommand( 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ListValue* args) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile = Profile::FromWebUI(web_ui()); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!profile) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const DictionaryValue* dict_src; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (args->GetSize() == 1 && args->GetDictionary(0, &dict_src)) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile->GetPrefs()->Set(prefs::kDevToolsPortForwardingConfig, *dict_src); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass InspectUI::WorkerCreationDestructionListener 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public WorkerServiceObserver, 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::RefCountedThreadSafe<WorkerCreationDestructionListener> { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerCreationDestructionListener() 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : discovery_ui_(NULL) {} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void Init(InspectUI* workers_ui) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(workers_ui); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!discovery_ui_); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) discovery_ui_ = workers_ui; 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::PostTask( 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WorkerCreationDestructionListener::RegisterObserver, 3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) this)); 3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InspectUIDestroyed() { 3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(discovery_ui_); 3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) discovery_ui_ = NULL; 3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::PostTask( 3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&WorkerCreationDestructionListener::UnregisterObserver, 3236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) this)); 3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void InitUI() { 3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::PostTask( 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BrowserThread::IO, FROM_HERE, 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&WorkerCreationDestructionListener::CollectWorkersData, 3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) this)); 3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private: 3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) friend class base::RefCountedThreadSafe<WorkerCreationDestructionListener>; 335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual ~WorkerCreationDestructionListener() {} 3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void WorkerCreated( 338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const GURL& url, 339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const string16& name, 3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int process_id, 3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int route_id) OVERRIDE { 342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CollectWorkersData(); 3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 3446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void WorkerDestroyed(int process_id, int route_id) OVERRIDE { 3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CollectWorkersData(); 347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CollectWorkersData() { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 351 scoped_ptr<ListValue> target_list(new ListValue()); 352 std::vector<WorkerService::WorkerInfo> worker_info = 353 WorkerService::GetInstance()->GetWorkers(); 354 for (size_t i = 0; i < worker_info.size(); ++i) { 355 target_list->Append(BuildTargetDescriptor( 356 kWorkerTargetType, 357 false, 358 worker_info[i].url, 359 UTF16ToUTF8(worker_info[i].name), 360 GURL(), 361 worker_info[i].process_id, 362 worker_info[i].route_id, 363 worker_info[i].handle)); 364 } 365 366 BrowserThread::PostTask( 367 BrowserThread::UI, FROM_HERE, 368 base::Bind(&WorkerCreationDestructionListener::PopulateWorkersList, 369 this, base::Owned(target_list.release()))); 370 } 371 372 void RegisterObserver() { 373 WorkerService::GetInstance()->AddObserver(this); 374 } 375 376 void UnregisterObserver() { 377 WorkerService::GetInstance()->RemoveObserver(this); 378 } 379 380 void PopulateWorkersList(ListValue* target_list) { 381 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 382 if (discovery_ui_) { 383 discovery_ui_->web_ui()->CallJavascriptFunction( 384 "populateWorkersList", *target_list); 385 } 386 } 387 388 InspectUI* discovery_ui_; 389}; 390 391InspectUI::InspectUI(content::WebUI* web_ui) 392 : WebUIController(web_ui) { 393 web_ui->AddMessageHandler(new InspectMessageHandler(this)); 394 Profile* profile = Profile::FromWebUI(web_ui); 395 content::WebUIDataSource::Add(profile, CreateInspectUIHTMLSource()); 396 397 // Set up the chrome://theme/ source. 398 ThemeSource* theme = new ThemeSource(profile); 399 content::URLDataSource::Add(profile, theme); 400} 401 402InspectUI::~InspectUI() { 403 StopListeningNotifications(); 404} 405 406void InspectUI::InitUI() { 407 StartListeningNotifications(); 408 PopulateLists(); 409 UpdatePortForwardingEnabled(); 410 UpdatePortForwardingConfig(); 411 observer_->InitUI(); 412} 413 414void InspectUI::InspectRemotePage(const std::string& id) { 415 RemotePages::iterator it = remote_pages_.find(id); 416 if (it != remote_pages_.end()) { 417 Profile* profile = Profile::FromWebUI(web_ui()); 418 it->second->Inspect(profile); 419 } 420} 421 422void InspectUI::PopulateLists() { 423 std::set<RenderViewHost*> tab_rvhs; 424 for (TabContentsIterator it; !it.done(); it.Next()) 425 tab_rvhs.insert(it->GetRenderViewHost()); 426 427 scoped_ptr<ListValue> target_list(new ListValue()); 428 429 std::vector<RenderViewHost*> rvh_vector = 430 DevToolsAgentHost::GetValidRenderViewHosts(); 431 432 for (std::vector<RenderViewHost*>::iterator it(rvh_vector.begin()); 433 it != rvh_vector.end(); it++) { 434 bool is_tab = tab_rvhs.find(*it) != tab_rvhs.end(); 435 target_list->Append(BuildTargetDescriptor(*it, is_tab)); 436 } 437 web_ui()->CallJavascriptFunction("populateLists", *target_list.get()); 438} 439 440void InspectUI::Observe(int type, 441 const content::NotificationSource& source, 442 const content::NotificationDetails& details) { 443 if (source != content::Source<WebContents>(web_ui()->GetWebContents())) 444 PopulateLists(); 445 else if (type == content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED) 446 StopListeningNotifications(); 447} 448 449void InspectUI::StartListeningNotifications() { 450 if (observer_) 451 return; 452 453 observer_ = new WorkerCreationDestructionListener(); 454 observer_->Init(this); 455 456 Profile* profile = Profile::FromWebUI(web_ui()); 457 DevToolsAdbBridge* adb_bridge = 458 DevToolsAdbBridge::Factory::GetForProfile(profile); 459 if (adb_bridge) 460 adb_bridge->AddListener(this); 461 462 notification_registrar_.Add(this, 463 content::NOTIFICATION_WEB_CONTENTS_CONNECTED, 464 content::NotificationService::AllSources()); 465 notification_registrar_.Add(this, 466 content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, 467 content::NotificationService::AllSources()); 468 notification_registrar_.Add(this, 469 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 470 content::NotificationService::AllSources()); 471 472 pref_change_registrar_.Init(profile->GetPrefs()); 473 pref_change_registrar_.Add(prefs::kDevToolsPortForwardingEnabled, 474 base::Bind(&InspectUI::UpdatePortForwardingEnabled, 475 base::Unretained(this))); 476 pref_change_registrar_.Add(prefs::kDevToolsPortForwardingConfig, 477 base::Bind(&InspectUI::UpdatePortForwardingConfig, 478 base::Unretained(this))); 479} 480 481void InspectUI::StopListeningNotifications() 482{ 483 if (!observer_.get()) 484 return; 485 Profile* profile = Profile::FromWebUI(web_ui()); 486 DevToolsAdbBridge* adb_bridge = 487 DevToolsAdbBridge::Factory::GetForProfile(profile); 488 if (adb_bridge) 489 adb_bridge->RemoveListener(this); 490 observer_->InspectUIDestroyed(); 491 observer_ = NULL; 492 notification_registrar_.RemoveAll(); 493 pref_change_registrar_.RemoveAll(); 494} 495 496content::WebUIDataSource* InspectUI::CreateInspectUIHTMLSource() { 497 content::WebUIDataSource* source = 498 content::WebUIDataSource::Create(chrome::kChromeUIInspectHost); 499 source->AddResourcePath("inspect.css", IDR_INSPECT_CSS); 500 source->AddResourcePath("inspect.js", IDR_INSPECT_JS); 501 source->SetDefaultResource(IDR_INSPECT_HTML); 502 return source; 503} 504 505void InspectUI::RemoteDevicesChanged( 506 DevToolsAdbBridge::RemoteDevices* devices) { 507 remote_pages_.clear(); 508 ListValue device_list; 509 for (DevToolsAdbBridge::RemoteDevices::iterator dit = devices->begin(); 510 dit != devices->end(); ++dit) { 511 DevToolsAdbBridge::RemoteDevice& device = *(dit->get()); 512 DictionaryValue* device_data = new DictionaryValue(); 513 device_data->SetString(kAdbModelField, device.model()); 514 device_data->SetString(kAdbSerialField, device.serial()); 515 ListValue* browser_list = new ListValue(); 516 device_data->Set(kAdbBrowsersField, browser_list); 517 518 DevToolsAdbBridge::RemoteBrowsers& browsers = device.browsers(); 519 for (DevToolsAdbBridge::RemoteBrowsers::iterator bit = 520 browsers.begin(); bit != browsers.end(); ++bit) { 521 DevToolsAdbBridge::RemoteBrowser& browser = *(bit->get()); 522 DictionaryValue* browser_data = new DictionaryValue(); 523 browser_data->SetString(kAdbBrowserNameField, browser.name()); 524 ListValue* page_list = new ListValue(); 525 browser_data->Set(kAdbPagesField, page_list); 526 527 DevToolsAdbBridge::RemotePages& pages = browser.pages(); 528 for (DevToolsAdbBridge::RemotePages::iterator it = 529 pages.begin(); it != pages.end(); ++it) { 530 DevToolsAdbBridge::RemotePage* page = it->get(); 531 DictionaryValue* page_data = BuildTargetDescriptor(kAdbTargetType, 532 false, GURL(page->url()), page->title(), GURL(page->favicon_url()), 533 0, 0); 534 page_data->SetString(kAdbPageIdField, page->global_id()); 535 page_list->Append(page_data); 536 remote_pages_[page->global_id()] = page; 537 } 538 browser_list->Append(browser_data); 539 } 540 device_list.Append(device_data); 541 } 542 web_ui()->CallJavascriptFunction("populateDeviceLists", device_list); 543} 544 545void InspectUI::UpdatePortForwardingEnabled() { 546 Profile* profile = Profile::FromWebUI(web_ui()); 547 const base::Value* value = profile->GetPrefs()->FindPreference( 548 prefs::kDevToolsPortForwardingEnabled)->GetValue(); 549 web_ui()->CallJavascriptFunction("updatePortForwardingEnabled", *value); 550 551} 552 553void InspectUI::UpdatePortForwardingConfig() { 554 Profile* profile = Profile::FromWebUI(web_ui()); 555 const base::Value* value = profile->GetPrefs()->FindPreference( 556 prefs::kDevToolsPortForwardingConfig)->GetValue(); 557 web_ui()->CallJavascriptFunction("updatePortForwardingConfig", *value); 558} 559