Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 49 bool GetTabId(content::WebContents* web_contents, int* tab_id) override { | 49 bool GetTabId(content::WebContents* web_contents, int* tab_id) override { |
| 50 return offline_pages::OfflinePageUtils::GetTabId(web_contents, tab_id); | 50 return offline_pages::OfflinePageUtils::GetTabId(web_contents, tab_id); |
| 51 } | 51 } |
| 52 }; | 52 }; |
| 53 } // namespace | 53 } // namespace |
| 54 | 54 |
| 55 namespace offline_pages { | 55 namespace offline_pages { |
| 56 | 56 |
| 57 using PageQuality = SnapshotController::PageQuality; | 57 using PageQuality = SnapshotController::PageQuality; |
| 58 | 58 |
| 59 bool RecentTabHelper::SnapshotProgressInfo::IsForLastN() { | 59 // Keeps client_id/request_id that will be used for the offline snapshot. |
| 60 // A last_n snapshot always has an invalid request id. | 60 struct RecentTabHelper::SnapshotProgressInfo { |
| 61 return request_id == OfflinePageModel::kInvalidOfflineId; | 61 public: |
| 62 } | 62 // For a downloads snapshot request, where the |request_id| is defined. |
| 63 SnapshotProgressInfo(const ClientId& client_id, int64_t request_id) | |
| 64 : client_id(client_id), request_id(request_id) {} | |
| 65 | |
| 66 // For a last_n snapshot request. | |
| 67 explicit SnapshotProgressInfo(const ClientId& client_id) | |
| 68 : client_id(client_id) {} | |
| 69 | |
| 70 bool IsForLastN() { return client_id.name_space == kLastNNamespace; } | |
| 71 | |
| 72 // The ClientID to go with the offline page. | |
| 73 ClientId client_id; | |
| 74 | |
| 75 // Id of the suspended request in Background Offliner. Used to un-suspend | |
| 76 // the request if the capture of the current page was not possible (e.g. | |
| 77 // the user navigated to another page before current one was loaded). | |
| 78 // 0 if this is a "last_n" info. | |
| 79 int64_t request_id = OfflinePageModel::kInvalidOfflineId; | |
| 80 | |
| 81 // Expected snapshot quality should the saving succeed. This value is only | |
| 82 // valid if |page_snapshot_completed| is true. | |
|
Dmitry Titov
2017/01/27 04:18:22
Not clear which "|page_snapshot_completed|" this c
carlosk
2017/01/27 18:47:14
Done.
| |
| 83 SnapshotController::PageQuality expected_page_quality = | |
| 84 SnapshotController::PageQuality::POOR; | |
| 85 }; | |
| 63 | 86 |
| 64 RecentTabHelper::RecentTabHelper(content::WebContents* web_contents) | 87 RecentTabHelper::RecentTabHelper(content::WebContents* web_contents) |
| 65 : content::WebContentsObserver(web_contents), | 88 : content::WebContentsObserver(web_contents), |
| 66 delegate_(new DefaultDelegate()), | 89 delegate_(new DefaultDelegate()), |
| 67 weak_ptr_factory_(this) { | 90 weak_ptr_factory_(this) { |
| 68 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 91 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 69 } | 92 } |
| 70 | 93 |
| 71 RecentTabHelper::~RecentTabHelper() { | 94 RecentTabHelper::~RecentTabHelper() { |
| 72 } | 95 } |
| 73 | 96 |
| 74 void RecentTabHelper::SetDelegate( | 97 void RecentTabHelper::SetDelegate( |
| 75 std::unique_ptr<RecentTabHelper::Delegate> delegate) { | 98 std::unique_ptr<RecentTabHelper::Delegate> delegate) { |
| 76 DCHECK(delegate); | 99 DCHECK(delegate); |
| 77 delegate_ = std::move(delegate); | 100 delegate_ = std::move(delegate); |
| 78 } | 101 } |
| 79 | 102 |
| 80 void RecentTabHelper::ObserveAndDownloadCurrentPage( | 103 void RecentTabHelper::ObserveAndDownloadCurrentPage( |
| 81 const ClientId& client_id, int64_t request_id) { | 104 const ClientId& client_id, int64_t request_id) { |
| 105 // Note: as this implementation only supports one client namespace, enforce | |
| 106 // that the call is from Downloads. | |
|
dewittj
2017/01/27 18:48:57
Suggestion to remove the DCHECK: change signature
carlosk
2017/01/27 23:13:30
As OfflinePageDownloadBridge also uses the ClientI
| |
| 107 DCHECK_EQ(kDownloadNamespace, client_id.name_space); | |
| 82 auto new_downloads_snapshot_info = | 108 auto new_downloads_snapshot_info = |
| 83 base::MakeUnique<SnapshotProgressInfo>(client_id, request_id); | 109 base::MakeUnique<SnapshotProgressInfo>(client_id, request_id); |
| 84 | 110 |
| 85 // If this tab helper is not enabled, immediately give the job back to | 111 // If this tab helper is not enabled, immediately give the job back to |
| 86 // RequestCoordinator. | 112 // RequestCoordinator. |
| 87 if (!EnsureInitialized()) { | 113 if (!EnsureInitialized()) { |
| 88 ReportDownloadStatusToRequestCoordinator(new_downloads_snapshot_info.get()); | 114 ReportDownloadStatusToRequestCoordinator(new_downloads_snapshot_info.get(), |
| 115 false); | |
| 89 return; | 116 return; |
| 90 } | 117 } |
| 91 | 118 |
| 92 // TODO(carlosk): This is a good moment check if a snapshot is currently being | 119 // If there is an ongoing snapshot request, completely ignore this one and |
| 93 // generated. This would allow the early cancellation of this request (without | 120 // cancel the Background Offliner request. |
| 94 // incurring in scheduling a background download). | 121 // TODO(carlosk): it might be better to make the decision to schedule or not |
|
dewittj
2017/01/27 18:48:57
This TODO is not really actionable. Is there a bu
carlosk
2017/01/27 23:13:30
Done.
| |
| 122 // the background request here. | |
| 123 // TODO(carlosk): an edge case happens when the ongoing request was | |
|
dewittj
2017/01/27 18:48:57
This should be more explicit about the race condit
carlosk
2017/01/27 23:13:30
Added a crbug with further details.
| |
| 124 // automatically and transparently scheduled by a navigation event and this | |
| 125 // call happens due to the user pressing the download button. The user's | |
| 126 // request to download the page will be immediately dismissed. | |
| 127 if (downloads_ongoing_snapshot_info_) { | |
| 128 ReportDownloadStatusToRequestCoordinator(new_downloads_snapshot_info.get(), | |
| 129 true); | |
| 130 return; | |
| 131 } | |
| 95 | 132 |
| 96 // Stores the new snapshot info. | 133 // Stores the new snapshot info. |
| 97 downloads_latest_snapshot_info_ = std::move(new_downloads_snapshot_info); | 134 downloads_ongoing_snapshot_info_ = std::move(new_downloads_snapshot_info); |
| 98 | 135 |
| 99 // If the page is not yet ready for a snapshot return now as it will be | 136 // If the page is not yet ready for a snapshot return now as it will be |
| 100 // started later, once page loading advances. | 137 // started later, once page loading advances. |
| 101 if (PageQuality::POOR == snapshot_controller_->current_page_quality()) | 138 if (PageQuality::POOR == snapshot_controller_->current_page_quality()) { |
| 139 downloads_snapshot_on_hold_ = true; | |
| 102 return; | 140 return; |
| 141 } | |
| 103 | 142 |
| 104 // Otherwise start saving the snapshot now. | 143 // Otherwise start saving the snapshot now. |
| 105 SaveSnapshotForDownloads(); | 144 SaveSnapshotForDownloads(false); |
| 106 } | 145 } |
| 107 | 146 |
| 108 // Initialize lazily. It needs TabAndroid for initialization, which is also a | 147 // Initialize lazily. It needs TabAndroid for initialization, which is also a |
| 109 // TabHelper - so can't initialize in constructor because of uncertain order | 148 // TabHelper - so can't initialize in constructor because of uncertain order |
| 110 // of creation of TabHelpers. | 149 // of creation of TabHelpers. |
| 111 bool RecentTabHelper::EnsureInitialized() { | 150 bool RecentTabHelper::EnsureInitialized() { |
| 112 if (snapshot_controller_) // Initialized already. | 151 if (snapshot_controller_) // Initialized already. |
| 113 return snapshots_enabled_; | 152 return snapshots_enabled_; |
| 114 | 153 |
| 115 snapshot_controller_.reset( | 154 snapshot_controller_.reset( |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 138 void RecentTabHelper::DidFinishNavigation( | 177 void RecentTabHelper::DidFinishNavigation( |
| 139 content::NavigationHandle* navigation_handle) { | 178 content::NavigationHandle* navigation_handle) { |
| 140 if (!navigation_handle->IsInMainFrame() || | 179 if (!navigation_handle->IsInMainFrame() || |
| 141 !navigation_handle->HasCommitted()) { | 180 !navigation_handle->HasCommitted()) { |
| 142 return; | 181 return; |
| 143 } | 182 } |
| 144 | 183 |
| 145 if (!EnsureInitialized()) | 184 if (!EnsureInitialized()) |
| 146 return; | 185 return; |
| 147 | 186 |
| 148 // We navigated to a different page, lets report progress to Background | 187 // If there is an ongoing downloads request, lets allow Background Offliner to |
| 149 // Offliner. | 188 // continue downloading this page. |
| 150 if (downloads_latest_snapshot_info_) | 189 if (downloads_ongoing_snapshot_info_) { |
| 151 ReportDownloadStatusToRequestCoordinator( | 190 ReportDownloadStatusToRequestCoordinator( |
| 152 downloads_latest_snapshot_info_.get()); | 191 downloads_ongoing_snapshot_info_.get(), false); |
| 192 } | |
| 153 | 193 |
| 154 // Cancel any and all in flight snapshot tasks from the previous page. | 194 // Cancel any and all in flight snapshot tasks from the previous page. |
| 155 weak_ptr_factory_.InvalidateWeakPtrs(); | 195 weak_ptr_factory_.InvalidateWeakPtrs(); |
|
dewittj
2017/01/27 18:48:57
perhaps the reset() + invalidateweakptrs should be
carlosk
2017/01/27 23:13:30
Done.
| |
| 156 downloads_latest_snapshot_info_.reset(); | 196 downloads_ongoing_snapshot_info_.reset(); |
| 197 downloads_latest_saved_snapshot_info_.reset(); | |
| 198 downloads_snapshot_on_hold_ = false; | |
| 157 last_n_ongoing_snapshot_info_.reset(); | 199 last_n_ongoing_snapshot_info_.reset(); |
| 158 | 200 |
| 159 // New navigation, new snapshot session. | 201 // New navigation, new snapshot session. |
| 160 snapshot_url_ = web_contents()->GetLastCommittedURL(); | 202 snapshot_url_ = web_contents()->GetLastCommittedURL(); |
| 161 | 203 |
| 162 // Always reset so that posted tasks get canceled. | 204 // Always reset so that posted tasks get canceled. |
| 163 snapshot_controller_->Reset(); | 205 snapshot_controller_->Reset(); |
| 164 | 206 |
| 165 // Check for conditions that would cause us not to snapshot. | 207 // Check for conditions that would cause us not to snapshot. |
| 166 bool can_save = !navigation_handle->IsErrorPage() && | 208 bool can_save = !navigation_handle->IsErrorPage() && |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 180 EnsureInitialized(); | 222 EnsureInitialized(); |
| 181 snapshot_controller_->DocumentAvailableInMainFrame(); | 223 snapshot_controller_->DocumentAvailableInMainFrame(); |
| 182 } | 224 } |
| 183 | 225 |
| 184 void RecentTabHelper::DocumentOnLoadCompletedInMainFrame() { | 226 void RecentTabHelper::DocumentOnLoadCompletedInMainFrame() { |
| 185 EnsureInitialized(); | 227 EnsureInitialized(); |
| 186 snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); | 228 snapshot_controller_->DocumentOnLoadCompletedInMainFrame(); |
| 187 } | 229 } |
| 188 | 230 |
| 189 void RecentTabHelper::WebContentsDestroyed() { | 231 void RecentTabHelper::WebContentsDestroyed() { |
| 190 // WebContents (and maybe Tab) is destroyed, report status to Offliner. | 232 // If there is an ongoing downloads request, lets allow Background Offliner to |
| 191 if (downloads_latest_snapshot_info_) | 233 // continue downloading this page. |
| 234 if (downloads_ongoing_snapshot_info_) | |
| 192 ReportDownloadStatusToRequestCoordinator( | 235 ReportDownloadStatusToRequestCoordinator( |
| 193 downloads_latest_snapshot_info_.get()); | 236 downloads_ongoing_snapshot_info_.get(), false); |
| 194 // And cancel any ongoing snapshots. | 237 // And cancel any ongoing snapshots. |
| 195 weak_ptr_factory_.InvalidateWeakPtrs(); | 238 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 196 } | 239 } |
| 197 | 240 |
| 198 // TODO(carlosk): this method is also called when the tab is being closed, when | 241 // TODO(carlosk): this method is also called when the tab is being closed, when |
| 199 // saving a snapshot is probably useless (low probability of the user undoing | 242 // saving a snapshot is probably useless (low probability of the user undoing |
| 200 // the close). We should detect that and avoid the saving. | 243 // the close). We should detect that and avoid the saving. |
| 201 void RecentTabHelper::WasHidden() { | 244 void RecentTabHelper::WasHidden() { |
| 202 if (!IsOffliningRecentPagesEnabled()) | 245 if (!IsOffliningRecentPagesEnabled()) |
| 203 return; | 246 return; |
| 204 | 247 |
| 205 // Return immediately if last_n is not listening to tab hidden events or if a | 248 // Return immediately if last_n is not listening to tab hidden events or if a |
| 206 // last_n snapshot is currently being saved. | 249 // last_n snapshot is currently being saved. |
| 207 if (!last_n_listen_to_tab_hidden_ || last_n_ongoing_snapshot_info_) | 250 if (!last_n_listen_to_tab_hidden_ || last_n_ongoing_snapshot_info_) |
| 208 return; | 251 return; |
| 209 | 252 |
| 210 // Do not save if page quality is too low or if we already have a snapshot | 253 // Do not save if page quality is too low or if we already have a snapshot |
| 211 // with the current quality level. | 254 // with the current quality level. |
| 212 // Note: we assume page quality for a page can only increase. | 255 // Note: we assume page quality for a page can only increase. |
| 213 PageQuality current_quality = snapshot_controller_->current_page_quality(); | 256 PageQuality current_quality = snapshot_controller_->current_page_quality(); |
| 214 if (current_quality == PageQuality::POOR || | 257 if (current_quality == PageQuality::POOR || |
| 215 current_quality == last_n_latest_saved_quality_) { | 258 current_quality == last_n_latest_saved_quality_) { |
| 216 return; | 259 return; |
| 217 } | 260 } |
| 218 | 261 |
| 219 last_n_ongoing_snapshot_info_ = | 262 last_n_ongoing_snapshot_info_ = |
| 220 base::MakeUnique<SnapshotProgressInfo>(GetRecentPagesClientId()); | 263 base::MakeUnique<SnapshotProgressInfo>(GetRecentPagesClientId()); |
| 264 DCHECK(last_n_ongoing_snapshot_info_->IsForLastN()); | |
| 221 DCHECK(snapshots_enabled_); | 265 DCHECK(snapshots_enabled_); |
| 222 // Remove previously captured pages for this tab. | 266 // Remove previously captured pages for this tab. |
| 223 page_model_->GetOfflineIdsForClientId( | 267 page_model_->GetOfflineIdsForClientId( |
| 224 GetRecentPagesClientId(), | 268 GetRecentPagesClientId(), |
| 225 base::Bind(&RecentTabHelper::ContinueSnapshotWithIdsToPurge, | 269 base::Bind(&RecentTabHelper::ContinueSnapshotWithIdsToPurge, |
| 226 weak_ptr_factory_.GetWeakPtr(), | 270 weak_ptr_factory_.GetWeakPtr(), |
| 227 last_n_ongoing_snapshot_info_.get())); | 271 last_n_ongoing_snapshot_info_.get())); |
| 228 } | 272 } |
| 229 | 273 |
| 230 // TODO(carlosk): rename this to RequestSnapshot and make it return a bool | 274 // TODO(carlosk): rename this to RequestSnapshot and make it return a bool |
| 231 // representing the acceptance of the snapshot request. | 275 // representing the acceptance of the snapshot request. |
| 232 void RecentTabHelper::StartSnapshot() { | 276 void RecentTabHelper::StartSnapshot() { |
| 233 DCHECK_NE(PageQuality::POOR, snapshot_controller_->current_page_quality()); | 277 DCHECK_NE(PageQuality::POOR, snapshot_controller_->current_page_quality()); |
| 234 | 278 |
| 235 // This is a navigation based snapshot request so check that snapshots are | 279 // As long as snapshots are enabled for this tab, there are two situations |
| 236 // both enabled and there is a downloads request for one. | 280 // that allow for a navigation event to start a snapshot: |
| 237 // TODO(carlosk): This is a good moment to add the check for an ongoing | 281 // 1) There is a request on hold waiting for the page to be minimally loaded. |
| 238 // snapshot that could trigger the early cancellation of this request. | 282 if (snapshots_enabled_ && downloads_snapshot_on_hold_) { |
| 239 if (snapshots_enabled_ && downloads_latest_snapshot_info_) | 283 downloads_snapshot_on_hold_ = false; |
| 240 SaveSnapshotForDownloads(); | 284 SaveSnapshotForDownloads(false); |
| 241 else | 285 return; |
| 242 snapshot_controller_->PendingSnapshotCompleted(); | 286 } |
| 287 | |
| 288 // 2) There's no ongoing snapshot and a previous one was saved with lower | |
| 289 // expected quality than what would be possible now. | |
| 290 if (snapshots_enabled_ && | |
| 291 (!downloads_ongoing_snapshot_info_ && | |
| 292 downloads_latest_saved_snapshot_info_ && | |
| 293 downloads_latest_saved_snapshot_info_->expected_page_quality < | |
| 294 snapshot_controller_->current_page_quality())) { | |
| 295 SaveSnapshotForDownloads(true); | |
| 296 return; | |
| 297 } | |
| 298 | |
| 299 // Notify the controller that a snapshot was not started. | |
| 300 snapshot_controller_->PendingSnapshotCompleted(); | |
| 243 } | 301 } |
| 244 | 302 |
| 245 // TODO(carlosk): There is still the possibility of overlapping snapshots with | 303 void RecentTabHelper::SaveSnapshotForDownloads(bool replace_latest) { |
| 246 // some combinations of calls to ObserveAndDownloadCurrentPage and | |
| 247 // StartSnapshot. It won't cause side effects beyond wasted resources and will | |
| 248 // be dealt with later. | |
| 249 void RecentTabHelper::SaveSnapshotForDownloads() { | |
| 250 DCHECK_NE(PageQuality::POOR, snapshot_controller_->current_page_quality()); | 304 DCHECK_NE(PageQuality::POOR, snapshot_controller_->current_page_quality()); |
| 251 DCHECK(downloads_latest_snapshot_info_); | |
| 252 | 305 |
| 253 // Requests the deletion of a potentially existing previous snapshot of this | 306 if (replace_latest) { |
| 254 // page. | 307 // Start by requesting the deletion of the existing previous snapshot of |
| 255 std::vector<int64_t> ids{downloads_latest_snapshot_info_->request_id}; | 308 // this page. |
| 256 ContinueSnapshotWithIdsToPurge(downloads_latest_snapshot_info_.get(), ids); | 309 DCHECK(downloads_latest_saved_snapshot_info_); |
| 310 DCHECK(!downloads_ongoing_snapshot_info_); | |
| 311 downloads_ongoing_snapshot_info_ = base::MakeUnique<SnapshotProgressInfo>( | |
| 312 downloads_latest_saved_snapshot_info_->client_id, | |
| 313 downloads_latest_saved_snapshot_info_->request_id); | |
| 314 std::vector<int64_t> ids{downloads_latest_saved_snapshot_info_->request_id}; | |
| 315 ContinueSnapshotWithIdsToPurge(downloads_ongoing_snapshot_info_.get(), ids); | |
| 316 } else { | |
| 317 // Otherwise go straight to saving the page. | |
| 318 DCHECK(downloads_ongoing_snapshot_info_); | |
| 319 ContinueSnapshotAfterPurge(downloads_ongoing_snapshot_info_.get(), | |
| 320 OfflinePageModel::DeletePageResult::SUCCESS); | |
| 321 } | |
| 257 } | 322 } |
| 258 | 323 |
| 259 // This is the 1st step of a sequence of async operations chained through | 324 // This is the 1st step of a sequence of async operations chained through |
| 260 // callbacks, mostly shared between last_n and downloads: | 325 // callbacks, mostly shared between last_n and downloads: |
| 261 // 1) Compute the set of old 'last_n' pages that have to be purged. | 326 // 1) Compute the set of old 'last_n' pages that have to be purged. |
| 262 // 2) Delete the pages found in the previous step. | 327 // 2) Delete the pages found in the previous step. |
| 263 // 3) Snapshot the current web contents. | 328 // 3) Snapshot the current web contents. |
| 264 // 4) Notify requesters about the final result of the operation. | 329 // 4) Notify requesters about the final result of the operation. |
| 265 // | 330 // |
| 266 // For last_n requests the sequence is started in 1); for downloads it starts in | 331 // For last_n requests the sequence is always started in 1). For downloads it |
| 267 // 2). Step 4) might be called anytime during the chain for early termination in | 332 // starts in either 2) or 3). Step 4) might be called anytime during the chain |
| 268 // case of errors. | 333 // for early termination in case of errors. |
| 269 void RecentTabHelper::ContinueSnapshotWithIdsToPurge( | 334 void RecentTabHelper::ContinueSnapshotWithIdsToPurge( |
| 270 SnapshotProgressInfo* snapshot_info, | 335 SnapshotProgressInfo* snapshot_info, |
| 271 const std::vector<int64_t>& page_ids) { | 336 const std::vector<int64_t>& page_ids) { |
| 272 DCHECK(snapshot_info); | 337 DCHECK(snapshot_info); |
| 273 | 338 |
| 274 page_model_->DeletePagesByOfflineId( | 339 page_model_->DeletePagesByOfflineId( |
| 275 page_ids, base::Bind(&RecentTabHelper::ContinueSnapshotAfterPurge, | 340 page_ids, base::Bind(&RecentTabHelper::ContinueSnapshotAfterPurge, |
| 276 weak_ptr_factory_.GetWeakPtr(), snapshot_info)); | 341 weak_ptr_factory_.GetWeakPtr(), snapshot_info)); |
| 277 } | 342 } |
| 278 | 343 |
| 279 void RecentTabHelper::ContinueSnapshotAfterPurge( | 344 void RecentTabHelper::ContinueSnapshotAfterPurge( |
| 280 SnapshotProgressInfo* snapshot_info, | 345 SnapshotProgressInfo* snapshot_info, |
| 281 OfflinePageModel::DeletePageResult result) { | 346 OfflinePageModel::DeletePageResult result) { |
| 282 DCHECK_EQ(snapshot_url_, web_contents()->GetLastCommittedURL()); | 347 DCHECK_EQ(snapshot_url_, web_contents()->GetLastCommittedURL()); |
| 283 if (result != OfflinePageModel::DeletePageResult::SUCCESS) { | 348 if (result != OfflinePageModel::DeletePageResult::SUCCESS) { |
| 284 ReportSnapshotCompleted(snapshot_info); | 349 ReportSnapshotCompleted(snapshot_info, false); |
| 285 return; | 350 return; |
| 286 } | 351 } |
| 287 | 352 |
| 288 snapshot_info->expected_page_quality = | 353 snapshot_info->expected_page_quality = |
| 289 snapshot_controller_->current_page_quality(); | 354 snapshot_controller_->current_page_quality(); |
| 290 OfflinePageModel::SavePageParams save_page_params; | 355 OfflinePageModel::SavePageParams save_page_params; |
| 291 save_page_params.url = snapshot_url_; | 356 save_page_params.url = snapshot_url_; |
| 292 save_page_params.client_id = snapshot_info->client_id; | 357 save_page_params.client_id = snapshot_info->client_id; |
| 293 save_page_params.proposed_offline_id = snapshot_info->request_id; | 358 save_page_params.proposed_offline_id = snapshot_info->request_id; |
| 294 page_model_->SavePage( | 359 page_model_->SavePage( |
| 295 save_page_params, delegate_->CreatePageArchiver(web_contents()), | 360 save_page_params, delegate_->CreatePageArchiver(web_contents()), |
| 296 base::Bind(&RecentTabHelper::SavePageCallback, | 361 base::Bind(&RecentTabHelper::SavePageCallback, |
| 297 weak_ptr_factory_.GetWeakPtr(), snapshot_info)); | 362 weak_ptr_factory_.GetWeakPtr(), snapshot_info)); |
| 298 } | 363 } |
| 299 | 364 |
| 300 void RecentTabHelper::SavePageCallback(SnapshotProgressInfo* snapshot_info, | 365 void RecentTabHelper::SavePageCallback(SnapshotProgressInfo* snapshot_info, |
| 301 OfflinePageModel::SavePageResult result, | 366 OfflinePageModel::SavePageResult result, |
| 302 int64_t offline_id) { | 367 int64_t offline_id) { |
| 303 DCHECK(snapshot_info->IsForLastN() || | 368 DCHECK(snapshot_info->IsForLastN() || |
| 304 snapshot_info->request_id == offline_id); | 369 snapshot_info->request_id == offline_id); |
| 305 snapshot_info->page_snapshot_completed = (result == SavePageResult::SUCCESS); | 370 ReportSnapshotCompleted(snapshot_info, result == SavePageResult::SUCCESS); |
| 306 ReportSnapshotCompleted(snapshot_info); | |
| 307 } | 371 } |
| 308 | 372 |
| 309 // Note: this is the final step in the chain of callbacks and it's where the | 373 // Note: this is the final step in the chain of callbacks and it's where the |
| 310 // behavior is different depending on this being a last_n or downloads snapshot. | 374 // behavior is different depending on this being a last_n or downloads snapshot. |
| 311 void RecentTabHelper::ReportSnapshotCompleted( | 375 void RecentTabHelper::ReportSnapshotCompleted( |
| 312 SnapshotProgressInfo* snapshot_info) { | 376 SnapshotProgressInfo* snapshot_info, |
| 377 bool success) { | |
| 313 if (snapshot_info->IsForLastN()) { | 378 if (snapshot_info->IsForLastN()) { |
| 314 DCHECK_EQ(snapshot_info, last_n_ongoing_snapshot_info_.get()); | 379 DCHECK_EQ(snapshot_info, last_n_ongoing_snapshot_info_.get()); |
| 315 if (snapshot_info->page_snapshot_completed) | 380 if (success) |
| 316 last_n_latest_saved_quality_ = snapshot_info->expected_page_quality; | 381 last_n_latest_saved_quality_ = snapshot_info->expected_page_quality; |
| 317 last_n_ongoing_snapshot_info_.reset(); | 382 last_n_ongoing_snapshot_info_.reset(); |
| 318 return; | 383 return; |
| 319 } | 384 } |
| 320 | 385 |
| 386 DCHECK_EQ(snapshot_info, downloads_ongoing_snapshot_info_.get()); | |
| 321 snapshot_controller_->PendingSnapshotCompleted(); | 387 snapshot_controller_->PendingSnapshotCompleted(); |
| 322 // Tell RequestCoordinator how the request should be processed further. | 388 // Tell RequestCoordinator how the request should be processed further. |
| 323 ReportDownloadStatusToRequestCoordinator(snapshot_info); | 389 ReportDownloadStatusToRequestCoordinator(snapshot_info, success); |
| 390 if (success) { | |
| 391 downloads_latest_saved_snapshot_info_ = | |
| 392 std::move(downloads_ongoing_snapshot_info_); | |
| 393 } else { | |
| 394 downloads_ongoing_snapshot_info_.reset(); | |
| 395 } | |
| 324 } | 396 } |
| 325 | 397 |
| 326 // Note: we cannot assume that snapshot_info == downloads_latest_snapshot_info_ | 398 // Note: we cannot assume that snapshot_info == downloads_latest_snapshot_info_ |
| 327 // because further calls made to ObserveAndDownloadCurrentPage will replace | 399 // because further calls made to ObserveAndDownloadCurrentPage will replace |
| 328 // downloads_latest_snapshot_info_ with a new instance. | 400 // downloads_latest_snapshot_info_ with a new instance. |
| 329 void RecentTabHelper::ReportDownloadStatusToRequestCoordinator( | 401 void RecentTabHelper::ReportDownloadStatusToRequestCoordinator( |
| 330 SnapshotProgressInfo* snapshot_info) { | 402 SnapshotProgressInfo* snapshot_info, |
| 403 bool cancel_background_request) { | |
| 331 DCHECK(snapshot_info); | 404 DCHECK(snapshot_info); |
| 332 DCHECK(!snapshot_info->IsForLastN()); | 405 DCHECK(!snapshot_info->IsForLastN()); |
| 333 | 406 |
| 334 RequestCoordinator* request_coordinator = | 407 RequestCoordinator* request_coordinator = |
| 335 RequestCoordinatorFactory::GetForBrowserContext( | 408 RequestCoordinatorFactory::GetForBrowserContext( |
| 336 web_contents()->GetBrowserContext()); | 409 web_contents()->GetBrowserContext()); |
| 337 if (!request_coordinator) | 410 if (!request_coordinator) |
| 338 return; | 411 return; |
| 339 | 412 |
| 340 // It is OK to call these methods more then once, depending on | 413 // It is OK to call these methods more then once, depending on |
| 341 // number of snapshots attempted in this tab helper. If the request_id is not | 414 // number of snapshots attempted in this tab helper. If the request_id is not |
| 342 // in the list of RequestCoordinator, these calls have no effect. | 415 // in the list of RequestCoordinator, these calls have no effect. |
| 343 if (snapshot_info->page_snapshot_completed) | 416 if (cancel_background_request) |
| 344 request_coordinator->MarkRequestCompleted(snapshot_info->request_id); | 417 request_coordinator->MarkRequestCompleted(snapshot_info->request_id); |
| 345 else | 418 else |
| 346 request_coordinator->EnableForOffliner(snapshot_info->request_id, | 419 request_coordinator->EnableForOffliner(snapshot_info->request_id, |
| 347 snapshot_info->client_id); | 420 snapshot_info->client_id); |
| 348 } | 421 } |
| 349 | 422 |
| 350 ClientId RecentTabHelper::GetRecentPagesClientId() const { | 423 ClientId RecentTabHelper::GetRecentPagesClientId() const { |
| 351 return ClientId(kLastNNamespace, tab_id_); | 424 return ClientId(kLastNNamespace, tab_id_); |
| 352 } | 425 } |
| 353 | 426 |
| 354 } // namespace offline_pages | 427 } // namespace offline_pages |
| OLD | NEW |