OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h" | 5 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h" |
6 | 6 |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/strings/utf_string_conversions.h" |
9 #include "chrome/browser/extensions/extension_host.h" | 11 #include "chrome/browser/extensions/extension_host.h" |
10 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
11 #include "chrome/browser/extensions/extension_system.h" | 13 #include "chrome/browser/extensions/extension_system.h" |
12 #include "chrome/browser/history/top_sites.h" | 14 #include "chrome/browser/history/top_sites.h" |
13 #include "chrome/browser/profiles/profile_manager.h" | 15 #include "chrome/browser/profiles/profile_manager.h" |
14 #include "chrome/browser/ui/browser.h" | 16 #include "chrome/browser/ui/browser.h" |
15 #include "chrome/browser/ui/browser_commands.h" | 17 #include "chrome/browser/ui/browser_commands.h" |
16 #include "chrome/browser/ui/browser_iterator.h" | 18 #include "chrome/browser/ui/browser_iterator.h" |
17 #include "chrome/browser/ui/browser_list.h" | 19 #include "chrome/browser/ui/browser_list.h" |
18 #include "chrome/browser/ui/browser_tabstrip.h" | 20 #include "chrome/browser/ui/browser_tabstrip.h" |
19 #include "chrome/browser/ui/host_desktop.h" | 21 #include "chrome/browser/ui/host_desktop.h" |
20 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" | 22 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" |
21 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
22 #include "chrome/common/chrome_paths.h" | 24 #include "chrome/common/chrome_paths.h" |
| 25 #include "content/public/browser/browser_thread.h" |
| 26 #include "content/public/browser/devtools_target.h" |
| 27 #include "content/public/browser/favicon_status.h" |
| 28 #include "content/public/browser/navigation_entry.h" |
| 29 #include "content/public/browser/render_view_host.h" |
23 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
24 #include "content/public/common/url_constants.h" | 31 #include "content/public/common/url_constants.h" |
25 #include "grit/devtools_discovery_page_resources.h" | 32 #include "grit/devtools_discovery_page_resources.h" |
| 33 #include "net/base/escape.h" |
26 #include "net/socket/tcp_listen_socket.h" | 34 #include "net/socket/tcp_listen_socket.h" |
27 #include "net/url_request/url_request_context_getter.h" | 35 #include "net/url_request/url_request_context_getter.h" |
28 #include "ui/base/resource/resource_bundle.h" | 36 #include "ui/base/resource/resource_bundle.h" |
29 | 37 |
| 38 using content::DevToolsAgentHost; |
30 using content::DevToolsHttpHandlerDelegate; | 39 using content::DevToolsHttpHandlerDelegate; |
| 40 using content::DevToolsTarget; |
31 using content::RenderViewHost; | 41 using content::RenderViewHost; |
| 42 using content::WebContents; |
| 43 |
| 44 namespace { |
| 45 |
| 46 const char kTargetTypePage[] = "page"; |
| 47 const char kTargetTypeOther[] = "other"; |
| 48 |
| 49 std::string GetExtensionName(WebContents* web_contents) { |
| 50 Profile* profile = |
| 51 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| 52 if (!profile) |
| 53 return std::string(); |
| 54 |
| 55 extensions::ExtensionHost* extension_host = |
| 56 extensions::ExtensionSystem::Get(profile)->process_manager()-> |
| 57 GetBackgroundHostForExtension(web_contents->GetURL().host()); |
| 58 |
| 59 if (!extension_host || extension_host->host_contents() != web_contents) |
| 60 return std::string(); |
| 61 |
| 62 return extension_host->extension()->name(); |
| 63 } |
| 64 |
| 65 class Target : public content::DevToolsTarget { |
| 66 public: |
| 67 Target(WebContents* web_contents, bool is_tab); |
| 68 |
| 69 virtual std::string GetId() const OVERRIDE { return id_; } |
| 70 virtual std::string GetType() const OVERRIDE { return type_; } |
| 71 virtual std::string GetTitle() const OVERRIDE { return title_; } |
| 72 virtual std::string GetDescription() const OVERRIDE { return description_; } |
| 73 virtual GURL GetUrl() const OVERRIDE { return url_; } |
| 74 virtual GURL GetFaviconUrl() const OVERRIDE { return favicon_url_; } |
| 75 virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { |
| 76 return last_activity_time_; |
| 77 } |
| 78 virtual bool IsAttached() const OVERRIDE { |
| 79 return agent_host_->IsAttached(); |
| 80 } |
| 81 virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { |
| 82 return agent_host_; |
| 83 } |
| 84 virtual bool Activate() const OVERRIDE; |
| 85 virtual bool Close() const OVERRIDE; |
| 86 |
| 87 private: |
| 88 scoped_refptr<DevToolsAgentHost> agent_host_; |
| 89 std::string id_; |
| 90 std::string type_; |
| 91 std::string title_; |
| 92 std::string description_; |
| 93 GURL url_; |
| 94 GURL favicon_url_; |
| 95 base::TimeTicks last_activity_time_; |
| 96 }; |
| 97 |
| 98 Target::Target(WebContents* web_contents, bool is_tab) { |
| 99 agent_host_ = |
| 100 DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost()); |
| 101 id_ = agent_host_->GetId(); |
| 102 type_ = is_tab ? kTargetTypePage : kTargetTypeOther; |
| 103 description_ = GetExtensionName(web_contents); |
| 104 title_ = UTF16ToUTF8(net::EscapeForHTML(web_contents->GetTitle())); |
| 105 url_ = web_contents->GetURL(); |
| 106 content::NavigationController& controller = web_contents->GetController(); |
| 107 content::NavigationEntry* entry = controller.GetActiveEntry(); |
| 108 if (entry != NULL && entry->GetURL().is_valid()) |
| 109 favicon_url_ = entry->GetFavicon().url; |
| 110 last_activity_time_ = web_contents->GetLastSelectedTime(); |
| 111 } |
| 112 |
| 113 bool Target::Activate() const { |
| 114 RenderViewHost* rvh = agent_host_->GetRenderViewHost(); |
| 115 if (!rvh) |
| 116 return false; |
| 117 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| 118 if (!web_contents) |
| 119 return false; |
| 120 web_contents->GetDelegate()->ActivateContents(web_contents); |
| 121 return true; |
| 122 } |
| 123 |
| 124 bool Target::Close() const { |
| 125 RenderViewHost* rvh = agent_host_->GetRenderViewHost(); |
| 126 if (!rvh) |
| 127 return false; |
| 128 rvh->ClosePage(); |
| 129 return true; |
| 130 } |
| 131 |
| 132 class WorkerTarget : public content::DevToolsTarget { |
| 133 public: |
| 134 explicit WorkerTarget(const content::WorkerService::WorkerInfo& worker_info); |
| 135 |
| 136 virtual std::string GetId() const OVERRIDE { return id_; } |
| 137 virtual std::string GetType() const OVERRIDE { return "other"; } |
| 138 virtual std::string GetTitle() const OVERRIDE { return title_; } |
| 139 virtual std::string GetDescription() const OVERRIDE { return description_; } |
| 140 virtual GURL GetUrl() const OVERRIDE { return url_; } |
| 141 virtual GURL GetFaviconUrl() const OVERRIDE { return GURL(); } |
| 142 virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { |
| 143 return base::TimeTicks(); |
| 144 } |
| 145 virtual bool IsAttached() const OVERRIDE { |
| 146 return agent_host_->IsAttached(); |
| 147 } |
| 148 virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { |
| 149 return agent_host_; |
| 150 } |
| 151 virtual bool Activate() const OVERRIDE { return false; } |
| 152 virtual bool Close() const OVERRIDE { return false; } |
| 153 |
| 154 private: |
| 155 scoped_refptr<DevToolsAgentHost> agent_host_; |
| 156 std::string id_; |
| 157 std::string title_; |
| 158 std::string description_; |
| 159 GURL url_; |
| 160 }; |
| 161 |
| 162 WorkerTarget::WorkerTarget(const content::WorkerService::WorkerInfo& worker) { |
| 163 agent_host_ = |
| 164 DevToolsAgentHost::GetForWorker(worker.process_id, worker.route_id); |
| 165 id_ = agent_host_->GetId(); |
| 166 title_ = UTF16ToUTF8(net::EscapeForHTML(worker.name)); |
| 167 description_ = |
| 168 base::StringPrintf("Worker pid:%d", base::GetProcId(worker.handle)); |
| 169 url_ = worker.url; |
| 170 } |
| 171 |
| 172 } // namespace |
32 | 173 |
33 BrowserListTabContentsProvider::BrowserListTabContentsProvider( | 174 BrowserListTabContentsProvider::BrowserListTabContentsProvider( |
34 chrome::HostDesktopType host_desktop_type) | 175 chrome::HostDesktopType host_desktop_type) |
35 : host_desktop_type_(host_desktop_type) { | 176 : host_desktop_type_(host_desktop_type) { |
36 } | 177 } |
37 | 178 |
38 BrowserListTabContentsProvider::~BrowserListTabContentsProvider() { | 179 BrowserListTabContentsProvider::~BrowserListTabContentsProvider() { |
39 } | 180 } |
40 | 181 |
41 std::string BrowserListTabContentsProvider::GetDiscoveryPageHTML() { | 182 std::string BrowserListTabContentsProvider::GetDiscoveryPageHTML() { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 continue; | 220 continue; |
80 scoped_refptr<base::RefCountedMemory> data; | 221 scoped_refptr<base::RefCountedMemory> data; |
81 if (top_sites->GetPageThumbnail(url, false, &data)) | 222 if (top_sites->GetPageThumbnail(url, false, &data)) |
82 return std::string( | 223 return std::string( |
83 reinterpret_cast<const char*>(data->front()), data->size()); | 224 reinterpret_cast<const char*>(data->front()), data->size()); |
84 } | 225 } |
85 | 226 |
86 return std::string(); | 227 return std::string(); |
87 } | 228 } |
88 | 229 |
89 RenderViewHost* BrowserListTabContentsProvider::CreateNewTarget() { | 230 scoped_ptr<DevToolsTarget> |
| 231 BrowserListTabContentsProvider::CreateNewTarget() { |
90 const BrowserList* browser_list = | 232 const BrowserList* browser_list = |
91 BrowserList::GetInstance(host_desktop_type_); | 233 BrowserList::GetInstance(host_desktop_type_); |
92 | 234 WebContents* web_contents; |
93 if (browser_list->empty()) { | 235 if (browser_list->empty()) { |
94 chrome::NewEmptyWindow(ProfileManager::GetLastUsedProfile(), | 236 chrome::NewEmptyWindow(ProfileManager::GetLastUsedProfile(), |
95 host_desktop_type_); | 237 host_desktop_type_); |
96 return browser_list->empty() ? NULL : | 238 if (browser_list->empty()) |
97 browser_list->get(0)->tab_strip_model()->GetActiveWebContents()-> | 239 return scoped_ptr<DevToolsTarget>(); |
98 GetRenderViewHost(); | 240 web_contents = |
99 } | 241 browser_list->get(0)->tab_strip_model()->GetActiveWebContents(); |
100 | 242 } else { |
101 content::WebContents* web_contents = chrome::AddSelectedTabWithURL( | 243 web_contents = chrome::AddSelectedTabWithURL( |
102 browser_list->get(0), | 244 browser_list->get(0), |
103 GURL(content::kAboutBlankURL), | 245 GURL(content::kAboutBlankURL), |
104 content::PAGE_TRANSITION_LINK); | 246 content::PAGE_TRANSITION_LINK); |
105 return web_contents->GetRenderViewHost(); | 247 } |
| 248 return scoped_ptr<DevToolsTarget>(new Target(web_contents, true)); |
106 } | 249 } |
107 | 250 void BrowserListTabContentsProvider::EnumerateTargets(TargetCallback callback) { |
108 content::DevToolsHttpHandlerDelegate::TargetType | 251 content::BrowserThread::PostTaskAndReplyWithResult( |
109 BrowserListTabContentsProvider::GetTargetType(content::RenderViewHost* rvh) { | 252 content::BrowserThread::IO, |
110 for (TabContentsIterator it; !it.done(); it.Next()) | 253 FROM_HERE, |
111 if (rvh == it->GetRenderViewHost()) | 254 base::Bind(&BrowserListTabContentsProvider::GetWorkerInfo, |
112 return kTargetTypeTab; | 255 base::Unretained(this)), |
113 | 256 base::Bind(&BrowserListTabContentsProvider::RespondWithTargetList, |
114 return kTargetTypeOther; | 257 base::Unretained(this), |
115 } | 258 callback)); |
116 | |
117 std::string BrowserListTabContentsProvider::GetViewDescription( | |
118 content::RenderViewHost* rvh) { | |
119 content::WebContents* web_contents = | |
120 content::WebContents::FromRenderViewHost(rvh); | |
121 if (!web_contents) | |
122 return std::string(); | |
123 | |
124 Profile* profile = | |
125 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | |
126 if (!profile) | |
127 return std::string(); | |
128 | |
129 extensions::ExtensionHost* extension_host = | |
130 extensions::ExtensionSystem::Get(profile)->process_manager()-> | |
131 GetBackgroundHostForExtension(web_contents->GetURL().host()); | |
132 | |
133 if (!extension_host || extension_host->host_contents() != web_contents) | |
134 return std::string(); | |
135 | |
136 return extension_host->extension()->name(); | |
137 } | 259 } |
138 | 260 |
139 #if defined(DEBUG_DEVTOOLS) | 261 #if defined(DEBUG_DEVTOOLS) |
140 static int g_last_tethering_port_ = 9333; | 262 static int g_last_tethering_port_ = 9333; |
141 | 263 |
142 scoped_ptr<net::StreamListenSocket> | 264 scoped_ptr<net::StreamListenSocket> |
143 BrowserListTabContentsProvider::CreateSocketForTethering( | 265 BrowserListTabContentsProvider::CreateSocketForTethering( |
144 net::StreamListenSocket::Delegate* delegate, | 266 net::StreamListenSocket::Delegate* delegate, |
145 std::string* name) { | 267 std::string* name) { |
146 if (g_last_tethering_port_ == 9444) | 268 if (g_last_tethering_port_ == 9444) |
147 g_last_tethering_port_ = 9333; | 269 g_last_tethering_port_ = 9333; |
148 int port = ++g_last_tethering_port_; | 270 int port = ++g_last_tethering_port_; |
149 *name = base::IntToString(port); | 271 *name = base::IntToString(port); |
150 return net::TCPListenSocket::CreateAndListen("127.0.0.1", port, delegate) | 272 return net::TCPListenSocket::CreateAndListen("127.0.0.1", port, delegate) |
151 .PassAs<net::StreamListenSocket>(); | 273 .PassAs<net::StreamListenSocket>(); |
152 } | 274 } |
153 #else | 275 #else |
154 scoped_ptr<net::StreamListenSocket> | 276 scoped_ptr<net::StreamListenSocket> |
155 BrowserListTabContentsProvider::CreateSocketForTethering( | 277 BrowserListTabContentsProvider::CreateSocketForTethering( |
156 net::StreamListenSocket::Delegate* delegate, | 278 net::StreamListenSocket::Delegate* delegate, |
157 std::string* name) { | 279 std::string* name) { |
158 return scoped_ptr<net::StreamListenSocket>(); | 280 return scoped_ptr<net::StreamListenSocket>(); |
159 } | 281 } |
160 #endif // defined(DEBUG_DEVTOOLS) | 282 #endif // defined(DEBUG_DEVTOOLS) |
| 283 |
| 284 BrowserListTabContentsProvider::WorkerInfoList |
| 285 BrowserListTabContentsProvider::GetWorkerInfo() { |
| 286 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 287 return content::WorkerService::GetInstance()->GetWorkers(); |
| 288 } |
| 289 |
| 290 void BrowserListTabContentsProvider::RespondWithTargetList( |
| 291 TargetCallback callback, const WorkerInfoList& worker_info_list) { |
| 292 std::set<RenderViewHost*> tab_rvhs; |
| 293 for (TabContentsIterator it; !it.done(); it.Next()) |
| 294 tab_rvhs.insert(it->GetRenderViewHost()); |
| 295 |
| 296 TargetList targets; |
| 297 |
| 298 std::vector<RenderViewHost*> rvh_list = |
| 299 content::DevToolsAgentHost::GetValidRenderViewHosts(); |
| 300 for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin(); |
| 301 it != rvh_list.end(); ++it) { |
| 302 bool is_tab = tab_rvhs.find(*it) != tab_rvhs.end(); |
| 303 WebContents* web_contents = WebContents::FromRenderViewHost(*it); |
| 304 if (web_contents) |
| 305 targets.push_back(new Target(web_contents, is_tab)); |
| 306 } |
| 307 |
| 308 for (size_t i = 0; i < worker_info_list.size(); ++i) |
| 309 targets.push_back(new WorkerTarget(worker_info_list[i])); |
| 310 |
| 311 callback.Run(targets); |
| 312 } |
OLD | NEW |