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