devtools_target_impl.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/devtools/devtools_target_impl.h" 6 7#include "base/strings/stringprintf.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/devtools/devtools_window.h" 10#include "chrome/browser/extensions/extension_tab_util.h" 11#include "chrome/browser/profiles/profile.h" 12#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 13#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 14#include "chrome/common/extensions/extension_constants.h" 15#include "content/public/browser/browser_thread.h" 16#include "content/public/browser/favicon_status.h" 17#include "content/public/browser/navigation_entry.h" 18#include "content/public/browser/render_frame_host.h" 19#include "content/public/browser/render_view_host.h" 20#include "content/public/browser/web_contents.h" 21#include "extensions/browser/extension_host.h" 22#include "extensions/browser/extension_registry.h" 23#include "extensions/browser/extension_system.h" 24#include "extensions/browser/guest_view/guest_view_base.h" 25#include "extensions/browser/process_manager.h" 26#include "extensions/common/constants.h" 27 28using content::BrowserThread; 29using content::DevToolsAgentHost; 30using content::RenderViewHost; 31using content::WebContents; 32using content::WorkerService; 33 34const char DevToolsTargetImpl::kTargetTypeApp[] = "app"; 35const char DevToolsTargetImpl::kTargetTypeBackgroundPage[] = "background_page"; 36const char DevToolsTargetImpl::kTargetTypePage[] = "page"; 37const char DevToolsTargetImpl::kTargetTypeWorker[] = "worker"; 38const char DevToolsTargetImpl::kTargetTypeWebView[] = "webview"; 39const char DevToolsTargetImpl::kTargetTypeIFrame[] = "iframe"; 40const char DevToolsTargetImpl::kTargetTypeOther[] = "other"; 41const char DevToolsTargetImpl::kTargetTypeServiceWorker[] = "service_worker"; 42 43namespace { 44 45// WebContentsTarget -------------------------------------------------------- 46 47class WebContentsTarget : public DevToolsTargetImpl { 48 public: 49 WebContentsTarget(WebContents* web_contents, bool is_tab); 50 51 // DevToolsTargetImpl overrides: 52 virtual WebContents* GetWebContents() const OVERRIDE; 53 virtual int GetTabId() const OVERRIDE; 54 virtual std::string GetExtensionId() const OVERRIDE; 55 virtual void Inspect(Profile* profile) const OVERRIDE; 56 57 private: 58 int tab_id_; 59 std::string extension_id_; 60}; 61 62WebContentsTarget::WebContentsTarget(WebContents* web_contents, bool is_tab) 63 : DevToolsTargetImpl(DevToolsAgentHost::GetOrCreateFor(web_contents)), 64 tab_id_(-1) { 65 set_type(kTargetTypeOther); 66 67 content::RenderFrameHost* rfh = 68 web_contents->GetRenderViewHost()->GetMainFrame(); 69 if (rfh->IsCrossProcessSubframe()) { 70 set_url(rfh->GetLastCommittedURL()); 71 set_type(kTargetTypeIFrame); 72 // TODO(pfeldman) Update for out of process iframes. 73 RenderViewHost* parent_rvh = rfh->GetParent()->GetRenderViewHost(); 74 set_parent_id(DevToolsAgentHost::GetOrCreateFor( 75 WebContents::FromRenderViewHost(parent_rvh))->GetId()); 76 return; 77 } 78 79 content::NavigationController& controller = web_contents->GetController(); 80 content::NavigationEntry* entry = controller.GetActiveEntry(); 81 if (entry != NULL && entry->GetURL().is_valid()) 82 set_favicon_url(entry->GetFavicon().url); 83 set_last_activity_time(web_contents->GetLastActiveTime()); 84 85 extensions::GuestViewBase* guest = 86 extensions::GuestViewBase::FromWebContents(web_contents); 87 WebContents* guest_contents = guest ? guest->embedder_web_contents() : NULL; 88 if (guest_contents) { 89 set_type(kTargetTypeWebView); 90 set_parent_id(DevToolsAgentHost::GetOrCreateFor(guest_contents)->GetId()); 91 return; 92 } 93 94 if (is_tab) { 95 set_type(kTargetTypePage); 96 tab_id_ = extensions::ExtensionTabUtil::GetTabId(web_contents); 97 return; 98 } 99 100 const extensions::Extension* extension = extensions::ExtensionRegistry::Get( 101 web_contents->GetBrowserContext())->enabled_extensions().GetByID( 102 GetURL().host()); 103 if (!extension) 104 return; 105 106 Profile* profile = 107 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 108 if (!profile) 109 return; 110 extensions::ExtensionSystem* extension_system = 111 extensions::ExtensionSystem::Get(profile); 112 set_title(extension->name()); 113 extensions::ExtensionHost* extension_host = 114 extension_system->process_manager()->GetBackgroundHostForExtension( 115 extension->id()); 116 if (extension_host && 117 extension_host->host_contents() == web_contents) { 118 set_type(kTargetTypeBackgroundPage); 119 extension_id_ = extension->id(); 120 } else if (extension->is_hosted_app() 121 || extension->is_legacy_packaged_app() 122 || extension->is_platform_app()) { 123 set_type(kTargetTypeApp); 124 } 125 set_favicon_url(extensions::ExtensionIconSource::GetIconURL( 126 extension, extension_misc::EXTENSION_ICON_SMALLISH, 127 ExtensionIconSet::MATCH_BIGGER, false, NULL)); 128} 129 130WebContents* WebContentsTarget::GetWebContents() const { 131 return GetAgentHost()->GetWebContents(); 132} 133 134int WebContentsTarget::GetTabId() const { 135 return tab_id_; 136} 137 138std::string WebContentsTarget::GetExtensionId() const { 139 return extension_id_; 140} 141 142void WebContentsTarget::Inspect(Profile* profile) const { 143 WebContents* web_contents = GetWebContents(); 144 if (!web_contents) 145 return; 146 DevToolsWindow::OpenDevToolsWindow(web_contents); 147} 148 149// WorkerTarget ---------------------------------------------------------------- 150 151class WorkerTarget : public DevToolsTargetImpl { 152 public: 153 explicit WorkerTarget(scoped_refptr<DevToolsAgentHost> agent_host); 154 155 // DevToolsTargetImpl overrides: 156 virtual void Inspect(Profile* profile) const OVERRIDE; 157}; 158 159WorkerTarget::WorkerTarget(scoped_refptr<DevToolsAgentHost> agent_host) 160 : DevToolsTargetImpl(agent_host) { 161 switch (agent_host->GetType()) { 162 case DevToolsAgentHost::TYPE_SHARED_WORKER: 163 set_type(kTargetTypeWorker); 164 break; 165 case DevToolsAgentHost::TYPE_SERVICE_WORKER: 166 set_type(kTargetTypeServiceWorker); 167 break; 168 default: 169 NOTREACHED(); 170 } 171} 172 173void WorkerTarget::Inspect(Profile* profile) const { 174 DevToolsWindow::OpenDevToolsWindowForWorker(profile, GetAgentHost()); 175} 176 177} // namespace 178 179// DevToolsTargetImpl ---------------------------------------------------------- 180 181DevToolsTargetImpl::~DevToolsTargetImpl() { 182} 183 184DevToolsTargetImpl::DevToolsTargetImpl( 185 scoped_refptr<DevToolsAgentHost> agent_host) 186 : agent_host_(agent_host), 187 title_(agent_host->GetTitle()), 188 url_(agent_host->GetURL()) { 189} 190 191std::string DevToolsTargetImpl::GetParentId() const { 192 return parent_id_; 193} 194 195std::string DevToolsTargetImpl::GetId() const { 196 return agent_host_->GetId(); 197} 198 199std::string DevToolsTargetImpl::GetType() const { 200 return type_; 201} 202 203std::string DevToolsTargetImpl::GetTitle() const { 204 return title_; 205} 206 207std::string DevToolsTargetImpl::GetDescription() const { 208 return description_; 209} 210 211GURL DevToolsTargetImpl::GetURL() const { 212 return url_; 213} 214 215GURL DevToolsTargetImpl::GetFaviconURL() const { 216 return favicon_url_; 217} 218 219base::TimeTicks DevToolsTargetImpl::GetLastActivityTime() const { 220 return last_activity_time_; 221} 222 223scoped_refptr<content::DevToolsAgentHost> 224DevToolsTargetImpl::GetAgentHost() const { 225 return agent_host_; 226} 227 228bool DevToolsTargetImpl::IsAttached() const { 229 return agent_host_->IsAttached(); 230} 231 232bool DevToolsTargetImpl::Activate() const { 233 return agent_host_->Activate(); 234} 235 236bool DevToolsTargetImpl::Close() const { 237 return agent_host_->Close(); 238} 239 240int DevToolsTargetImpl::GetTabId() const { 241 return -1; 242} 243 244WebContents* DevToolsTargetImpl::GetWebContents() const { 245 return NULL; 246} 247 248std::string DevToolsTargetImpl::GetExtensionId() const { 249 return std::string(); 250} 251 252void DevToolsTargetImpl::Inspect(Profile* /*profile*/) const { 253} 254 255void DevToolsTargetImpl::Reload() const { 256} 257 258// static 259scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForWebContents( 260 content::WebContents* web_contents, 261 bool is_tab) { 262 return scoped_ptr<DevToolsTargetImpl>( 263 new WebContentsTarget(web_contents, is_tab)); 264} 265 266// static 267void DevToolsTargetImpl::EnumerateAllTargets(Callback callback) { 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 269 270 std::set<WebContents*> tab_web_contents; 271 for (TabContentsIterator it; !it.done(); it.Next()) 272 tab_web_contents.insert(*it); 273 274 DevToolsTargetImpl::List result; 275 DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll(); 276 for (DevToolsAgentHost::List::iterator it = agents.begin(); 277 it != agents.end(); ++it) { 278 DevToolsAgentHost* agent_host = (*it).get(); 279 switch (agent_host->GetType()) { 280 case DevToolsAgentHost::TYPE_WEB_CONTENTS: 281 if (WebContents* web_contents = agent_host->GetWebContents()) { 282 const bool is_tab = 283 tab_web_contents.find(web_contents) != tab_web_contents.end(); 284 result.push_back(new WebContentsTarget(web_contents, is_tab)); 285 } 286 break; 287 case DevToolsAgentHost::TYPE_SHARED_WORKER: 288 result.push_back(new WorkerTarget(agent_host)); 289 break; 290 case DevToolsAgentHost::TYPE_SERVICE_WORKER: 291 result.push_back(new WorkerTarget(agent_host)); 292 break; 293 default: 294 break; 295 } 296 } 297 298 callback.Run(result); 299} 300