Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(655)

Side by Side Diff: chrome/browser/android/offline_pages/recent_tab_helper.cc

Issue 2278773002: Modify RecentTabHelper to be always-on and observe the loading of the pages. (Closed)
Patch Set: cr feedback Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 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 "chrome/browser/android/offline_pages/recent_tab_helper.h" 5 #include "chrome/browser/android/offline_pages/recent_tab_helper.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h" 14 #include "base/metrics/histogram_macros.h"
15 #include "base/strings/string_number_conversions.h" 15 #include "base/strings/string_number_conversions.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h" 18 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
19 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" 19 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
20 #include "chrome/browser/android/offline_pages/offline_page_utils.h" 20 #include "chrome/browser/android/offline_pages/offline_page_utils.h"
21 #include "components/offline_pages/client_namespace_constants.h" 21 #include "components/offline_pages/client_namespace_constants.h"
22 #include "components/offline_pages/offline_page_feature.h"
22 #include "components/offline_pages/offline_page_item.h" 23 #include "components/offline_pages/offline_page_item.h"
23 #include "components/offline_pages/offline_page_model.h" 24 #include "components/offline_pages/offline_page_model.h"
24 #include "content/public/browser/browser_context.h" 25 #include "content/public/browser/browser_context.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/navigation_entry.h" 27 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/navigation_handle.h" 28 #include "content/public/browser/navigation_handle.h"
28 29
29 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::RecentTabHelper); 30 DEFINE_WEB_CONTENTS_USER_DATA_KEY(offline_pages::RecentTabHelper);
30 31
31 namespace { 32 namespace {
(...skipping 15 matching lines...) Expand all
47 } 48 }
48 }; 49 };
49 } // namespace 50 } // namespace
50 51
51 namespace offline_pages { 52 namespace offline_pages {
52 53
53 RecentTabHelper::RecentTabHelper(content::WebContents* web_contents) 54 RecentTabHelper::RecentTabHelper(content::WebContents* web_contents)
54 : content::WebContentsObserver(web_contents), 55 : content::WebContentsObserver(web_contents),
55 page_model_(nullptr), 56 page_model_(nullptr),
56 snapshots_enabled_(false), 57 snapshots_enabled_(false),
58 is_page_ready_for_snapshot_(false),
57 delegate_(new DefaultDelegate()), 59 delegate_(new DefaultDelegate()),
58 weak_ptr_factory_(this) { 60 weak_ptr_factory_(this) {
59 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 61 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
60 } 62 }
61 63
62 RecentTabHelper::~RecentTabHelper() { 64 RecentTabHelper::~RecentTabHelper() {
63 } 65 }
64 66
65 void RecentTabHelper::SetDelegate( 67 void RecentTabHelper::SetDelegate(
66 std::unique_ptr<RecentTabHelper::Delegate> delegate) { 68 std::unique_ptr<RecentTabHelper::Delegate> delegate) {
67 DCHECK(delegate); 69 DCHECK(delegate);
68 delegate_ = std::move(delegate); 70 delegate_ = std::move(delegate);
69 } 71 }
70 72
71 void RecentTabHelper::LazyInitialize() { 73 // Initialize lazily. It needs TabAndroid for initialization, which is also a
72 snapshot_controller_.reset(new SnapshotController(delegate_->GetTaskRunner(), 74 // TabHelper - so can't initialize in constructor because of uncertain order
73 this)); 75 // of creation of TabHelpers.
76 void RecentTabHelper::EnsureInitialized() {
77 if (snapshot_controller_) // Initialized already.
78 return;
79
80 snapshot_controller_.reset(
81 new SnapshotController(delegate_->GetTaskRunner(), this));
82 snapshot_controller_->Stop(); // It is reset when navigation commits.
83
74 int tab_id_number = 0; 84 int tab_id_number = 0;
75 tab_id_.clear(); 85 tab_id_.clear();
76 86
77 if (delegate_->GetTabId(web_contents(), &tab_id_number)) 87 if (delegate_->GetTabId(web_contents(), &tab_id_number))
78 tab_id_ = base::IntToString(tab_id_number); 88 tab_id_ = base::IntToString(tab_id_number);
79 89
80 page_model_ = OfflinePageModelFactory::GetForBrowserContext(
81 web_contents()->GetBrowserContext());
82
83 // TODO(dimich): When we have BackgroundOffliner, avoid capturing prerenderer 90 // TODO(dimich): When we have BackgroundOffliner, avoid capturing prerenderer
84 // WebContents with its origin as well. 91 // WebContents with its origin as well.
85 snapshots_enabled_ = page_model_ && 92 snapshots_enabled_ = !tab_id_.empty() &&
86 !tab_id_.empty() &&
87 !web_contents()->GetBrowserContext()->IsOffTheRecord(); 93 !web_contents()->GetBrowserContext()->IsOffTheRecord();
88 94
89 if (!snapshots_enabled_) 95 if (!snapshots_enabled_)
90 snapshot_controller_->Stop(); 96 return;
97
98 page_model_ = OfflinePageModelFactory::GetForBrowserContext(
99 web_contents()->GetBrowserContext());
91 } 100 }
92 101
93 void RecentTabHelper::DidFinishNavigation( 102 void RecentTabHelper::DidFinishNavigation(
94 content::NavigationHandle* navigation_handle) { 103 content::NavigationHandle* navigation_handle) {
95 if (!navigation_handle->IsInMainFrame() || 104 if (!navigation_handle->IsInMainFrame() ||
96 !navigation_handle->HasCommitted()) { 105 !navigation_handle->HasCommitted()) {
97 return; 106 return;
98 } 107 }
99 108
100 // Initialize lazily. It needs TabAndroid for initization, which is also a 109 // Cancel tasks in flight that relate to the previous page.
101 // TabHelper - so can't initialize in constructor because of uncertain order 110 weak_ptr_factory_.InvalidateWeakPtrs();
102 // of creation of TabHelpers. 111 is_page_ready_for_snapshot_ = false;
103 if (!snapshot_controller_)
104 LazyInitialize();
105 112
113 EnsureInitialized();
106 if (!snapshots_enabled_) 114 if (!snapshots_enabled_)
107 return; 115 return;
108 116
109 // Cancel tasks in flight that relate to the previous page.
110 weak_ptr_factory_.InvalidateWeakPtrs();
111 117
112 // New navigation, new snapshot session. 118 // New navigation, new snapshot session.
113 snapshot_url_ = GURL(); 119 snapshot_url_ = web_contents()->GetLastCommittedURL();
114 GURL last_committed_url = web_contents()->GetLastCommittedURL();
115 120
116 // Check for conditions that would cause us not to snapshot. 121 // Check for conditions that would cause us not to snapshot.
117 bool can_save = !navigation_handle->IsErrorPage() && 122 bool can_save = !navigation_handle->IsErrorPage() &&
118 OfflinePageModel::CanSaveURL(last_committed_url); 123 OfflinePageModel::CanSaveURL(snapshot_url_);
119 124
120 UMA_HISTOGRAM_BOOLEAN("OfflinePages.CanSaveRecentPage", can_save); 125 UMA_HISTOGRAM_BOOLEAN("OfflinePages.CanSaveRecentPage", can_save);
121 126
122 // Always reset so that posted tasks get cancelled. 127 // Always reset so that posted tasks get canceled.
123 snapshot_controller_->Reset(); 128 snapshot_controller_->Reset();
124 129
125 if (!can_save) 130 if (!can_save)
126 snapshot_controller_->Stop(); 131 snapshot_controller_->Stop();
127 else
128 snapshot_url_ = last_committed_url;
129 } 132 }
130 133
131 void RecentTabHelper::DocumentAvailableInMainFrame() { 134 void RecentTabHelper::DocumentAvailableInMainFrame() {
132 if (!snapshots_enabled_) 135 EnsureInitialized();
133 return;
134 snapshot_controller_->DocumentAvailableInMainFrame(); 136 snapshot_controller_->DocumentAvailableInMainFrame();
135 } 137 }
136 138
137 void RecentTabHelper::DocumentOnLoadCompletedInMainFrame() { 139 void RecentTabHelper::DocumentOnLoadCompletedInMainFrame() {
138 // TODO(dimich): Figure out when this can fire before DidFinishNavigate(). 140 EnsureInitialized();
139 // See bug 628716 for more info.
140 if (!snapshots_enabled_)
141 return;
142 snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); 141 snapshot_controller_->DocumentOnLoadCompletedInMainFrame();
143 } 142 }
144 143
145 // This starts a sequence of async operations chained through callbacks: 144 // This starts a sequence of async operations chained through callbacks:
146 // - compute the set of old 'last_n' pages that have to be purged 145 // - compute the set of old 'last_n' pages that have to be purged
147 // - delete the pages found in the previous step 146 // - delete the pages found in the previous step
148 // - snapshot the current web contents 147 // - snapshot the current web contents
149 // Along the chain, the original URL is passed and compared, to detect 148 // Along the chain, the original URL is passed and compared, to detect
150 // possible navigation and cancel snapshot in that case. 149 // possible navigation and cancel snapshot in that case.
151 void RecentTabHelper::StartSnapshot() { 150 void RecentTabHelper::StartSnapshot() {
152 if (!snapshots_enabled_) 151 is_page_ready_for_snapshot_ = true;
152
153 if (!snapshots_enabled_ ||
154 !page_model_ ||
155 !offline_pages::IsOffliningRecentPagesEnabled()) {
156 ReportSnapshotCompleted();
153 return; 157 return;
158 }
159
154 // Remove previously captured pages for this tab. 160 // Remove previously captured pages for this tab.
155 page_model_->GetOfflineIdsForClientId( 161 page_model_->GetOfflineIdsForClientId(
156 client_id(), 162 client_id(),
157 base::Bind(&RecentTabHelper::ContinueSnapshotWithIdsToPurge, 163 base::Bind(&RecentTabHelper::ContinueSnapshotWithIdsToPurge,
158 weak_ptr_factory_.GetWeakPtr())); 164 weak_ptr_factory_.GetWeakPtr()));
159 } 165 }
160 166
161 void RecentTabHelper::ContinueSnapshotWithIdsToPurge( 167 void RecentTabHelper::ContinueSnapshotWithIdsToPurge(
162 const std::vector<int64_t>& page_ids) { 168 const std::vector<int64_t>& page_ids) {
163 page_model_->DeletePagesByOfflineId( 169 page_model_->DeletePagesByOfflineId(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 bool RecentTabHelper::IsSamePage() const { 202 bool RecentTabHelper::IsSamePage() const {
197 return web_contents() && 203 return web_contents() &&
198 (web_contents()->GetLastCommittedURL() == snapshot_url_); 204 (web_contents()->GetLastCommittedURL() == snapshot_url_);
199 } 205 }
200 206
201 ClientId RecentTabHelper::client_id() const { 207 ClientId RecentTabHelper::client_id() const {
202 return ClientId(kLastNNamespace, tab_id_); 208 return ClientId(kLastNNamespace, tab_id_);
203 } 209 }
204 210
205 } // namespace offline_pages 211 } // namespace offline_pages
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698