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

Unified Diff: chrome/browser/android/offline_pages/background_loader_offliner.cc

Issue 2534673002: [Offline pages] Create offliner that uses background loader (Closed)
Patch Set: bleh it works now Created 4 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/offline_pages/background_loader_offliner.cc
diff --git a/chrome/browser/android/offline_pages/background_loader_offliner.cc b/chrome/browser/android/offline_pages/background_loader_offliner.cc
new file mode 100644
index 0000000000000000000000000000000000000000..096a5229acc2c2d6cb5eefe0f4bf9c3ef3b58c11
--- /dev/null
+++ b/chrome/browser/android/offline_pages/background_loader_offliner.cc
@@ -0,0 +1,148 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/offline_pages/background_loader_offliner.h"
+
+#include "base/sys_info.h"
+#include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
+#include "components/offline_pages/core/background/save_page_request.h"
+#include "components/offline_pages/core/offline_page_model.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/web_contents.h"
+
+namespace offline_pages {
+
+BackgroundLoaderOffliner::BackgroundLoaderOffliner(
+ content::BrowserContext* browser_context,
+ const OfflinerPolicy* policy,
+ OfflinePageModel* offline_page_model)
+ : browser_context_(browser_context),
+ offline_page_model_(offline_page_model),
+ is_low_end_device_(base::SysInfo::IsLowEndDevice()),
+ save_state_(NONE),
+ weak_ptr_factory_(this) {
+ DCHECK(offline_page_model_);
+ DCHECK(browser_context_);
+}
+
+BackgroundLoaderOffliner::~BackgroundLoaderOffliner() {}
+
+bool BackgroundLoaderOffliner::LoadAndSave(const SavePageRequest& request,
+ const CompletionCallback& callback) {
+ DCHECK(callback);
+
+ if (pending_request_) {
+ DVLOG(1) << "Already have pending request";
+ return false;
+ }
+
+ if (!OfflinePageModel::CanSaveURL(request.url())) {
+ DVLOG(1) << "Not able to save page for requested url: " << request.url();
+ return false;
+ }
+
+ if (!loader_)
+ ResetState();
+
+ // Track copy of pending request.
+ pending_request_.reset(new SavePageRequest(request));
+ completion_callback_ = callback;
+
+ // Listen for app foreground/background change.
+ app_listener_.reset(new base::android::ApplicationStatusListener(
+ base::Bind(&BackgroundLoaderOffliner::OnApplicationStateChange,
+ weak_ptr_factory_.GetWeakPtr())));
+
+ loader_.get()->LoadPage(request.url());
+
+ return true;
+}
+
+void BackgroundLoaderOffliner::Cancel() {
+ // TODO(chili): We are not able to cancel a pending
+ // OfflinePageModel::SavePage() operation. We just ignore the callback.
+ if (!pending_request_)
+ return;
+
+ if (save_state_ != NONE) {
+ save_state_ = DELETE_AFTER_SAVE;
+ return;
+ }
+
+ ResetState();
+}
+
+void BackgroundLoaderOffliner::DidStopLoading() {
+ if (!pending_request_.get()) {
+ DVLOG(1) << "DidStopLoading called even though no pending request.";
+ return;
+ }
+
+ save_state_ = SAVING;
+ SavePageRequest request(*pending_request_.get());
+ content::WebContents* web_contents(
+ content::WebContentsObserver::web_contents());
+
+ std::unique_ptr<OfflinePageArchiver> archiver(
+ new OfflinePageMHTMLArchiver(web_contents));
+
+ OfflinePageModel::SavePageParams params;
+ params.url = web_contents->GetLastCommittedURL();
+ params.client_id = request.client_id();
+ params.proposed_offline_id = request.request_id();
+ offline_page_model_->SavePage(
+ params, std::move(archiver),
+ base::Bind(&BackgroundLoaderOffliner::OnPageSaved,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BackgroundLoaderOffliner::OnPageSaved(SavePageResult save_result,
+ int64_t offline_id) {
+ if (!pending_request_)
+ return;
+
+ SavePageRequest request(*pending_request_.get());
+ ResetState();
+
+ if (save_state_ == DELETE_AFTER_SAVE) {
+ save_state_ = NONE;
+ return;
+ }
+
+ save_state_ = NONE;
+
+ Offliner::RequestStatus save_status;
+ if (save_result == SavePageResult::SUCCESS)
+ save_status = RequestStatus::SAVED;
+ else
+ save_status = RequestStatus::SAVE_FAILED;
+
+ completion_callback_.Run(request, save_status);
+}
+
+void BackgroundLoaderOffliner::ResetState() {
+ pending_request_.reset();
+ // TODO(chili): Remove after RequestCoordinator can handle multiple offliners.
+ // We reset the loader and observer after completion so loaders
+ // will not be re-used across different requests/tries. This is a temporary
+ // solution while there exists assumptions about the number of offliners
+ // there are.
+ loader_.reset(
+ new background_loader::BackgroundLoaderContents(browser_context_));
+ content::WebContentsObserver::Observe(loader_.get()->web_contents());
+}
+
+void BackgroundLoaderOffliner::OnApplicationStateChange(
+ base::android::ApplicationState application_state) {
+ if (pending_request_ && is_low_end_device_ &&
+ application_state ==
+ base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES) {
+ DVLOG(1) << "App became active, canceling current offlining request";
+ SavePageRequest* request = pending_request_.get();
+ Cancel();
+ completion_callback_.Run(*request, RequestStatus::FOREGROUND_CANCELED);
+ }
+}
+
+} // namespace offline_pages

Powered by Google App Engine
This is Rietveld 408576698