Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / android / dev_tools_manager_delegate_android.cc
blobb7561ad6afeb2adb95a7ad0c7ea00b391c6a2252
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.
5 #include "chrome/browser/android/dev_tools_manager_delegate_android.h"
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_factory.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 "components/history/core/browser/top_sites.h"
18 #include "content/public/browser/devtools_agent_host.h"
19 #include "content/public/browser/devtools_target.h"
20 #include "content/public/browser/favicon_status.h"
21 #include "content/public/browser/navigation_entry.h"
22 #include "content/public/browser/web_contents.h"
24 using content::DevToolsAgentHost;
25 using content::WebContents;
27 namespace {
29 const char kTargetTypePage[] = "page";
30 const char kTargetTypeServiceWorker[] = "service_worker";
31 const char kTargetTypeOther[] = "other";
33 GURL GetFaviconURLForContents(WebContents* web_contents) {
34 content::NavigationController& controller = web_contents->GetController();
35 content::NavigationEntry* entry = controller.GetActiveEntry();
36 if (entry != NULL && entry->GetURL().is_valid())
37 return entry->GetFavicon().url;
38 return GURL();
41 GURL GetFaviconURLForAgentHost(
42 scoped_refptr<DevToolsAgentHost> agent_host) {
43 if (WebContents* web_contents = agent_host->GetWebContents())
44 return GetFaviconURLForContents(web_contents);
45 return GURL();
48 base::TimeTicks GetLastActiveTimeForAgentHost(
49 scoped_refptr<DevToolsAgentHost> agent_host) {
50 if (WebContents* web_contents = agent_host->GetWebContents())
51 return web_contents->GetLastActiveTime();
52 return base::TimeTicks();
55 class TargetBase : public content::DevToolsTarget {
56 public:
57 // content::DevToolsTarget implementation:
58 std::string GetParentId() const override { return std::string(); }
60 std::string GetTitle() const override { return title_; }
62 std::string GetDescription() const override { return std::string(); }
64 GURL GetURL() const override { return url_; }
66 GURL GetFaviconURL() const override { return favicon_url_; }
68 base::TimeTicks GetLastActivityTime() const override {
69 return last_activity_time_;
72 protected:
73 explicit TargetBase(WebContents* web_contents)
74 : title_(base::UTF16ToUTF8(web_contents->GetTitle())),
75 url_(web_contents->GetURL()),
76 favicon_url_(GetFaviconURLForContents(web_contents)),
77 last_activity_time_(web_contents->GetLastActiveTime()) {
80 explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host)
81 : title_(agent_host->GetTitle()),
82 url_(agent_host->GetURL()),
83 favicon_url_(GetFaviconURLForAgentHost(agent_host)),
84 last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) {
87 TargetBase(const std::string& title, const GURL& url)
88 : title_(title),
89 url_(url) {
92 private:
93 const std::string title_;
94 const GURL url_;
95 const GURL favicon_url_;
96 const base::TimeTicks last_activity_time_;
99 class TabTarget : public TargetBase {
100 public:
101 static TabTarget* CreateForWebContents(int tab_id,
102 WebContents* web_contents) {
103 return new TabTarget(tab_id, web_contents);
106 static TabTarget* CreateForUnloadedTab(int tab_id,
107 const base::string16& title,
108 const GURL& url) {
109 return new TabTarget(tab_id, title, url);
112 // content::DevToolsTarget implementation:
113 std::string GetId() const override { return base::IntToString(tab_id_); }
115 std::string GetType() const override { return kTargetTypePage; }
117 bool IsAttached() const override {
118 TabModel* model;
119 int index;
120 if (!FindTab(&model, &index))
121 return false;
122 WebContents* web_contents = model->GetWebContentsAt(index);
123 if (!web_contents)
124 return false;
125 return DevToolsAgentHost::IsDebuggerAttached(web_contents);
128 scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
129 TabModel* model;
130 int index;
131 if (!FindTab(&model, &index))
132 return NULL;
133 WebContents* web_contents = model->GetWebContentsAt(index);
134 if (!web_contents) {
135 // The tab has been pushed out of memory, pull it back.
136 TabAndroid* tab = model->GetTabAt(index);
137 if (!tab)
138 return NULL;
140 if (!tab->LoadIfNeeded())
141 return NULL;
143 web_contents = model->GetWebContentsAt(index);
144 if (!web_contents)
145 return NULL;
147 return DevToolsAgentHost::GetOrCreateFor(web_contents);
150 bool Activate() const override {
151 TabModel* model;
152 int index;
153 if (!FindTab(&model, &index))
154 return false;
155 model->SetActiveIndex(index);
156 return true;
159 bool Close() const override {
160 TabModel* model;
161 int index;
162 if (!FindTab(&model, &index))
163 return false;
164 model->CloseTabAt(index);
165 return true;
168 private:
169 TabTarget(int tab_id, WebContents* web_contents)
170 : TargetBase(web_contents),
171 tab_id_(tab_id) {
174 TabTarget(int tab_id, const base::string16& title, const GURL& url)
175 : TargetBase(base::UTF16ToUTF8(title), url),
176 tab_id_(tab_id) {
179 bool FindTab(TabModel** model_result, int* index_result) const {
180 for (TabModelList::const_iterator iter = TabModelList::begin();
181 iter != TabModelList::end(); ++iter) {
182 TabModel* model = *iter;
183 for (int i = 0; i < model->GetTabCount(); ++i) {
184 TabAndroid* tab = model->GetTabAt(i);
185 if (tab && tab->GetAndroidId() == tab_id_) {
186 *model_result = model;
187 *index_result = i;
188 return true;
192 return false;
195 const int tab_id_;
198 class NonTabTarget : public TargetBase {
199 public:
200 explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host)
201 : TargetBase(agent_host),
202 agent_host_(agent_host) {
205 // content::DevToolsTarget implementation:
206 std::string GetId() const override { return agent_host_->GetId(); }
208 std::string GetType() const override {
209 switch (agent_host_->GetType()) {
210 case DevToolsAgentHost::TYPE_WEB_CONTENTS:
211 if (TabModelList::begin() == TabModelList::end()) {
212 // If there are no tab models we must be running in ChromeShell.
213 // Return the 'page' target type for backwards compatibility.
214 return kTargetTypePage;
216 break;
217 case DevToolsAgentHost::TYPE_SERVICE_WORKER:
218 return kTargetTypeServiceWorker;
219 default:
220 break;
222 return kTargetTypeOther;
225 bool IsAttached() const override { return agent_host_->IsAttached(); }
227 scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
228 return agent_host_;
231 bool Activate() const override { return agent_host_->Activate(); }
233 bool Close() const override { return agent_host_->Close(); }
235 private:
236 scoped_refptr<DevToolsAgentHost> agent_host_;
239 } // namespace
241 DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid()
242 : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) {
245 DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() {
248 void DevToolsManagerDelegateAndroid::Inspect(
249 content::BrowserContext* browser_context,
250 content::DevToolsAgentHost* agent_host) {
253 base::DictionaryValue* DevToolsManagerDelegateAndroid::HandleCommand(
254 content::DevToolsAgentHost* agent_host,
255 base::DictionaryValue* command_dict) {
256 return network_protocol_handler_->HandleCommand(agent_host, command_dict);
259 void DevToolsManagerDelegateAndroid::DevToolsAgentStateChanged(
260 content::DevToolsAgentHost* agent_host,
261 bool attached) {
262 network_protocol_handler_->DevToolsAgentStateChanged(agent_host, attached);
265 scoped_ptr<content::DevToolsTarget>
266 DevToolsManagerDelegateAndroid::CreateNewTarget(const GURL& url) {
267 if (TabModelList::empty())
268 return scoped_ptr<content::DevToolsTarget>();
270 TabModel* tab_model = TabModelList::get(0);
271 if (!tab_model)
272 return scoped_ptr<content::DevToolsTarget>();
274 WebContents* web_contents = tab_model->CreateNewTabForDevTools(url);
275 if (!web_contents)
276 return scoped_ptr<content::DevToolsTarget>();
278 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
279 if (!tab)
280 return scoped_ptr<content::DevToolsTarget>();
282 return scoped_ptr<content::DevToolsTarget>(
283 TabTarget::CreateForWebContents(tab->GetAndroidId(), web_contents));
286 void DevToolsManagerDelegateAndroid::EnumerateTargets(TargetCallback callback) {
287 TargetList targets;
289 // Enumerate existing tabs, including the ones with no WebContents.
290 std::set<WebContents*> tab_web_contents;
291 for (TabModelList::const_iterator iter = TabModelList::begin();
292 iter != TabModelList::end(); ++iter) {
293 TabModel* model = *iter;
294 for (int i = 0; i < model->GetTabCount(); ++i) {
295 TabAndroid* tab = model->GetTabAt(i);
296 if (!tab)
297 continue;
299 WebContents* web_contents = model->GetWebContentsAt(i);
300 if (web_contents) {
301 tab_web_contents.insert(web_contents);
302 targets.push_back(TabTarget::CreateForWebContents(tab->GetAndroidId(),
303 web_contents));
304 } else {
305 targets.push_back(TabTarget::CreateForUnloadedTab(tab->GetAndroidId(),
306 tab->GetTitle(),
307 tab->GetURL()));
312 // Add targets for WebContents not associated with any tabs.
313 DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
314 for (DevToolsAgentHost::List::iterator it = agents.begin();
315 it != agents.end(); ++it) {
316 if (WebContents* web_contents = (*it)->GetWebContents()) {
317 if (tab_web_contents.find(web_contents) != tab_web_contents.end())
318 continue;
320 targets.push_back(new NonTabTarget(*it));
323 callback.Run(targets);
326 std::string DevToolsManagerDelegateAndroid::GetPageThumbnailData(
327 const GURL& url) {
328 Profile* profile = ProfileManager::GetLastUsedProfile()->GetOriginalProfile();
329 scoped_refptr<history::TopSites> top_sites =
330 TopSitesFactory::GetForProfile(profile);
331 if (top_sites) {
332 scoped_refptr<base::RefCountedMemory> data;
333 if (top_sites->GetPageThumbnail(url, false, &data))
334 return std::string(data->front_as<char>(), data->size());
336 return std::string();