blob: d47968e35fb96c9bd247821cefa175f91b349e77 [file] [log] [blame]
// Copyright 2019 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/download/deferred_client_wrapper.h"
#include <vector>
#include "base/bind.h"
#include "build/build_config.h"
#include "chrome/browser/android/startup_bridge.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/transition_manager/full_browser_transition_manager.h"
#include "components/download/internal/background_service/stats.h"
#include "components/download/public/background_service/clients.h"
#include "components/download/public/background_service/download_metadata.h"
#include "components/keyed_service/core/simple_factory_key.h"
namespace download {
DeferredClientWrapper::DeferredClientWrapper(DownloadClient client_id,
ClientFactory client_factory,
SimpleFactoryKey* key)
: client_factory_(std::move(client_factory)),
key_(key),
weak_ptr_factory_(this) {
#if defined(OS_ANDROID)
client_id_ = client_id;
full_browser_requested_ = false;
#endif
FullBrowserTransitionManager::Get()->RegisterCallbackOnProfileCreation(
key_, base::BindOnce(&DeferredClientWrapper::InflateClient,
weak_ptr_factory_.GetWeakPtr()));
#if !defined(OS_ANDROID)
// On non-android platforms we can only be running in full browser mode. In
// full browser mode, FullBrowserTransitionManager synchronously calls the
// callback when it is registered.
DCHECK(wrapped_client_);
#endif
}
DeferredClientWrapper::~DeferredClientWrapper() = default;
void DeferredClientWrapper::OnServiceInitialized(
bool state_lost,
const std::vector<DownloadMetaData>& downloads) {
base::OnceClosure callback =
base::BindOnce(&DeferredClientWrapper::ForwardOnServiceInitialized,
weak_ptr_factory_.GetWeakPtr(), state_lost, downloads);
deferred_closures_.push_back(std::move(callback));
bool force_inflate = downloads.size() > 0 || state_lost;
RunDeferredClosures(force_inflate);
}
void DeferredClientWrapper::OnServiceUnavailable() {
base::OnceClosure callback =
base::BindOnce(&DeferredClientWrapper::ForwardOnServiceUnavailable,
weak_ptr_factory_.GetWeakPtr());
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(false /*force_inflate*/);
}
void DeferredClientWrapper::OnDownloadStarted(
const std::string& guid,
const std::vector<GURL>& url_chain,
const scoped_refptr<const net::HttpResponseHeaders>& headers) {
base::OnceClosure callback =
base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadStarted,
weak_ptr_factory_.GetWeakPtr(), guid, url_chain, headers);
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(true /*force_inflate*/);
}
void DeferredClientWrapper::OnDownloadUpdated(const std::string& guid,
uint64_t bytes_uploaded,
uint64_t bytes_downloaded) {
base::OnceClosure callback = base::BindOnce(
&DeferredClientWrapper::ForwardOnDownloadUpdated,
weak_ptr_factory_.GetWeakPtr(), guid, bytes_uploaded, bytes_downloaded);
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(true /*force_inflate*/);
}
void DeferredClientWrapper::OnDownloadFailed(
const std::string& guid,
const download::CompletionInfo& info,
FailureReason reason) {
base::OnceClosure callback =
base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadFailed,
weak_ptr_factory_.GetWeakPtr(), guid, info, reason);
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(true /*force_inflate*/);
}
void DeferredClientWrapper::OnDownloadSucceeded(
const std::string& guid,
const CompletionInfo& completion_info) {
base::OnceClosure callback =
base::BindOnce(&DeferredClientWrapper::ForwardOnDownloadSucceeded,
weak_ptr_factory_.GetWeakPtr(), guid, completion_info);
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(true /*force_inflate*/);
}
bool DeferredClientWrapper::CanServiceRemoveDownloadedFile(
const std::string& guid,
bool force_delete) {
base::OnceClosure callback = base::BindOnce(
&DeferredClientWrapper::ForwardCanServiceRemoveDownloadedFile,
weak_ptr_factory_.GetWeakPtr(), guid, force_delete);
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(force_delete /*force_inflate*/);
return false;
}
void DeferredClientWrapper::GetUploadData(
const std::string& guid,
GetUploadDataCallback upload_callback) {
base::OnceClosure callback = base::BindOnce(
&DeferredClientWrapper::ForwardGetUploadData,
weak_ptr_factory_.GetWeakPtr(), guid, std::move(upload_callback));
deferred_closures_.push_back(std::move(callback));
RunDeferredClosures(true /*force_inflate*/);
}
void DeferredClientWrapper::ForwardOnServiceInitialized(
bool state_lost,
const std::vector<DownloadMetaData>& downloads) {
wrapped_client_->OnServiceInitialized(state_lost, downloads);
}
void DeferredClientWrapper::ForwardOnServiceUnavailable() {
wrapped_client_->OnServiceUnavailable();
}
void DeferredClientWrapper::ForwardOnDownloadStarted(
const std::string& guid,
const std::vector<GURL>& url_chain,
const scoped_refptr<const net::HttpResponseHeaders>& headers) {
wrapped_client_->OnDownloadStarted(guid, url_chain, headers);
}
void DeferredClientWrapper::ForwardOnDownloadUpdated(
const std::string& guid,
uint64_t bytes_uploaded,
uint64_t bytes_downloaded) {
wrapped_client_->OnDownloadUpdated(guid, bytes_uploaded, bytes_downloaded);
}
void DeferredClientWrapper::ForwardOnDownloadFailed(
const std::string& guid,
const download::CompletionInfo& info,
FailureReason reason) {
wrapped_client_->OnDownloadFailed(guid, info, reason);
}
void DeferredClientWrapper::ForwardOnDownloadSucceeded(
const std::string& guid,
const CompletionInfo& completion_info) {
wrapped_client_->OnDownloadSucceeded(guid, completion_info);
}
void DeferredClientWrapper::ForwardCanServiceRemoveDownloadedFile(
const std::string& guid,
bool force_delete) {
wrapped_client_->CanServiceRemoveDownloadedFile(guid, force_delete);
}
void DeferredClientWrapper::ForwardGetUploadData(
const std::string& guid,
GetUploadDataCallback callback) {
wrapped_client_->GetUploadData(guid, std::move(callback));
}
void DeferredClientWrapper::RunDeferredClosures(bool force_inflate) {
if (wrapped_client_) {
DoRunDeferredClosures();
} else if (force_inflate) {
#if defined(OS_ANDROID)
// The constructor registers InflateClient as a callback with
// FullBrowserTransitionManager on Profile creation. We just need to trigger
// loading full browser. Once full browser is loaded and profile is
// created, FullBrowserTransitionManager will call InflateClient.
LaunchFullBrowser();
#else
// For platforms that do not implement reduced mode (i.e. non-android), the
// wrapped client should have been inflated in the constructor.
NOTREACHED();
#endif
}
}
void DeferredClientWrapper::DoRunDeferredClosures() {
DCHECK(wrapped_client_);
for (auto& closure : deferred_closures_) {
std::move(closure).Run();
}
deferred_closures_.clear();
}
void DeferredClientWrapper::InflateClient(Profile* profile) {
DCHECK(profile);
DCHECK(client_factory_);
wrapped_client_ = std::move(client_factory_).Run(profile);
DoRunDeferredClosures();
}
#if defined(OS_ANDROID)
void DeferredClientWrapper::LaunchFullBrowser() {
if (full_browser_requested_)
return;
full_browser_requested_ = true;
stats::LogDownloadClientInflatedFullBrowser(client_id_);
android_startup::LoadFullBrowser();
}
#endif
} // namespace download