OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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/android/dev_tools_manager_delegate_android.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/compiler_specific.h" | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "chrome/browser/android/tab_android.h" | |
12 #include "chrome/browser/browser_process.h" | |
13 #include "chrome/browser/history/top_sites.h" | |
14 #include "chrome/browser/profiles/profile_manager.h" | |
15 #include "chrome/browser/ui/android/tab_model/tab_model.h" | |
16 #include "chrome/browser/ui/android/tab_model/tab_model_list.h" | |
17 #include "content/public/browser/devtools_agent_host.h" | |
18 #include "content/public/browser/devtools_target.h" | |
19 #include "content/public/browser/favicon_status.h" | |
20 #include "content/public/browser/navigation_entry.h" | |
21 #include "content/public/browser/web_contents.h" | |
22 | |
23 using content::DevToolsAgentHost; | |
24 using content::WebContents; | |
25 | |
26 namespace { | |
27 | |
28 const char kTargetTypePage[] = "page"; | |
29 const char kTargetTypeServiceWorker[] = "service_worker"; | |
30 const char kTargetTypeOther[] = "other"; | |
31 | |
32 static GURL GetFaviconURLForContents(WebContents* web_contents) { | |
pfeldman
2014/09/18 11:45:58
No need to declare as static since in an anonymous
dgozman
2014/09/19 10:04:33
Done.
| |
33 content::NavigationController& controller = web_contents->GetController(); | |
34 content::NavigationEntry* entry = controller.GetActiveEntry(); | |
35 if (entry != NULL && entry->GetURL().is_valid()) | |
36 return entry->GetFavicon().url; | |
37 return GURL(); | |
38 } | |
39 | |
40 static GURL GetFaviconURLForAgentHost( | |
41 scoped_refptr<DevToolsAgentHost> agent_host) { | |
42 if (WebContents* web_contents = agent_host->GetWebContents()) | |
43 return GetFaviconURLForContents(web_contents); | |
44 return GURL(); | |
45 } | |
46 | |
47 static base::TimeTicks GetLastActiveTimeForAgentHost( | |
48 scoped_refptr<DevToolsAgentHost> agent_host) { | |
49 if (WebContents* web_contents = agent_host->GetWebContents()) | |
50 return web_contents->GetLastActiveTime(); | |
51 return base::TimeTicks(); | |
52 } | |
53 | |
54 class TargetBase : public content::DevToolsTarget { | |
55 public: | |
56 // content::DevToolsTarget implementation: | |
57 virtual std::string GetParentId() const OVERRIDE { return std::string(); } | |
58 | |
59 virtual std::string GetTitle() const OVERRIDE { return title_; } | |
60 | |
61 virtual std::string GetDescription() const OVERRIDE { return std::string(); } | |
62 | |
63 virtual GURL GetURL() const OVERRIDE { return url_; } | |
64 | |
65 virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; } | |
66 | |
67 virtual base::TimeTicks GetLastActivityTime() const OVERRIDE { | |
68 return last_activity_time_; | |
69 } | |
70 | |
71 protected: | |
72 explicit TargetBase(WebContents* web_contents) | |
73 : title_(base::UTF16ToUTF8(web_contents->GetTitle())), | |
74 url_(web_contents->GetURL()), | |
75 favicon_url_(GetFaviconURLForContents(web_contents)), | |
76 last_activity_time_(web_contents->GetLastActiveTime()) { | |
77 } | |
78 | |
79 explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host) | |
80 : title_(agent_host->GetTitle()), | |
81 url_(agent_host->GetURL()), | |
82 favicon_url_(GetFaviconURLForAgentHost(agent_host)), | |
83 last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) { | |
84 } | |
85 | |
86 TargetBase(const std::string& title, const GURL& url) | |
87 : title_(title), | |
88 url_(url) { | |
89 } | |
90 | |
91 private: | |
92 const std::string title_; | |
93 const GURL url_; | |
94 const GURL favicon_url_; | |
95 const base::TimeTicks last_activity_time_; | |
96 }; | |
97 | |
98 class TabTarget : public TargetBase { | |
99 public: | |
100 static TabTarget* CreateForWebContents(int tab_id, | |
101 WebContents* web_contents) { | |
102 return new TabTarget(tab_id, web_contents); | |
103 } | |
104 | |
105 static TabTarget* CreateForUnloadedTab(int tab_id, | |
106 const base::string16& title, | |
107 const GURL& url) { | |
108 return new TabTarget(tab_id, title, url); | |
109 } | |
110 | |
111 // content::DevToolsTarget implementation: | |
112 virtual std::string GetId() const OVERRIDE { | |
113 return base::IntToString(tab_id_); | |
114 } | |
115 | |
116 virtual std::string GetType() const OVERRIDE { | |
117 return kTargetTypePage; | |
118 } | |
119 | |
120 virtual bool IsAttached() const OVERRIDE { | |
121 TabModel* model; | |
122 int index; | |
123 if (!FindTab(&model, &index)) | |
124 return false; | |
125 WebContents* web_contents = model->GetWebContentsAt(index); | |
126 if (!web_contents) | |
127 return false; | |
128 return DevToolsAgentHost::IsDebuggerAttached(web_contents); | |
129 } | |
130 | |
131 virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { | |
132 TabModel* model; | |
133 int index; | |
134 if (!FindTab(&model, &index)) | |
135 return NULL; | |
136 WebContents* web_contents = model->GetWebContentsAt(index); | |
137 if (!web_contents) { | |
138 // The tab has been pushed out of memory, pull it back. | |
139 TabAndroid* tab = model->GetTabAt(index); | |
140 if (!tab) | |
141 return NULL; | |
142 | |
143 tab->LoadIfNeeded(); | |
144 web_contents = model->GetWebContentsAt(index); | |
145 if (!web_contents) | |
146 return NULL; | |
147 } | |
148 return DevToolsAgentHost::GetOrCreateFor(web_contents); | |
149 } | |
150 | |
151 virtual bool Activate() const OVERRIDE { | |
152 TabModel* model; | |
153 int index; | |
154 if (!FindTab(&model, &index)) | |
155 return false; | |
156 model->SetActiveIndex(index); | |
157 return true; | |
158 } | |
159 | |
160 virtual bool Close() const OVERRIDE { | |
161 TabModel* model; | |
162 int index; | |
163 if (!FindTab(&model, &index)) | |
164 return false; | |
165 model->CloseTabAt(index); | |
166 return true; | |
167 } | |
168 | |
169 private: | |
170 TabTarget(int tab_id, WebContents* web_contents) | |
171 : TargetBase(web_contents), | |
172 tab_id_(tab_id) { | |
173 } | |
174 | |
175 TabTarget(int tab_id, const base::string16& title, const GURL& url) | |
176 : TargetBase(base::UTF16ToUTF8(title), url), | |
177 tab_id_(tab_id) { | |
178 } | |
179 | |
180 bool FindTab(TabModel** model_result, int* index_result) const { | |
181 for (TabModelList::const_iterator iter = TabModelList::begin(); | |
182 iter != TabModelList::end(); ++iter) { | |
183 TabModel* model = *iter; | |
184 for (int i = 0; i < model->GetTabCount(); ++i) { | |
185 TabAndroid* tab = model->GetTabAt(i); | |
186 if (tab && tab->GetAndroidId() == tab_id_) { | |
187 *model_result = model; | |
188 *index_result = i; | |
189 return true; | |
190 } | |
191 } | |
192 } | |
193 return false; | |
194 } | |
195 | |
196 const int tab_id_; | |
197 }; | |
198 | |
199 class NonTabTarget : public TargetBase { | |
200 public: | |
201 explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host) | |
202 : TargetBase(agent_host), | |
203 agent_host_(agent_host) { | |
204 } | |
205 | |
206 // content::DevToolsTarget implementation: | |
207 virtual std::string GetId() const OVERRIDE { | |
208 return agent_host_->GetId(); | |
209 } | |
210 | |
211 virtual std::string GetType() const OVERRIDE { | |
212 switch (agent_host_->GetType()) { | |
213 case DevToolsAgentHost::TYPE_WEB_CONTENTS: | |
214 if (TabModelList::begin() == TabModelList::end()) { | |
215 // If there are no tab models we must be running in ChromeShell. | |
216 // Return the 'page' target type for backwards compatibility. | |
217 return kTargetTypePage; | |
218 } | |
219 break; | |
220 case DevToolsAgentHost::TYPE_SERVICE_WORKER: | |
221 return kTargetTypeServiceWorker; | |
222 default: | |
223 break; | |
224 } | |
225 return kTargetTypeOther; | |
226 } | |
227 | |
228 virtual bool IsAttached() const OVERRIDE { | |
229 return agent_host_->IsAttached(); | |
230 } | |
231 | |
232 virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE { | |
233 return agent_host_; | |
234 } | |
235 | |
236 virtual bool Activate() const OVERRIDE { | |
237 return agent_host_->Activate(); | |
238 } | |
239 | |
240 virtual bool Close() const OVERRIDE { | |
241 return agent_host_->Close(); | |
242 } | |
243 | |
244 private: | |
245 scoped_refptr<DevToolsAgentHost> agent_host_; | |
246 }; | |
247 | |
248 } // namespace | |
249 | |
250 DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid() | |
251 : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) { | |
252 } | |
253 | |
254 DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() { | |
255 } | |
256 | |
257 void DevToolsManagerDelegateAndroid::Inspect( | |
258 content::BrowserContext* browser_context, | |
259 content::DevToolsAgentHost* agent_host) { | |
260 } | |
261 | |
262 base::DictionaryValue* DevToolsManagerDelegateAndroid::HandleCommand( | |
263 content::DevToolsAgentHost* agent_host, | |
264 base::DictionaryValue* command_dict) { | |
265 return network_protocol_handler_->HandleCommand(agent_host, command_dict); | |
266 } | |
267 | |
268 void DevToolsManagerDelegateAndroid::DevToolsAgentStateChanged( | |
269 content::DevToolsAgentHost* agent_host, | |
270 bool attached) { | |
271 network_protocol_handler_->DevToolsAgentStateChanged(agent_host, attached); | |
272 } | |
273 | |
274 scoped_ptr<content::DevToolsTarget> | |
275 DevToolsManagerDelegateAndroid::CreateNewTarget(const GURL& url) { | |
276 if (TabModelList::empty()) | |
277 return scoped_ptr<content::DevToolsTarget>(); | |
278 TabModel* tab_model = TabModelList::get(0); | |
279 if (!tab_model) | |
280 return scoped_ptr<content::DevToolsTarget>(); | |
281 WebContents* web_contents = tab_model->CreateNewTabForDevTools(url); | |
282 if (!web_contents) | |
283 return scoped_ptr<content::DevToolsTarget>(); | |
284 | |
285 TabAndroid* tab = TabAndroid::FromWebContents(web_contents); | |
286 if (!tab) | |
287 return scoped_ptr<content::DevToolsTarget>(); | |
288 | |
289 return scoped_ptr<content::DevToolsTarget>( | |
290 TabTarget::CreateForWebContents(tab->GetAndroidId(), web_contents)); | |
291 } | |
292 | |
293 void DevToolsManagerDelegateAndroid::EnumerateTargets(TargetCallback callback) { | |
294 TargetList targets; | |
295 | |
296 // Enumerate existing tabs, including the ones with no WebContents. | |
297 std::set<WebContents*> tab_web_contents; | |
298 for (TabModelList::const_iterator iter = TabModelList::begin(); | |
299 iter != TabModelList::end(); ++iter) { | |
300 TabModel* model = *iter; | |
301 for (int i = 0; i < model->GetTabCount(); ++i) { | |
302 TabAndroid* tab = model->GetTabAt(i); | |
303 if (!tab) | |
304 continue; | |
305 | |
306 WebContents* web_contents = model->GetWebContentsAt(i); | |
307 if (web_contents) { | |
308 tab_web_contents.insert(web_contents); | |
309 targets.push_back(TabTarget::CreateForWebContents(tab->GetAndroidId(), | |
310 web_contents)); | |
311 } else { | |
312 targets.push_back(TabTarget::CreateForUnloadedTab(tab->GetAndroidId(), | |
313 tab->GetTitle(), | |
314 tab->GetURL())); | |
315 } | |
316 } | |
317 } | |
318 | |
319 // Add targets for WebContents not associated with any tabs. | |
320 DevToolsAgentHost::List agents = | |
321 DevToolsAgentHost::GetOrCreateAll(); | |
322 for (DevToolsAgentHost::List::iterator it = agents.begin(); | |
323 it != agents.end(); ++it) { | |
324 if (WebContents* web_contents = (*it)->GetWebContents()) { | |
325 if (tab_web_contents.find(web_contents) != tab_web_contents.end()) | |
326 continue; | |
327 } | |
328 targets.push_back(new NonTabTarget(*it)); | |
329 } | |
330 | |
331 callback.Run(targets); | |
332 } | |
333 | |
334 std::string DevToolsManagerDelegateAndroid::GetPageThumbnailData( | |
335 const GURL& url) { | |
336 Profile* profile = | |
337 ProfileManager::GetLastUsedProfile()->GetOriginalProfile(); | |
338 history::TopSites* top_sites = profile->GetTopSites(); | |
339 if (top_sites) { | |
340 scoped_refptr<base::RefCountedMemory> data; | |
341 if (top_sites->GetPageThumbnail(url, false, &data)) | |
342 return std::string(data->front_as<char>(), data->size()); | |
343 } | |
344 return ""; | |
345 } | |
OLD | NEW |