Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / android / dev_tools_discovery_provider_android.cc
blobaea64f638149379b852504353c2ca554233a81de
1 // Copyright 2015 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_discovery_provider_android.h"
7 #include "base/basictypes.h"
8 #include "base/bind.h"
9 #include "base/compiler_specific.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/android/tab_android.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/ui/android/tab_model/tab_model.h"
15 #include "chrome/browser/ui/android/tab_model/tab_model_list.h"
16 #include "components/devtools_discovery/basic_target_descriptor.h"
17 #include "components/devtools_discovery/devtools_discovery_manager.h"
18 #include "content/public/browser/devtools_agent_host.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"
23 using content::DevToolsAgentHost;
24 using content::WebContents;
26 namespace {
28 GURL GetFaviconURLForContents(WebContents* web_contents) {
29 content::NavigationController& controller = web_contents->GetController();
30 content::NavigationEntry* entry = controller.GetActiveEntry();
31 if (entry != NULL && entry->GetURL().is_valid())
32 return entry->GetFavicon().url;
33 return GURL();
36 class TabDescriptor : public devtools_discovery::DevToolsTargetDescriptor {
37 public:
38 static TabDescriptor* CreateForWebContents(int tab_id,
39 WebContents* web_contents) {
40 return new TabDescriptor(tab_id, web_contents);
43 static TabDescriptor* CreateForUnloadedTab(int tab_id,
44 const base::string16& title,
45 const GURL& url) {
46 return new TabDescriptor(tab_id, title, url);
49 ~TabDescriptor() override {
52 // devtools_discovery::DevToolsTargetDescriptor implementation.
53 std::string GetParentId() const override {
54 return std::string();
57 std::string GetTitle() const override {
58 return title_;
61 std::string GetDescription() const override {
62 return std::string();
65 GURL GetURL() const override {
66 return url_;
69 GURL GetFaviconURL() const override {
70 return favicon_url_;
73 base::TimeTicks GetLastActivityTime() const override {
74 return last_activity_time_;
77 std::string GetId() const override {
78 return base::IntToString(tab_id_);
81 std::string GetType() const override {
82 return devtools_discovery::BasicTargetDescriptor::kTypePage;
85 bool IsAttached() const override {
86 TabModel* model;
87 int index;
88 if (!FindTab(&model, &index))
89 return false;
90 WebContents* web_contents = model->GetWebContentsAt(index);
91 if (!web_contents)
92 return false;
93 return DevToolsAgentHost::IsDebuggerAttached(web_contents);
96 scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
97 TabModel* model;
98 int index;
99 if (!FindTab(&model, &index))
100 return NULL;
101 WebContents* web_contents = model->GetWebContentsAt(index);
102 if (!web_contents) {
103 // The tab has been pushed out of memory, pull it back.
104 TabAndroid* tab = model->GetTabAt(index);
105 if (!tab)
106 return NULL;
108 if (!tab->LoadIfNeeded())
109 return NULL;
111 web_contents = model->GetWebContentsAt(index);
112 if (!web_contents)
113 return NULL;
115 return DevToolsAgentHost::GetOrCreateFor(web_contents);
118 bool Activate() const override {
119 TabModel* model;
120 int index;
121 if (!FindTab(&model, &index))
122 return false;
123 model->SetActiveIndex(index);
124 return true;
127 bool Close() const override {
128 TabModel* model;
129 int index;
130 if (!FindTab(&model, &index))
131 return false;
132 model->CloseTabAt(index);
133 return true;
136 private:
137 TabDescriptor(int tab_id, WebContents* web_contents)
138 : tab_id_(tab_id),
139 title_(base::UTF16ToUTF8(web_contents->GetTitle())),
140 url_(web_contents->GetURL()),
141 favicon_url_(GetFaviconURLForContents(web_contents)),
142 last_activity_time_(web_contents->GetLastActiveTime()) {
145 TabDescriptor(int tab_id, const base::string16& title, const GURL& url)
146 : tab_id_(tab_id),
147 title_(base::UTF16ToUTF8(title)),
148 url_(url) {
151 bool FindTab(TabModel** model_result, int* index_result) const {
152 for (TabModelList::const_iterator iter = TabModelList::begin();
153 iter != TabModelList::end(); ++iter) {
154 TabModel* model = *iter;
155 for (int i = 0; i < model->GetTabCount(); ++i) {
156 TabAndroid* tab = model->GetTabAt(i);
157 if (tab && tab->GetAndroidId() == tab_id_) {
158 *model_result = model;
159 *index_result = i;
160 return true;
164 return false;
167 const int tab_id_;
168 const std::string title_;
169 const GURL url_;
170 const GURL favicon_url_;
171 const base::TimeTicks last_activity_time_;
173 DISALLOW_COPY_AND_ASSIGN(TabDescriptor);
176 scoped_ptr<devtools_discovery::DevToolsTargetDescriptor>
177 CreateNewAndroidTab(const GURL& url) {
178 if (TabModelList::empty())
179 return scoped_ptr<devtools_discovery::DevToolsTargetDescriptor>();
181 TabModel* tab_model = TabModelList::get(0);
182 if (!tab_model)
183 return scoped_ptr<devtools_discovery::DevToolsTargetDescriptor>();
185 WebContents* web_contents = tab_model->CreateNewTabForDevTools(url);
186 if (!web_contents)
187 return scoped_ptr<devtools_discovery::DevToolsTargetDescriptor>();
189 TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
190 if (!tab)
191 return scoped_ptr<devtools_discovery::DevToolsTargetDescriptor>();
193 return make_scoped_ptr(TabDescriptor::CreateForWebContents(
194 tab->GetAndroidId(), web_contents));
197 } // namespace
199 DevToolsDiscoveryProviderAndroid::DevToolsDiscoveryProviderAndroid() {
202 DevToolsDiscoveryProviderAndroid::~DevToolsDiscoveryProviderAndroid() {
205 devtools_discovery::DevToolsTargetDescriptor::List
206 DevToolsDiscoveryProviderAndroid::GetDescriptors() {
207 devtools_discovery::DevToolsTargetDescriptor::List result;
209 // Enumerate existing tabs, including the ones with no WebContents.
210 std::set<WebContents*> tab_web_contents;
211 for (TabModelList::const_iterator iter = TabModelList::begin();
212 iter != TabModelList::end(); ++iter) {
213 TabModel* model = *iter;
214 for (int i = 0; i < model->GetTabCount(); ++i) {
215 TabAndroid* tab = model->GetTabAt(i);
216 if (!tab)
217 continue;
219 WebContents* web_contents = tab->web_contents();
220 if (web_contents) {
221 tab_web_contents.insert(web_contents);
222 result.push_back(TabDescriptor::CreateForWebContents(
223 tab->GetAndroidId(), web_contents));
224 } else {
225 result.push_back(TabDescriptor::CreateForUnloadedTab(
226 tab->GetAndroidId(), tab->GetTitle(), tab->GetURL()));
231 // Add descriptors for targets not associated with any tabs.
232 DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
233 for (DevToolsAgentHost::List::iterator it = agents.begin();
234 it != agents.end(); ++it) {
235 if (WebContents* web_contents = (*it)->GetWebContents()) {
236 if (tab_web_contents.find(web_contents) != tab_web_contents.end())
237 continue;
239 result.push_back(new devtools_discovery::BasicTargetDescriptor(*it));
242 return result;
245 // static
246 void DevToolsDiscoveryProviderAndroid::Install() {
247 devtools_discovery::DevToolsDiscoveryManager* discovery_manager =
248 devtools_discovery::DevToolsDiscoveryManager::GetInstance();
249 discovery_manager->AddProvider(
250 make_scoped_ptr(new DevToolsDiscoveryProviderAndroid()));
251 discovery_manager->SetCreateCallback(base::Bind(&CreateNewAndroidTab));