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/sessions/session_restore_delegate.h"
7 #include "base/metrics/field_trial.h"
8 #include "chrome/browser/sessions/session_restore_stats_collector.h"
9 #include "chrome/browser/sessions/tab_loader.h"
10 #include "chrome/common/url_constants.h"
11 #include "components/favicon/content/content_favicon_driver.h"
12 #include "content/public/browser/web_contents.h"
16 bool IsInternalPage(const GURL
& url
) {
17 // There are many chrome:// UI URLs, but only look for the ones that users
18 // are likely to have open. Most of the benefit is from the NTP URL.
19 const char* const kReloadableUrlPrefixes
[] = {
20 chrome::kChromeUIDownloadsURL
,
21 chrome::kChromeUIHistoryURL
,
22 chrome::kChromeUINewTabURL
,
23 chrome::kChromeUISettingsURL
,
25 // Prefix-match against the table above. Use strncmp to avoid allocating
26 // memory to convert the URL prefix constants into std::strings.
27 for (size_t i
= 0; i
< arraysize(kReloadableUrlPrefixes
); ++i
) {
28 if (!strncmp(url
.spec().c_str(), kReloadableUrlPrefixes
[i
],
29 strlen(kReloadableUrlPrefixes
[i
])))
37 SessionRestoreDelegate::RestoredTab::RestoredTab(content::WebContents
* contents
,
41 : contents_(contents
),
42 is_active_(is_active
),
44 is_internal_page_(IsInternalPage(contents
->GetLastCommittedURL())),
45 is_pinned_(is_pinned
) {
48 bool SessionRestoreDelegate::RestoredTab::operator<(
49 const RestoredTab
& right
) const {
50 // Tab with internal web UI like NTP or Settings are good choices to
52 if (is_internal_page_
!= right
.is_internal_page_
)
53 return !is_internal_page_
;
54 // Pinned tabs should be loaded first.
55 if (is_pinned_
!= right
.is_pinned_
)
57 // Apps should be loaded before normal tabs.
58 if (is_app_
!= right
.is_app_
)
60 // Restore using MRU. Behind an experiment for now.
61 if (SessionRestore::GetSmartRestoreMode() ==
62 SessionRestore::SMART_RESTORE_MODE_MRU
)
63 return contents_
->GetLastActiveTime() >
64 right
.contents_
->GetLastActiveTime();
69 void SessionRestoreDelegate::RestoreTabs(
70 const std::vector
<RestoredTab
>& tabs
,
71 const base::TimeTicks
& restore_started
) {
72 // Restore the favicon for all tabs. Any tab may end up being deferred due
73 // to memory pressure so it's best to have some visual indication of its
75 for (const auto& restored_tab
: tabs
) {
76 // Restore the favicon for deferred tabs.
77 favicon::ContentFaviconDriver
* favicon_driver
=
78 favicon::ContentFaviconDriver::FromWebContents(restored_tab
.contents());
79 favicon_driver
->FetchFavicon(favicon_driver
->GetActiveURL());
82 // This experiment allows us to have comparative numbers for session restore
83 // metrics. It will be removed once those numbers are obtained.
84 // TODO(georgesak): Remove this experiment when stats are collected.
85 base::FieldTrial
* trial
=
86 base::FieldTrialList::Find("IntelligentSessionRestore");
87 if (!trial
|| trial
->group_name() != "DontRestoreBackgroundTabs") {
88 TabLoader::RestoreTabs(tabs
, restore_started
);
90 // A TabLoader will not be used for this session restore, so manually create
91 // and use a SessionRestoreStatsCollector, normally owned by the TabLoader.
92 scoped_ptr
<SessionRestoreStatsCollector::StatsReportingDelegate
>
94 new SessionRestoreStatsCollector::UmaStatsReportingDelegate());
95 scoped_refptr
<SessionRestoreStatsCollector
> stats_collector
=
96 new SessionRestoreStatsCollector(restore_started
,
97 reporting_delegate
.Pass());
98 stats_collector
->TrackTabs(tabs
);
99 for (const auto& restored_tab
: tabs
) {
100 if (!restored_tab
.is_active()) {
101 // Non-active tabs aren't being loaded, so mark them as deferred.
102 auto tab_controller
= &restored_tab
.contents()->GetController();
103 stats_collector
->DeferTab(tab_controller
);