| OLD | NEW |
| (Empty) |
| 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_host.h" | |
| 11 #include "chrome/browser/extensions/extension_service.h" | |
| 12 #include "chrome/browser/extensions/extension_system.h" | |
| 13 #include "chrome/browser/extensions/extension_tab_util.h" | |
| 14 #include "chrome/browser/profiles/profile.h" | |
| 15 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | |
| 16 #include "chrome/common/extensions/extension_constants.h" | |
| 17 #include "content/public/browser/browser_thread.h" | |
| 18 #include "content/public/browser/favicon_status.h" | |
| 19 #include "content/public/browser/navigation_entry.h" | |
| 20 #include "content/public/browser/render_view_host.h" | |
| 21 #include "content/public/browser/web_contents.h" | |
| 22 | |
| 23 using content::BrowserThread; | |
| 24 using content::DevToolsAgentHost; | |
| 25 using content::RenderViewHost; | |
| 26 using content::WebContents; | |
| 27 using content::WorkerService; | |
| 28 | |
| 29 namespace { | |
| 30 | |
| 31 const char kTargetTypeApp[] = "app"; | |
| 32 const char kTargetTypeBackgroundPage[] = "background_page"; | |
| 33 const char kTargetTypePage[] = "page"; | |
| 34 const char kTargetTypeWorker[] = "worker"; | |
| 35 const char kTargetTypeOther[] = "other"; | |
| 36 | |
| 37 std::string GetExtensionName(WebContents* web_contents) { | |
| 38 Profile* profile = | |
| 39 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
| 40 if (!profile) | |
| 41 return std::string(); | |
| 42 | |
| 43 extensions::ExtensionHost* extension_host = | |
| 44 extensions::ExtensionSystem::Get(profile)->process_manager()-> | |
| 45 GetBackgroundHostForExtension(web_contents->GetURL().host()); | |
| 46 | |
| 47 if (!extension_host || extension_host->host_contents() != web_contents) | |
| 48 return std::string(); | |
| 49 | |
| 50 return extension_host->extension()->name(); | |
| 51 } | |
| 52 | |
| 53 class WebContentsTarget : public DevToolsTargetImpl { | |
| 54 public: | |
| 55 explicit WebContentsTarget(WebContents* web_contents); | |
| 56 | |
| 57 // content::DevToolsTarget overrides: | |
| 58 virtual bool Activate() const OVERRIDE; | |
| 59 virtual bool Close() const OVERRIDE; | |
| 60 | |
| 61 // DevToolsTargetImpl overrides: | |
| 62 virtual WebContents* GetWebContents() const OVERRIDE; | |
| 63 virtual int GetTabId() const OVERRIDE; | |
| 64 virtual std::string GetExtensionId() const OVERRIDE; | |
| 65 virtual void Inspect(Profile* profile) const OVERRIDE; | |
| 66 | |
| 67 private: | |
| 68 int tab_id_; | |
| 69 std::string extension_id_; | |
| 70 }; | |
| 71 | |
| 72 WebContentsTarget::WebContentsTarget(WebContents* web_contents) { | |
| 73 agent_host_ = | |
| 74 DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost()); | |
| 75 id_ = agent_host_->GetId(); | |
| 76 title_ = UTF16ToUTF8(web_contents->GetTitle()); | |
| 77 url_ = web_contents->GetURL(); | |
| 78 content::NavigationController& controller = web_contents->GetController(); | |
| 79 content::NavigationEntry* entry = controller.GetActiveEntry(); | |
| 80 if (entry != NULL && entry->GetURL().is_valid()) | |
| 81 favicon_url_ = entry->GetFavicon().url; | |
| 82 last_activity_time_ = web_contents->GetLastSelectedTime(); | |
| 83 | |
| 84 tab_id_ = ExtensionTabUtil::GetTabId(web_contents); | |
| 85 if (tab_id_ >= 0) { | |
| 86 type_ = kTargetTypePage; | |
| 87 } else { | |
| 88 type_ = kTargetTypeOther; | |
| 89 Profile* profile = | |
| 90 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
| 91 if (profile) { | |
| 92 ExtensionService* extension_service = profile->GetExtensionService(); | |
| 93 const extensions::Extension* extension = extension_service-> | |
| 94 extensions()->GetByID(url_.host()); | |
| 95 if (extension) { | |
| 96 title_ = extension->name(); | |
| 97 if (extension->is_hosted_app() | |
| 98 || extension->is_legacy_packaged_app() | |
| 99 || extension->is_platform_app()) { | |
| 100 type_ = kTargetTypeApp; | |
| 101 } else { | |
| 102 extensions::ExtensionHost* extension_host = | |
| 103 extensions::ExtensionSystem::Get(profile)->process_manager()-> | |
| 104 GetBackgroundHostForExtension(extension->id()); | |
| 105 if (extension_host && | |
| 106 extension_host->host_contents() == web_contents) { | |
| 107 type_ = kTargetTypeBackgroundPage; | |
| 108 extension_id_ = extension->id(); | |
| 109 } | |
| 110 } | |
| 111 favicon_url_ = extensions::ExtensionIconSource::GetIconURL( | |
| 112 extension, extension_misc::EXTENSION_ICON_SMALLISH, | |
| 113 ExtensionIconSet::MATCH_BIGGER, false, NULL); | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 std::string extension_name = GetExtensionName(web_contents); | |
| 118 if (!extension_name.empty()) { | |
| 119 type_ = kTargetTypeBackgroundPage; | |
| 120 title_ = extension_name; | |
| 121 } | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 bool WebContentsTarget::Activate() const { | |
| 126 WebContents* web_contents = GetWebContents(); | |
| 127 if (!web_contents) | |
| 128 return false; | |
| 129 web_contents->GetDelegate()->ActivateContents(web_contents); | |
| 130 return true; | |
| 131 } | |
| 132 | |
| 133 bool WebContentsTarget::Close() const { | |
| 134 RenderViewHost* rvh = agent_host_->GetRenderViewHost(); | |
| 135 if (!rvh) | |
| 136 return false; | |
| 137 rvh->ClosePage(); | |
| 138 return true; | |
| 139 } | |
| 140 | |
| 141 WebContents* WebContentsTarget::GetWebContents() const { | |
| 142 RenderViewHost* rvh = agent_host_->GetRenderViewHost(); | |
| 143 return rvh ? WebContents::FromRenderViewHost(rvh) : NULL; | |
| 144 } | |
| 145 | |
| 146 int WebContentsTarget::GetTabId() const { | |
| 147 return tab_id_; | |
| 148 } | |
| 149 | |
| 150 std::string WebContentsTarget::GetExtensionId() const { | |
| 151 return extension_id_; | |
| 152 } | |
| 153 | |
| 154 void WebContentsTarget::Inspect(Profile* profile) const { | |
| 155 RenderViewHost* rvh = agent_host_->GetRenderViewHost(); | |
| 156 if (!rvh) | |
| 157 return; | |
| 158 DevToolsWindow::OpenDevToolsWindow(rvh); | |
| 159 } | |
| 160 | |
| 161 /////////////////////////////////////////////////////////////////////////////// | |
| 162 | |
| 163 class WorkerTarget : public DevToolsTargetImpl { | |
| 164 public: | |
| 165 explicit WorkerTarget(const WorkerService::WorkerInfo& worker_info); | |
| 166 | |
| 167 // content::DevToolsTarget overrides: | |
| 168 virtual bool Close() const OVERRIDE; | |
| 169 | |
| 170 // DevToolsTargetImpl overrides: | |
| 171 virtual void Inspect(Profile* profile) const OVERRIDE; | |
| 172 | |
| 173 private: | |
| 174 int process_id_; | |
| 175 int route_id_; | |
| 176 }; | |
| 177 | |
| 178 WorkerTarget::WorkerTarget(const WorkerService::WorkerInfo& worker) { | |
| 179 agent_host_ = | |
| 180 DevToolsAgentHost::GetForWorker(worker.process_id, worker.route_id); | |
| 181 id_ = agent_host_->GetId(); | |
| 182 type_ = kTargetTypeWorker; | |
| 183 title_ = UTF16ToUTF8(worker.name); | |
| 184 description_ = | |
| 185 base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle)); | |
| 186 url_ = worker.url; | |
| 187 | |
| 188 process_id_ = worker.process_id; | |
| 189 route_id_ = worker.route_id; | |
| 190 } | |
| 191 | |
| 192 static void TerminateWorker(int process_id, int route_id) { | |
| 193 WorkerService::GetInstance()->TerminateWorker(process_id, route_id); | |
| 194 } | |
| 195 | |
| 196 bool WorkerTarget::Close() const { | |
| 197 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, | |
| 198 base::Bind(&TerminateWorker, process_id_, route_id_)); | |
| 199 return true; | |
| 200 } | |
| 201 | |
| 202 void WorkerTarget::Inspect(Profile* profile) const { | |
| 203 DevToolsWindow::OpenDevToolsWindowForWorker(profile, agent_host_.get()); | |
| 204 } | |
| 205 | |
| 206 } // namespace | |
| 207 | |
| 208 DevToolsTargetImpl::~DevToolsTargetImpl() { | |
| 209 } | |
| 210 | |
| 211 DevToolsTargetImpl::DevToolsTargetImpl() { | |
| 212 } | |
| 213 | |
| 214 std::string DevToolsTargetImpl::GetId() const { | |
| 215 return id_; | |
| 216 } | |
| 217 | |
| 218 std::string DevToolsTargetImpl::GetType() const { | |
| 219 return type_; | |
| 220 } | |
| 221 | |
| 222 std::string DevToolsTargetImpl::GetTitle() const { | |
| 223 return title_; | |
| 224 } | |
| 225 | |
| 226 std::string DevToolsTargetImpl::GetDescription() const { | |
| 227 return description_; | |
| 228 } | |
| 229 | |
| 230 GURL DevToolsTargetImpl::GetUrl() const { | |
| 231 return url_; | |
| 232 } | |
| 233 | |
| 234 GURL DevToolsTargetImpl::GetFaviconUrl() const { | |
| 235 return favicon_url_; | |
| 236 } | |
| 237 | |
| 238 base::TimeTicks DevToolsTargetImpl::GetLastActivityTime() const { | |
| 239 return last_activity_time_; | |
| 240 } | |
| 241 | |
| 242 scoped_refptr<content::DevToolsAgentHost> | |
| 243 DevToolsTargetImpl::GetAgentHost() const { | |
| 244 return agent_host_; | |
| 245 } | |
| 246 | |
| 247 bool DevToolsTargetImpl::IsAttached() const { | |
| 248 return agent_host_->IsAttached(); | |
| 249 } | |
| 250 | |
| 251 bool DevToolsTargetImpl::Activate() const { | |
| 252 return false; | |
| 253 } | |
| 254 | |
| 255 bool DevToolsTargetImpl::Close() const { | |
| 256 return false; | |
| 257 } | |
| 258 | |
| 259 int DevToolsTargetImpl::GetTabId() const { | |
| 260 return -1; | |
| 261 } | |
| 262 | |
| 263 WebContents* DevToolsTargetImpl::GetWebContents() const { | |
| 264 return NULL; | |
| 265 } | |
| 266 | |
| 267 std::string DevToolsTargetImpl::GetExtensionId() const { | |
| 268 return std::string(); | |
| 269 } | |
| 270 | |
| 271 void DevToolsTargetImpl::Inspect(Profile*) const { | |
| 272 } | |
| 273 | |
| 274 void DevToolsTargetImpl::Reload() const { | |
| 275 } | |
| 276 | |
| 277 // static | |
| 278 scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForWebContents( | |
| 279 content::WebContents* web_contents) { | |
| 280 return scoped_ptr<DevToolsTargetImpl>(new WebContentsTarget(web_contents)); | |
| 281 } | |
| 282 | |
| 283 // static | |
| 284 scoped_ptr<DevToolsTargetImpl> DevToolsTargetImpl::CreateForWorker( | |
| 285 const WorkerService::WorkerInfo& worker_info) { | |
| 286 return scoped_ptr<DevToolsTargetImpl>(new WorkerTarget(worker_info)); | |
| 287 } | |
| 288 | |
| 289 // static | |
| 290 DevToolsTargetImpl::List DevToolsTargetImpl::EnumerateWebContentsTargets() { | |
| 291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 292 DevToolsTargetImpl::List result; | |
| 293 std::vector<RenderViewHost*> rvh_list = | |
| 294 content::DevToolsAgentHost::GetValidRenderViewHosts(); | |
| 295 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); | |
| 296 it != rvh_list.end(); ++it) { | |
| 297 WebContents* web_contents = WebContents::FromRenderViewHost(*it); | |
| 298 if (web_contents) | |
| 299 result.push_back(new WebContentsTarget(web_contents)); | |
| 300 } | |
| 301 return result; | |
| 302 } | |
| 303 | |
| 304 static void CreateWorkerTargets( | |
| 305 const std::vector<WorkerService::WorkerInfo>& worker_info, | |
| 306 DevToolsTargetImpl::Callback callback) { | |
| 307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 308 DevToolsTargetImpl::List result; | |
| 309 for (size_t i = 0; i < worker_info.size(); ++i) { | |
| 310 result.push_back(new WorkerTarget(worker_info[i])); | |
| 311 } | |
| 312 callback.Run(result); | |
| 313 } | |
| 314 | |
| 315 // static | |
| 316 void DevToolsTargetImpl::EnumerateWorkerTargets(Callback callback) { | |
| 317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 318 content::BrowserThread::PostTask( | |
| 319 content::BrowserThread::UI, | |
| 320 FROM_HERE, | |
| 321 base::Bind(&CreateWorkerTargets, | |
| 322 WorkerService::GetInstance()->GetWorkers(), | |
| 323 callback)); | |
| 324 } | |
| 325 | |
| 326 static void CollectAllTargets( | |
| 327 DevToolsTargetImpl::Callback callback, | |
| 328 const DevToolsTargetImpl::List& worker_targets) { | |
| 329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 330 DevToolsTargetImpl::List result = | |
| 331 DevToolsTargetImpl::EnumerateWebContentsTargets(); | |
| 332 result.insert(result.begin(), worker_targets.begin(), worker_targets.end()); | |
| 333 callback.Run(result); | |
| 334 } | |
| 335 | |
| 336 // static | |
| 337 void DevToolsTargetImpl::EnumerateAllTargets(Callback callback) { | |
| 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 339 content::BrowserThread::PostTask( | |
| 340 content::BrowserThread::IO, | |
| 341 FROM_HERE, | |
| 342 base::Bind(&DevToolsTargetImpl::EnumerateWorkerTargets, | |
| 343 base::Bind(&CollectAllTargets, callback))); | |
| 344 } | |
| OLD | NEW |