| Index: chrome/browser/android/dev_tools_manager_delegate_android.cc
|
| diff --git a/chrome/browser/android/dev_tools_manager_delegate_android.cc b/chrome/browser/android/dev_tools_manager_delegate_android.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2754946b111ee5b9eabf1f5ecda21f9c47e7398f
|
| --- /dev/null
|
| +++ b/chrome/browser/android/dev_tools_manager_delegate_android.cc
|
| @@ -0,0 +1,345 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/android/dev_tools_manager_delegate_android.h"
|
| +
|
| +#include "base/basictypes.h"
|
| +#include "base/compiler_specific.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "chrome/browser/android/tab_android.h"
|
| +#include "chrome/browser/browser_process.h"
|
| +#include "chrome/browser/history/top_sites.h"
|
| +#include "chrome/browser/profiles/profile_manager.h"
|
| +#include "chrome/browser/ui/android/tab_model/tab_model.h"
|
| +#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
|
| +#include "content/public/browser/devtools_agent_host.h"
|
| +#include "content/public/browser/devtools_target.h"
|
| +#include "content/public/browser/favicon_status.h"
|
| +#include "content/public/browser/navigation_entry.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +
|
| +using content::DevToolsAgentHost;
|
| +using content::WebContents;
|
| +
|
| +namespace {
|
| +
|
| +const char kTargetTypePage[] = "page";
|
| +const char kTargetTypeServiceWorker[] = "service_worker";
|
| +const char kTargetTypeOther[] = "other";
|
| +
|
| +GURL GetFaviconURLForContents(WebContents* web_contents) {
|
| + content::NavigationController& controller = web_contents->GetController();
|
| + content::NavigationEntry* entry = controller.GetActiveEntry();
|
| + if (entry != NULL && entry->GetURL().is_valid())
|
| + return entry->GetFavicon().url;
|
| + return GURL();
|
| +}
|
| +
|
| +GURL GetFaviconURLForAgentHost(
|
| + scoped_refptr<DevToolsAgentHost> agent_host) {
|
| + if (WebContents* web_contents = agent_host->GetWebContents())
|
| + return GetFaviconURLForContents(web_contents);
|
| + return GURL();
|
| +}
|
| +
|
| +base::TimeTicks GetLastActiveTimeForAgentHost(
|
| + scoped_refptr<DevToolsAgentHost> agent_host) {
|
| + if (WebContents* web_contents = agent_host->GetWebContents())
|
| + return web_contents->GetLastActiveTime();
|
| + return base::TimeTicks();
|
| +}
|
| +
|
| +class TargetBase : public content::DevToolsTarget {
|
| + public:
|
| + // content::DevToolsTarget implementation:
|
| + virtual std::string GetParentId() const OVERRIDE { return std::string(); }
|
| +
|
| + virtual std::string GetTitle() const OVERRIDE { return title_; }
|
| +
|
| + virtual std::string GetDescription() const OVERRIDE { return std::string(); }
|
| +
|
| + virtual GURL GetURL() const OVERRIDE { return url_; }
|
| +
|
| + virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
|
| +
|
| + virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
|
| + return last_activity_time_;
|
| + }
|
| +
|
| + protected:
|
| + explicit TargetBase(WebContents* web_contents)
|
| + : title_(base::UTF16ToUTF8(web_contents->GetTitle())),
|
| + url_(web_contents->GetURL()),
|
| + favicon_url_(GetFaviconURLForContents(web_contents)),
|
| + last_activity_time_(web_contents->GetLastActiveTime()) {
|
| + }
|
| +
|
| + explicit TargetBase(scoped_refptr<DevToolsAgentHost> agent_host)
|
| + : title_(agent_host->GetTitle()),
|
| + url_(agent_host->GetURL()),
|
| + favicon_url_(GetFaviconURLForAgentHost(agent_host)),
|
| + last_activity_time_(GetLastActiveTimeForAgentHost(agent_host)) {
|
| + }
|
| +
|
| + TargetBase(const std::string& title, const GURL& url)
|
| + : title_(title),
|
| + url_(url) {
|
| + }
|
| +
|
| + private:
|
| + const std::string title_;
|
| + const GURL url_;
|
| + const GURL favicon_url_;
|
| + const base::TimeTicks last_activity_time_;
|
| +};
|
| +
|
| +class TabTarget : public TargetBase {
|
| + public:
|
| + static TabTarget* CreateForWebContents(int tab_id,
|
| + WebContents* web_contents) {
|
| + return new TabTarget(tab_id, web_contents);
|
| + }
|
| +
|
| + static TabTarget* CreateForUnloadedTab(int tab_id,
|
| + const base::string16& title,
|
| + const GURL& url) {
|
| + return new TabTarget(tab_id, title, url);
|
| + }
|
| +
|
| + // content::DevToolsTarget implementation:
|
| + virtual std::string GetId() const OVERRIDE {
|
| + return base::IntToString(tab_id_);
|
| + }
|
| +
|
| + virtual std::string GetType() const OVERRIDE {
|
| + return kTargetTypePage;
|
| + }
|
| +
|
| + virtual bool IsAttached() const OVERRIDE {
|
| + TabModel* model;
|
| + int index;
|
| + if (!FindTab(&model, &index))
|
| + return false;
|
| + WebContents* web_contents = model->GetWebContentsAt(index);
|
| + if (!web_contents)
|
| + return false;
|
| + return DevToolsAgentHost::IsDebuggerAttached(web_contents);
|
| + }
|
| +
|
| + virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
|
| + TabModel* model;
|
| + int index;
|
| + if (!FindTab(&model, &index))
|
| + return NULL;
|
| + WebContents* web_contents = model->GetWebContentsAt(index);
|
| + if (!web_contents) {
|
| + // The tab has been pushed out of memory, pull it back.
|
| + TabAndroid* tab = model->GetTabAt(index);
|
| + if (!tab)
|
| + return NULL;
|
| +
|
| + tab->LoadIfNeeded();
|
| + web_contents = model->GetWebContentsAt(index);
|
| + if (!web_contents)
|
| + return NULL;
|
| + }
|
| + return DevToolsAgentHost::GetOrCreateFor(web_contents);
|
| + }
|
| +
|
| + virtual bool Activate() const OVERRIDE {
|
| + TabModel* model;
|
| + int index;
|
| + if (!FindTab(&model, &index))
|
| + return false;
|
| + model->SetActiveIndex(index);
|
| + return true;
|
| + }
|
| +
|
| + virtual bool Close() const OVERRIDE {
|
| + TabModel* model;
|
| + int index;
|
| + if (!FindTab(&model, &index))
|
| + return false;
|
| + model->CloseTabAt(index);
|
| + return true;
|
| + }
|
| +
|
| + private:
|
| + TabTarget(int tab_id, WebContents* web_contents)
|
| + : TargetBase(web_contents),
|
| + tab_id_(tab_id) {
|
| + }
|
| +
|
| + TabTarget(int tab_id, const base::string16& title, const GURL& url)
|
| + : TargetBase(base::UTF16ToUTF8(title), url),
|
| + tab_id_(tab_id) {
|
| + }
|
| +
|
| + bool FindTab(TabModel** model_result, int* index_result) const {
|
| + for (TabModelList::const_iterator iter = TabModelList::begin();
|
| + iter != TabModelList::end(); ++iter) {
|
| + TabModel* model = *iter;
|
| + for (int i = 0; i < model->GetTabCount(); ++i) {
|
| + TabAndroid* tab = model->GetTabAt(i);
|
| + if (tab && tab->GetAndroidId() == tab_id_) {
|
| + *model_result = model;
|
| + *index_result = i;
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + const int tab_id_;
|
| +};
|
| +
|
| +class NonTabTarget : public TargetBase {
|
| + public:
|
| + explicit NonTabTarget(scoped_refptr<DevToolsAgentHost> agent_host)
|
| + : TargetBase(agent_host),
|
| + agent_host_(agent_host) {
|
| + }
|
| +
|
| + // content::DevToolsTarget implementation:
|
| + virtual std::string GetId() const OVERRIDE {
|
| + return agent_host_->GetId();
|
| + }
|
| +
|
| + virtual std::string GetType() const OVERRIDE {
|
| + switch (agent_host_->GetType()) {
|
| + case DevToolsAgentHost::TYPE_WEB_CONTENTS:
|
| + if (TabModelList::begin() == TabModelList::end()) {
|
| + // If there are no tab models we must be running in ChromeShell.
|
| + // Return the 'page' target type for backwards compatibility.
|
| + return kTargetTypePage;
|
| + }
|
| + break;
|
| + case DevToolsAgentHost::TYPE_SERVICE_WORKER:
|
| + return kTargetTypeServiceWorker;
|
| + default:
|
| + break;
|
| + }
|
| + return kTargetTypeOther;
|
| + }
|
| +
|
| + virtual bool IsAttached() const OVERRIDE {
|
| + return agent_host_->IsAttached();
|
| + }
|
| +
|
| + virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
|
| + return agent_host_;
|
| + }
|
| +
|
| + virtual bool Activate() const OVERRIDE {
|
| + return agent_host_->Activate();
|
| + }
|
| +
|
| + virtual bool Close() const OVERRIDE {
|
| + return agent_host_->Close();
|
| + }
|
| +
|
| + private:
|
| + scoped_refptr<DevToolsAgentHost> agent_host_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +DevToolsManagerDelegateAndroid::DevToolsManagerDelegateAndroid()
|
| + : network_protocol_handler_(new DevToolsNetworkProtocolHandler()) {
|
| +}
|
| +
|
| +DevToolsManagerDelegateAndroid::~DevToolsManagerDelegateAndroid() {
|
| +}
|
| +
|
| +void DevToolsManagerDelegateAndroid::Inspect(
|
| + content::BrowserContext* browser_context,
|
| + content::DevToolsAgentHost* agent_host) {
|
| +}
|
| +
|
| +base::DictionaryValue* DevToolsManagerDelegateAndroid::HandleCommand(
|
| + content::DevToolsAgentHost* agent_host,
|
| + base::DictionaryValue* command_dict) {
|
| + return network_protocol_handler_->HandleCommand(agent_host, command_dict);
|
| +}
|
| +
|
| +void DevToolsManagerDelegateAndroid::DevToolsAgentStateChanged(
|
| + content::DevToolsAgentHost* agent_host,
|
| + bool attached) {
|
| + network_protocol_handler_->DevToolsAgentStateChanged(agent_host, attached);
|
| +}
|
| +
|
| +scoped_ptr<content::DevToolsTarget>
|
| + DevToolsManagerDelegateAndroid::CreateNewTarget(const GURL& url) {
|
| + if (TabModelList::empty())
|
| + return scoped_ptr<content::DevToolsTarget>();
|
| +
|
| + TabModel* tab_model = TabModelList::get(0);
|
| + if (!tab_model)
|
| + return scoped_ptr<content::DevToolsTarget>();
|
| +
|
| + WebContents* web_contents = tab_model->CreateNewTabForDevTools(url);
|
| + if (!web_contents)
|
| + return scoped_ptr<content::DevToolsTarget>();
|
| +
|
| + TabAndroid* tab = TabAndroid::FromWebContents(web_contents);
|
| + if (!tab)
|
| + return scoped_ptr<content::DevToolsTarget>();
|
| +
|
| + return scoped_ptr<content::DevToolsTarget>(
|
| + TabTarget::CreateForWebContents(tab->GetAndroidId(), web_contents));
|
| +}
|
| +
|
| +void DevToolsManagerDelegateAndroid::EnumerateTargets(TargetCallback callback) {
|
| + TargetList targets;
|
| +
|
| + // Enumerate existing tabs, including the ones with no WebContents.
|
| + std::set<WebContents*> tab_web_contents;
|
| + for (TabModelList::const_iterator iter = TabModelList::begin();
|
| + iter != TabModelList::end(); ++iter) {
|
| + TabModel* model = *iter;
|
| + for (int i = 0; i < model->GetTabCount(); ++i) {
|
| + TabAndroid* tab = model->GetTabAt(i);
|
| + if (!tab)
|
| + continue;
|
| +
|
| + WebContents* web_contents = model->GetWebContentsAt(i);
|
| + if (web_contents) {
|
| + tab_web_contents.insert(web_contents);
|
| + targets.push_back(TabTarget::CreateForWebContents(tab->GetAndroidId(),
|
| + web_contents));
|
| + } else {
|
| + targets.push_back(TabTarget::CreateForUnloadedTab(tab->GetAndroidId(),
|
| + tab->GetTitle(),
|
| + tab->GetURL()));
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Add targets for WebContents not associated with any tabs.
|
| + DevToolsAgentHost::List agents = DevToolsAgentHost::GetOrCreateAll();
|
| + for (DevToolsAgentHost::List::iterator it = agents.begin();
|
| + it != agents.end(); ++it) {
|
| + if (WebContents* web_contents = (*it)->GetWebContents()) {
|
| + if (tab_web_contents.find(web_contents) != tab_web_contents.end())
|
| + continue;
|
| + }
|
| + targets.push_back(new NonTabTarget(*it));
|
| + }
|
| +
|
| + callback.Run(targets);
|
| +}
|
| +
|
| +std::string DevToolsManagerDelegateAndroid::GetPageThumbnailData(
|
| + const GURL& url) {
|
| + Profile* profile = ProfileManager::GetLastUsedProfile()->GetOriginalProfile();
|
| + history::TopSites* top_sites = profile->GetTopSites();
|
| + if (top_sites) {
|
| + scoped_refptr<base::RefCountedMemory> data;
|
| + if (top_sites->GetPageThumbnail(url, false, &data))
|
| + return std::string(data->front_as<char>(), data->size());
|
| + }
|
| + return std::string();
|
| +}
|
|
|