OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
6 | 6 |
7 #include "chrome/browser/dom_ui/new_tab_ui.h" | 7 #include "chrome/browser/dom_ui/new_tab_ui.h" |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "grit/theme_resources.h" | 48 #include "grit/theme_resources.h" |
49 | 49 |
50 namespace { | 50 namespace { |
51 | 51 |
52 // The number of recent bookmarks we show. | 52 // The number of recent bookmarks we show. |
53 const int kRecentBookmarks = 9; | 53 const int kRecentBookmarks = 9; |
54 | 54 |
55 // The number of search URLs to show. | 55 // The number of search URLs to show. |
56 const int kSearchURLs = 3; | 56 const int kSearchURLs = 3; |
57 | 57 |
| 58 // The amount of time there must be no painting for us to consider painting |
| 59 // finished. Observed times are in the ~1200ms range on Windows. |
| 60 const int kTimeoutMs = 2000; |
| 61 |
58 // Strings sent to the page via jstemplates used to set the direction of the | 62 // Strings sent to the page via jstemplates used to set the direction of the |
59 // HTML document based on locale. | 63 // HTML document based on locale. |
60 const char kRTLHtmlTextDirection[] = "rtl"; | 64 const char kRTLHtmlTextDirection[] = "rtl"; |
61 const char kDefaultHtmlTextDirection[] = "ltr"; | 65 const char kDefaultHtmlTextDirection[] = "ltr"; |
62 | 66 |
63 //////////////////////////////////////////////////////////////////////////////// | |
64 // PaintTimer | |
65 | |
66 // To measure end-to-end performance of the new tab page, we observe paint | |
67 // messages and wait for the page to stop repainting. | |
68 class PaintTimer : public RenderWidgetHost::PaintObserver { | |
69 public: | |
70 PaintTimer() { | |
71 Start(); | |
72 } | |
73 | |
74 // Start the benchmarking and the timer. | |
75 void Start() { | |
76 start_ = base::TimeTicks::Now(); | |
77 last_paint_ = start_; | |
78 | |
79 timer_.Start(base::TimeDelta::FromMilliseconds(kTimeoutMs), this, | |
80 &PaintTimer::Timeout); | |
81 } | |
82 | |
83 // A callback that is invoked whenever our RenderWidgetHost paints. | |
84 virtual void RenderWidgetHostWillPaint(RenderWidgetHost* rhw) {} | |
85 | |
86 virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh) { | |
87 last_paint_ = base::TimeTicks::Now(); | |
88 } | |
89 | |
90 // The timer callback. If enough time has elapsed since the last paint | |
91 // message, we say we're done painting; otherwise, we keep waiting. | |
92 void Timeout() { | |
93 base::TimeTicks now = base::TimeTicks::Now(); | |
94 if ((now - last_paint_) >= base::TimeDelta::FromMilliseconds(kTimeoutMs)) { | |
95 // Painting has quieted down. Log this as the full time to run. | |
96 base::TimeDelta load_time = last_paint_ - start_; | |
97 int load_time_ms = static_cast<int>(load_time.InMilliseconds()); | |
98 NotificationService::current()->Notify( | |
99 NotificationType::INITIAL_NEW_TAB_UI_LOAD, | |
100 NotificationService::AllSources(), | |
101 Details<int>(&load_time_ms)); | |
102 UMA_HISTOGRAM_TIMES("NewTabUI load", load_time); | |
103 } else { | |
104 // Not enough quiet time has elapsed. | |
105 // Some more paints must've occurred since we set the timeout. | |
106 // Wait some more. | |
107 timer_.Start(base::TimeDelta::FromMilliseconds(kTimeoutMs), this, | |
108 &PaintTimer::Timeout); | |
109 } | |
110 } | |
111 | |
112 private: | |
113 // The amount of time there must be no painting for us to consider painting | |
114 // finished. Observed times are in the ~1200ms range on Windows. | |
115 static const int kTimeoutMs = 2000; | |
116 // The time when we started benchmarking. | |
117 base::TimeTicks start_; | |
118 // The last time we got a paint notification. | |
119 base::TimeTicks last_paint_; | |
120 // Scoping so we can be sure our timeouts don't outlive us. | |
121 base::OneShotTimer<PaintTimer> timer_; | |
122 | |
123 DISALLOW_COPY_AND_ASSIGN(PaintTimer); | |
124 }; | |
125 | |
126 /////////////////////////////////////////////////////////////////////////////// | 67 /////////////////////////////////////////////////////////////////////////////// |
127 // RecentlyClosedTabsHandler | 68 // RecentlyClosedTabsHandler |
128 | 69 |
129 class RecentlyClosedTabsHandler : public DOMMessageHandler, | 70 class RecentlyClosedTabsHandler : public DOMMessageHandler, |
130 public TabRestoreServiceObserver { | 71 public TabRestoreServiceObserver { |
131 public: | 72 public: |
132 RecentlyClosedTabsHandler() : tab_restore_service_(NULL) {} | 73 RecentlyClosedTabsHandler() : tab_restore_service_(NULL) {} |
133 virtual ~RecentlyClosedTabsHandler(); | 74 virtual ~RecentlyClosedTabsHandler(); |
134 | 75 |
135 // DOMMessageHandler implementation. | 76 // DOMMessageHandler implementation. |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, | 344 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, |
404 NotificationService::AllSources()); | 345 NotificationService::AllSources()); |
405 // Listen for bookmark bar visibility changes. | 346 // Listen for bookmark bar visibility changes. |
406 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, | 347 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, |
407 NotificationService::AllSources()); | 348 NotificationService::AllSources()); |
408 } | 349 } |
409 | 350 |
410 NewTabUI::~NewTabUI() { | 351 NewTabUI::~NewTabUI() { |
411 } | 352 } |
412 | 353 |
| 354 // The timer callback. If enough time has elapsed since the last paint |
| 355 // message, we say we're done painting; otherwise, we keep waiting. |
| 356 void NewTabUI::PaintTimeout() { |
| 357 // The amount of time there must be no painting for us to consider painting |
| 358 // finished. Observed times are in the ~1200ms range on Windows. |
| 359 base::TimeTicks now = base::TimeTicks::Now(); |
| 360 if ((now - last_paint_) >= base::TimeDelta::FromMilliseconds(kTimeoutMs)) { |
| 361 // Painting has quieted down. Log this as the full time to run. |
| 362 base::TimeDelta load_time = last_paint_ - start_; |
| 363 int load_time_ms = static_cast<int>(load_time.InMilliseconds()); |
| 364 NotificationService::current()->Notify( |
| 365 NotificationType::INITIAL_NEW_TAB_UI_LOAD, |
| 366 NotificationService::AllSources(), |
| 367 Details<int>(&load_time_ms)); |
| 368 UMA_HISTOGRAM_TIMES("NewTabUI load", load_time); |
| 369 } else { |
| 370 // Not enough quiet time has elapsed. |
| 371 // Some more paints must've occurred since we set the timeout. |
| 372 // Wait some more. |
| 373 timer_.Start(base::TimeDelta::FromMilliseconds(kTimeoutMs), this, |
| 374 &NewTabUI::PaintTimeout); |
| 375 } |
| 376 } |
| 377 |
| 378 void NewTabUI::StartTimingPaint(RenderViewHost* render_view_host) { |
| 379 start_ = base::TimeTicks::Now(); |
| 380 last_paint_ = start_; |
| 381 registrar_.Add(this, NotificationType::RENDER_WIDGET_HOST_DID_PAINT, |
| 382 Source<RenderWidgetHost>(render_view_host)); |
| 383 timer_.Start(base::TimeDelta::FromMilliseconds(kTimeoutMs), this, |
| 384 &NewTabUI::PaintTimeout); |
| 385 |
| 386 } |
413 void NewTabUI::RenderViewCreated(RenderViewHost* render_view_host) { | 387 void NewTabUI::RenderViewCreated(RenderViewHost* render_view_host) { |
414 render_view_host->set_paint_observer(new PaintTimer); | 388 StartTimingPaint(render_view_host); |
415 } | 389 } |
416 | 390 |
417 void NewTabUI::RenderViewReused(RenderViewHost* render_view_host) { | 391 void NewTabUI::RenderViewReused(RenderViewHost* render_view_host) { |
418 render_view_host->set_paint_observer(new PaintTimer); | 392 StartTimingPaint(render_view_host); |
419 } | 393 } |
420 | 394 |
421 void NewTabUI::Observe(NotificationType type, | 395 void NewTabUI::Observe(NotificationType type, |
422 const NotificationSource& source, | 396 const NotificationSource& source, |
423 const NotificationDetails& details) { | 397 const NotificationDetails& details) { |
424 if (NotificationType::BROWSER_THEME_CHANGED == type) { | 398 if (NotificationType::BROWSER_THEME_CHANGED == type) { |
425 InitializeCSSCaches(); | 399 InitializeCSSCaches(); |
426 ListValue args; | 400 ListValue args; |
427 args.Append(Value::CreateStringValue( | 401 args.Append(Value::CreateStringValue( |
428 GetProfile()->GetThemeProvider()->HasCustomImage( | 402 GetProfile()->GetThemeProvider()->HasCustomImage( |
429 IDR_THEME_NTP_ATTRIBUTION) ? | 403 IDR_THEME_NTP_ATTRIBUTION) ? |
430 "true" : "false")); | 404 "true" : "false")); |
431 CallJavascriptFunction(L"themeChanged", args); | 405 CallJavascriptFunction(L"themeChanged", args); |
432 } else if (NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED) { | 406 } else if (NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED) { |
433 if (GetProfile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar)) | 407 if (GetProfile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar)) |
434 CallJavascriptFunction(L"bookmarkBarAttached"); | 408 CallJavascriptFunction(L"bookmarkBarAttached"); |
435 else | 409 else |
436 CallJavascriptFunction(L"bookmarkBarDetached"); | 410 CallJavascriptFunction(L"bookmarkBarDetached"); |
| 411 } else if (NotificationType::RENDER_WIDGET_HOST_DID_PAINT) { |
| 412 last_paint_ = base::TimeTicks::Now(); |
437 } | 413 } |
438 } | 414 } |
439 | 415 |
440 void NewTabUI::InitializeCSSCaches() { | 416 void NewTabUI::InitializeCSSCaches() { |
441 DOMUIThemeSource* theme = new DOMUIThemeSource(GetProfile()); | 417 DOMUIThemeSource* theme = new DOMUIThemeSource(GetProfile()); |
442 BrowserThread::PostTask( | 418 BrowserThread::PostTask( |
443 BrowserThread::IO, FROM_HERE, | 419 BrowserThread::IO, FROM_HERE, |
444 NewRunnableMethod( | 420 NewRunnableMethod( |
445 ChromeURLDataManager::GetInstance(), | 421 ChromeURLDataManager::GetInstance(), |
446 &ChromeURLDataManager::AddDataSource, | 422 &ChromeURLDataManager::AddDataSource, |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 | 592 |
617 scoped_refptr<RefCountedBytes> html_bytes( | 593 scoped_refptr<RefCountedBytes> html_bytes( |
618 profile_->GetNTPResourceCache()->GetNewTabHTML(is_off_the_record)); | 594 profile_->GetNTPResourceCache()->GetNewTabHTML(is_off_the_record)); |
619 | 595 |
620 SendResponse(request_id, html_bytes); | 596 SendResponse(request_id, html_bytes); |
621 } | 597 } |
622 | 598 |
623 std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string&) const { | 599 std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string&) const { |
624 return "text/html"; | 600 return "text/html"; |
625 } | 601 } |
OLD | NEW |