1e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// found in the LICENSE file. 4e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 5e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/tab_contents_information.h" 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 7e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/callback.h" 8e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/strings/utf_string_conversions.h" 9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/browser_process.h" 10e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/devtools/devtools_window.h" 11e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/favicon/favicon_tab_helper.h" 12e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/prerender/prerender_manager.h" 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/prerender/prerender_manager_factory.h" 14e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/profiles/profile.h" 15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/profiles/profile_manager.h" 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/renderer_resource.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/task_manager/task_manager_util.h" 18e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/browser.h" 19e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/browser_finder.h" 20e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/browser_iterator.h" 21e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h" 22e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/public/browser/render_process_host.h" 23e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/public/browser/web_contents.h" 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/browser/extension_registry.h" 25e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "extensions/browser/process_map.h" 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "extensions/common/constants.h" 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/extension_set.h" 28e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "grit/generated_resources.h" 29e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "grit/theme_resources.h" 30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/base/l10n/l10n_util.h" 31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/base/resource/resource_bundle.h" 32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "ui/gfx/image/image_skia.h" 33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 34e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochusing content::WebContents; 35e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 36e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace task_manager { 37e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochnamespace { 39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Returns true if the WebContents is currently owned by the prerendering 41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// manager. 42e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool IsContentsPrerendering(WebContents* web_contents) { 43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Profile* profile = 44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Profile::FromBrowserContext(web_contents->GetBrowserContext()); 45e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender::PrerenderManager* prerender_manager = 46e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender::PrerenderManagerFactory::GetForProfile(profile); 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return prerender_manager && 48e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender_manager->IsWebContentsPrerendering(web_contents, NULL); 49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 53e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// Tracks a single tab contents, prerendered page, or Instant page. 54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass TabContentsResource : public RendererResource { 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch explicit TabContentsResource(content::WebContents* web_contents); 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual ~TabContentsResource(); 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Resource methods: 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual Type GetType() const OVERRIDE; 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual base::string16 GetTitle() const OVERRIDE; 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual gfx::ImageSkia GetIcon() const OVERRIDE; 63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual content::WebContents* GetWebContents() const OVERRIDE; 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private: 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Returns true if contains content rendered by an extension. 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool HostsExtension() const; 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static gfx::ImageSkia* prerender_icon_; 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content::WebContents* web_contents_; 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Profile* profile_; 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DISALLOW_COPY_AND_ASSIGN(TabContentsResource); 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}; 75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochgfx::ImageSkia* TabContentsResource::prerender_icon_ = NULL; 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTabContentsResource::TabContentsResource(WebContents* web_contents) 79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : RendererResource(web_contents->GetRenderProcessHost()->GetHandle(), 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch web_contents->GetRenderViewHost()), 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch web_contents_(web_contents), 82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch profile_(Profile::FromBrowserContext(web_contents->GetBrowserContext())) { 83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!prerender_icon_) { 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender_icon_ = rb.GetImageSkiaNamed(IDR_PRERENDER); 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTabContentsResource::~TabContentsResource() {} 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool TabContentsResource::HostsExtension() const { 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return web_contents_->GetURL().SchemeIs(extensions::kExtensionScheme); 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochResource::Type TabContentsResource::GetType() const { 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // A tab that loads an extension URL is considered to be an extension for 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // these purposes, although it's tracked as a TabContentsResource. 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return HostsExtension() ? EXTENSION : RENDERER; 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbase::string16 TabContentsResource::GetTitle() const { 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Fall back on the URL if there's no title. 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GURL url = web_contents_->GetURL(); 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::string16 tab_title = util::GetTitleFromWebContents(web_contents_); 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Only classify as an app if the URL is an app and the tab is hosting an 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // extension process. (It's possible to be showing the URL from before it 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // was installed as an app.) 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extensions::ProcessMap* process_map = extensions::ProcessMap::Get(profile_); 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bool is_app = 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionRegistry::Get(profile_) 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->enabled_extensions().GetAppByURL(url) != NULL && 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch process_map->Contains(web_contents_->GetRenderProcessHost()->GetID()); 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch int message_id = util::GetMessagePrefixID( 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_app, 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch HostsExtension(), 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch profile_->IsOffTheRecord(), 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IsContentsPrerendering(web_contents_), 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch false); // is_background 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return l10n_util::GetStringFUTF16(message_id, tab_title); 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochgfx::ImageSkia TabContentsResource::GetIcon() const { 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (IsContentsPrerendering(web_contents_)) 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return *prerender_icon_; 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch FaviconTabHelper::CreateForWebContents(web_contents_); 128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return FaviconTabHelper::FromWebContents(web_contents_)-> 129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch GetFavicon().AsImageSkia(); 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochWebContents* TabContentsResource::GetWebContents() const { 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return web_contents_; 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTabContentsInformation::TabContentsInformation() {} 137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTabContentsInformation::~TabContentsInformation() {} 139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 140e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool TabContentsInformation::CheckOwnership( 141e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content::WebContents* web_contents) { 142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return chrome::FindBrowserWithWebContents(web_contents) || 143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DevToolsWindow::IsDevToolsWindow(web_contents->GetRenderViewHost()) || 144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IsContentsPrerendering(web_contents); 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid TabContentsInformation::GetAll(const NewWebContentsCallback& callback) { 148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (TabContentsIterator iterator; !iterator.done(); iterator.Next()) { 149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callback.Run(*iterator); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) WebContents* devtools = 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DevToolsWindow::GetInTabWebContents(*iterator, NULL); 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (devtools) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) callback.Run(devtools); 154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Because a WebContents* may start its life as a prerender, and later be 157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // put into a tab, this class tracks the prerender contents in the same 158e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // way as the tab contents. 159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::vector<Profile*> profiles( 160e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch g_browser_process->profile_manager()->GetLoadedProfiles()); 161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (size_t i = 0; i < profiles.size(); ++i) { 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender::PrerenderManager* prerender_manager = 163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender::PrerenderManagerFactory::GetForProfile(profiles[i]); 164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (prerender_manager) { 165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const std::vector<content::WebContents*> contentses = 166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch prerender_manager->GetAllPrerenderingContents(); 167e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (size_t j = 0; j < contentses.size(); ++j) 168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch callback.Run(contentses[j]); 169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 173e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochscoped_ptr<RendererResource> TabContentsInformation::MakeResource( 174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content::WebContents* web_contents) { 175e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return scoped_ptr<RendererResource>(new TabContentsResource(web_contents)); 176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace task_manager 179