11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/android/dev_tools_manager_delegate_android.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/basictypes.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/compiler_specific.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_number_conversions.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/utf_string_conversions.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/android/tab_android.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/browser_process.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/history/top_sites.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/profiles/profile_manager.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/android/tab_model/tab_model.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/devtools_agent_host.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/devtools_target.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/favicon_status.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/navigation_entry.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/web_contents.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::DevToolsAgentHost;
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing content::WebContents;
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kTargetTypePage[] = "page";
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kTargetTypeServiceWorker[] = "service_worker";
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kTargetTypeOther[] = "other";
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGURL GetFaviconURLForContents(WebContents* web_contents) {
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::NavigationController& controller = web_contents->GetController();
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::NavigationEntry* entry = controller.GetActiveEntry();
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (entry != NULL && entry->GetURL().is_valid())
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return entry->GetFavicon().url;
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return GURL();
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciGURL GetFaviconURLForAgentHost(
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<DevToolsAgentHost> agent_host) {
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (WebContents* web_contents = agent_host->GetWebContents())
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return GetFaviconURLForContents(web_contents);
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return GURL();
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeTicks GetLastActiveTimeForAgentHost(
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<DevToolsAgentHost> agent_host) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (WebContents* web_contents = agent_host->GetWebContents())
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return web_contents->GetLastActiveTime();
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::TimeTicks();
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TargetBase : public content::DevToolsTarget {
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // content::DevToolsTarget implementation:
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetParentId() const OVERRIDE { return std::string(); }
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetTitle() const OVERRIDE { return title_; }
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetDescription() const OVERRIDE { return std::string(); }
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual GURL GetURL() const OVERRIDE { return url_; }
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return last_activity_time_;
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit TargetBase(WebContents* web_contents)
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : title_(base::UTF16ToUTF8(web_contents->GetTitle())),
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url_(web_contents->GetURL()),
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        favicon_url_(GetFaviconURLForContents(web_contents)),
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        last_activity_time_(web_contents->GetLastActiveTime()) {
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host)
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : title_(agent_host->GetTitle()),
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url_(agent_host->GetURL()),
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        favicon_url_(GetFaviconURLForAgentHost(agent_host)),
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TargetBase(const std::string& title, const GURL& url)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : title_(title),
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        url_(url) {
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const std::string title_;
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL url_;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const GURL favicon_url_;
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const base::TimeTicks last_activity_time_;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass TabTarget : public TargetBase {
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static TabTarget* CreateForWebContents(int tab_id,
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         WebContents* web_contents) {
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return new TabTarget(tab_id, web_contents);
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static TabTarget* CreateForUnloadedTab(int tab_id,
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         const base::string16& title,
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         const GURL& url) {
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return new TabTarget(tab_id, title, url);
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // content::DevToolsTarget implementation:
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetId() const OVERRIDE {
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return base::IntToString(tab_id_);
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetType() const OVERRIDE {
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return kTargetTypePage;
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool IsAttached() const OVERRIDE {
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TabModel* model;
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int index;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FindTab(&model, &index))
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebContents* web_contents = model->GetWebContentsAt(index);
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!web_contents)
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return DevToolsAgentHost::IsDebuggerAttached(web_contents);
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TabModel* model;
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int index;
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FindTab(&model, &index))
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return NULL;
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebContents* web_contents = model->GetWebContentsAt(index);
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!web_contents) {
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // The tab has been pushed out of memory, pull it back.
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TabAndroid* tab = model->GetTabAt(index);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!tab)
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return NULL;
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (!tab->LoadIfNeeded())
14434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)        return NULL;
14534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_contents = model->GetWebContentsAt(index);
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!web_contents)
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return NULL;
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return DevToolsAgentHost::GetOrCreateFor(web_contents);
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool Activate() const OVERRIDE {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TabModel* model;
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int index;
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FindTab(&model, &index))
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    model->SetActiveIndex(index);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool Close() const OVERRIDE {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TabModel* model;
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int index;
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FindTab(&model, &index))
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    model->CloseTabAt(index);
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TabTarget(int tab_id, WebContents* web_contents)
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : TargetBase(web_contents),
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tab_id_(tab_id) {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TabTarget(int tab_id, const base::string16& title, const GURL& url)
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : TargetBase(base::UTF16ToUTF8(title), url),
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tab_id_(tab_id) {
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool FindTab(TabModel** model_result, int* index_result) const {
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (TabModelList::const_iterator iter = TabModelList::begin();
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        iter != TabModelList::end(); ++iter) {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TabModel* model = *iter;
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (int i = 0; i < model->GetTabCount(); ++i) {
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TabAndroid* tab = model->GetTabAt(i);
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (tab && tab->GetAndroidId() == tab_id_) {
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          *model_result = model;
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          *index_result = i;
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          return true;
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const int tab_id_;
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass NonTabTarget : public TargetBase {
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host)
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : TargetBase(agent_host),
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        agent_host_(agent_host) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // content::DevToolsTarget implementation:
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetId() const OVERRIDE {
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return agent_host_->GetId();
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual std::string GetType() const OVERRIDE {
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    switch (agent_host_->GetType()) {
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      case DevToolsAgentHost::TYPE_WEB_CONTENTS:
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if (TabModelList::begin() == TabModelList::end()) {
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          // If there are no tab models we must be running in ChromeShell.
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          // Return the 'page' target type for backwards compatibility.
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          return kTargetTypePage;
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        }
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      case DevToolsAgentHost::TYPE_SERVICE_WORKER:
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return kTargetTypeServiceWorker;
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      default:
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return kTargetTypeOther;
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool IsAttached() const OVERRIDE {
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return agent_host_->IsAttached();
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return agent_host_;
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool Activate() const OVERRIDE {
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return agent_host_->Activate();
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual bool Close() const OVERRIDE {
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return agent_host_->Close();
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<DevToolsAgentHost> agent_host_;
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid()
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) {
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() {
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DevToolsManagerDelegateAndroid::Inspect(
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::BrowserContext* browser_context,
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::DevToolsAgentHost* agent_host) {
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::DictionaryValue* DevToolsManagerDelegateAndroid::HandleCommand(
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::DevToolsAgentHost* agent_host,
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::DictionaryValue* command_dict) {
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return network_protocol_handler_->HandleCommand(agent_host, command_dict);
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DevToolsManagerDelegateAndroid::DevToolsAgentStateChanged(
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::DevToolsAgentHost* agent_host,
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool attached) {
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  network_protocol_handler_->DevToolsAgentStateChanged(agent_host, attached);
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<content::DevToolsTarget>
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DevToolsManagerDelegateAndroid::CreateNewTarget(const GURL& url) {
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (TabModelList::empty())
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<content::DevToolsTarget>();
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TabModel* tab_model = TabModelList::get(0);
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!tab_model)
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<content::DevToolsTarget>();
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebContents* web_contents = tab_model->CreateNewTabForDevTools(url);
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!web_contents)
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<content::DevToolsTarget>();
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!tab)
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<content::DevToolsTarget>();
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return scoped_ptr<content::DevToolsTarget>(
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TabTarget::CreateForWebContents(tab->GetAndroidId(), web_contents));
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DevToolsManagerDelegateAndroid::EnumerateTargets(TargetCallback callback) {
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TargetList targets;
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Enumerate existing tabs, including the ones with no WebContents.
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::set<WebContents*> tab_web_contents;
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TabModelList::const_iterator iter = TabModelList::begin();
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      iter != TabModelList::end(); ++iter) {
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TabModel* model = *iter;
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (int i = 0; i < model->GetTabCount(); ++i) {
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TabAndroid* tab = model->GetTabAt(i);
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!tab)
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebContents* web_contents = model->GetWebContentsAt(i);
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (web_contents) {
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tab_web_contents.insert(web_contents);
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        targets.push_back(TabTarget::CreateForWebContents(tab->GetAndroidId(),
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          web_contents));
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else {
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        targets.push_back(TabTarget::CreateForUnloadedTab(tab->GetAndroidId(),
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          tab->GetTitle(),
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          tab->GetURL()));
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Add targets for WebContents not associated with any tabs.
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (DevToolsAgentHost::List::iterator it = agents.begin();
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != agents.end(); ++it) {
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (WebContents* web_contents = (*it)->GetWebContents()) {
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (tab_web_contents.find(web_contents) != tab_web_contents.end())
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    targets.push_back(new NonTabTarget(*it));
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callback.Run(targets);
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string DevToolsManagerDelegateAndroid::GetPageThumbnailData(
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& url) {
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Profile* profile = ProfileManager::GetLastUsedProfile()->GetOriginalProfile();
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  history::TopSites* top_sites = profile->GetTopSites();
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (top_sites) {
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<base::RefCountedMemory> data;
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (top_sites->GetPageThumbnail(url, false, &data))
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return std::string(data->front_as<char>(), data->size());
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return std::string();
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
348