Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / task_management / providers / web_contents / renderer_task.cc
blobca30ac750dd15e99591707ebeb60063e23cd64a9
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/task_management/providers/web_contents/renderer_task.h"
7 #include "base/i18n/rtl.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/favicon/favicon_utils.h"
12 #include "chrome/browser/process_resource_usage.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_info_cache.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/task_management/task_manager_observer.h"
17 #include "chrome/grit/generated_resources.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_delegate.h"
21 #include "content/public/common/service_registry.h"
22 #include "ui/base/l10n/l10n_util.h"
24 namespace task_management {
26 namespace {
28 // Creates the Mojo service wrapper that will be used to sample the V8 memory
29 // usage and the the WebCache resource stats of the render process hosted by
30 // |render_process_host|.
31 ProcessResourceUsage* CreateRendererResourcesSampler(
32 content::RenderProcessHost* render_process_host) {
33 ResourceUsageReporterPtr service;
34 content::ServiceRegistry* service_registry =
35 render_process_host->GetServiceRegistry();
36 if (service_registry)
37 service_registry->ConnectToRemoteService(mojo::GetProxy(&service));
38 return new ProcessResourceUsage(service.Pass());
41 // Gets the profile name associated with the browser context of the given
42 // |render_process_host| from the profile info cache.
43 base::string16 GetRendererProfileName(
44 const content::RenderProcessHost* render_process_host) {
45 Profile* profile =
46 Profile::FromBrowserContext(render_process_host->GetBrowserContext());
47 DCHECK(profile);
48 ProfileInfoCache& cache =
49 g_browser_process->profile_manager()->GetProfileInfoCache();
50 size_t index =
51 cache.GetIndexOfProfileWithPath(profile->GetOriginalProfile()->GetPath());
52 if (index != std::string::npos)
53 return cache.GetNameOfProfileAtIndex(index);
55 return base::string16();
58 inline bool IsRendererResourceSamplingDisabled(int64 flags) {
59 return (flags & (REFRESH_TYPE_V8_MEMORY | REFRESH_TYPE_WEBCACHE_STATS)) == 0;
62 } // namespace
64 RendererTask::RendererTask(const base::string16& title,
65 const gfx::ImageSkia* icon,
66 content::WebContents* web_contents,
67 content::RenderProcessHost* render_process_host)
68 : Task(title, icon, render_process_host->GetHandle()),
69 web_contents_(web_contents),
70 render_process_host_(render_process_host),
71 renderer_resources_sampler_(
72 CreateRendererResourcesSampler(render_process_host_)),
73 render_process_id_(render_process_host_->GetID()),
74 v8_memory_allocated_(0),
75 v8_memory_used_(0),
76 webcache_stats_(),
77 profile_name_(GetRendererProfileName(render_process_host_)) {
78 // All renderer tasks are capable of reporting network usage, so the default
79 // invalid value of -1 doesn't apply here.
80 OnNetworkBytesRead(0);
82 // Tag the web_contents with a |ContentFaviconDriver| (if needed) so that
83 // we can use it to observe favicons changes.
84 favicon::CreateContentFaviconDriverForWebContents(web_contents);
85 favicon::ContentFaviconDriver::FromWebContents(web_contents)->AddObserver(
86 this);
89 RendererTask::~RendererTask() {
90 favicon::ContentFaviconDriver::FromWebContents(web_contents())->
91 RemoveObserver(this);
94 void RendererTask::Activate() {
95 if (!web_contents_->GetDelegate())
96 return;
98 web_contents_->GetDelegate()->ActivateContents(web_contents_);
101 void RendererTask::Refresh(const base::TimeDelta& update_interval,
102 int64 refresh_flags) {
103 Task::Refresh(update_interval, refresh_flags);
105 if (IsRendererResourceSamplingDisabled(refresh_flags))
106 return;
108 // The renderer resources refresh is performed asynchronously, we will invoke
109 // it and record the current values (which might be invalid at the moment. We
110 // can safely ignore that and count on future refresh cycles potentially
111 // having valid values).
112 renderer_resources_sampler_->Refresh(base::Closure());
114 v8_memory_allocated_ = base::saturated_cast<int64>(
115 renderer_resources_sampler_->GetV8MemoryAllocated());
116 v8_memory_used_ = base::saturated_cast<int64>(
117 renderer_resources_sampler_->GetV8MemoryUsed());
118 webcache_stats_ = renderer_resources_sampler_->GetWebCoreCacheStats();
121 Task::Type RendererTask::GetType() const {
122 return Task::RENDERER;
125 int RendererTask::GetChildProcessUniqueID() const {
126 return render_process_id_;
129 base::string16 RendererTask::GetProfileName() const {
130 return profile_name_;
133 int64 RendererTask::GetV8MemoryAllocated() const {
134 return v8_memory_allocated_;
137 int64 RendererTask::GetV8MemoryUsed() const {
138 return v8_memory_used_;
141 bool RendererTask::ReportsWebCacheStats() const {
142 return true;
145 blink::WebCache::ResourceTypeStats RendererTask::GetWebCacheStats() const {
146 return webcache_stats_;
149 void RendererTask::OnFaviconAvailable(const gfx::Image& image) {
152 void RendererTask::OnFaviconUpdated(favicon::FaviconDriver* favicon_driver,
153 bool icon_url_changed) {
154 UpdateFavicon();
157 // static
158 base::string16 RendererTask::GetTitleFromWebContents(
159 content::WebContents* web_contents) {
160 DCHECK(web_contents);
161 base::string16 title = web_contents->GetTitle();
162 if (title.empty()) {
163 GURL url = web_contents->GetURL();
164 title = base::UTF8ToUTF16(url.spec());
165 // Force URL to be LTR.
166 title = base::i18n::GetDisplayStringInLTRDirectionality(title);
167 } else {
168 // Since the title could later be concatenated with
169 // IDS_TASK_MANAGER_TAB_PREFIX (for example), we need to explicitly set the
170 // title to be LTR format if there is no strong RTL charater in it.
171 // Otherwise, if IDS_TASK_MANAGER_TAB_PREFIX is an RTL word, the
172 // concatenated result might be wrong. For example, http://mail.yahoo.com,
173 // whose title is "Yahoo! Mail: The best web-based Email!", without setting
174 // it explicitly as LTR format, the concatenated result will be "!Yahoo!
175 // Mail: The best web-based Email :BAT", in which the capital letters "BAT"
176 // stands for the Hebrew word for "tab".
177 base::i18n::AdjustStringForLocaleDirection(&title);
179 return title;
182 // static
183 const gfx::ImageSkia* RendererTask::GetFaviconFromWebContents(
184 content::WebContents* web_contents) {
185 DCHECK(web_contents);
187 // Tag the web_contents with a |ContentFaviconDriver| (if needed) so that
188 // we can use it to retrieve the favicon if there is one.
189 favicon::CreateContentFaviconDriverForWebContents(web_contents);
190 gfx::Image image =
191 favicon::ContentFaviconDriver::FromWebContents(web_contents)->
192 GetFavicon();
193 if (image.IsEmpty())
194 return nullptr;
196 return image.ToImageSkia();
199 // static
200 const base::string16 RendererTask::PrefixRendererTitle(
201 const base::string16& title,
202 bool is_app,
203 bool is_extension,
204 bool is_incognito,
205 bool is_background) {
206 int message_id = IDS_TASK_MANAGER_TAB_PREFIX;
208 if (is_incognito && !is_app && !is_extension) {
209 message_id = IDS_TASK_MANAGER_TAB_INCOGNITO_PREFIX;
210 } else if (is_app) {
211 if (is_background)
212 message_id = IDS_TASK_MANAGER_BACKGROUND_PREFIX;
213 else if (is_incognito)
214 message_id = IDS_TASK_MANAGER_APP_INCOGNITO_PREFIX;
215 else
216 message_id = IDS_TASK_MANAGER_APP_PREFIX;
217 } else if (is_extension) {
218 if (is_incognito)
219 message_id = IDS_TASK_MANAGER_EXTENSION_INCOGNITO_PREFIX;
220 else
221 message_id = IDS_TASK_MANAGER_EXTENSION_PREFIX;
224 return l10n_util::GetStringFUTF16(message_id, title);
227 } // namespace task_management