Commit 182706e5 authored by David Black's avatar David Black Committed by Commit Bot

Persist downloads to holding space persistence.

Previously downloads were only persisted by the DownloadManager. Moving
forward, we want to be able to update holding space items when their
backing files are renamed/moved, but this will leave us unable to
restore any renamed/moved downloads unless we persist them ourselves.

Persisting downloads ourselves also greatly simplifies holding space
restoration on start up due to removal of the one-off case for
downloads.

Bug: 1136173
Change-Id: I867a793449f9668f9899c75f057af7a0d35174af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2458387Reviewed-by: default avatarAhmed Mehfooz <amehfooz@chromium.org>
Commit-Queue: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#814898}
parent 9880f3be
......@@ -6,10 +6,7 @@
#include <vector>
#include "ash/public/cpp/holding_space/holding_space_constants.h"
#include "ash/public/cpp/holding_space/holding_space_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/holding_space/holding_space_util.h"
#include "content/public/browser/browser_context.h"
namespace ash {
......@@ -18,22 +15,6 @@ namespace {
content::DownloadManager* download_manager_for_testing = nullptr;
// Helpers ---------------------------------------------------------------------
// Returns true if `download` is sufficiently recent, false otherwise.
bool IsRecentEnough(Profile* profile, const download::DownloadItem* download) {
const base::Time end_time = download->GetEndTime();
// A `download` must be more recent than the time of the holding space feature
// first becoming available.
PrefService* prefs = profile->GetPrefs();
if (end_time < holding_space_prefs::GetTimeOfFirstAvailability(prefs).value())
return false;
// A `download` must be more recent that `kMaxFileAge`.
return end_time >= base::Time::Now() - kMaxFileAge;
}
} // namespace
// HoldingSpaceDownloadsDelegate -----------------------------------------------
......@@ -41,11 +22,9 @@ bool IsRecentEnough(Profile* profile, const download::DownloadItem* download) {
HoldingSpaceDownloadsDelegate::HoldingSpaceDownloadsDelegate(
Profile* profile,
HoldingSpaceModel* model,
ItemDownloadedCallback item_downloaded_callback,
DownloadsRestoredCallback downloads_restored_callback)
ItemDownloadedCallback item_downloaded_callback)
: HoldingSpaceKeyedServiceDelegate(profile, model),
item_downloaded_callback_(item_downloaded_callback),
downloads_restored_callback_(std::move(downloads_restored_callback)) {}
item_downloaded_callback_(item_downloaded_callback) {}
HoldingSpaceDownloadsDelegate::~HoldingSpaceDownloadsDelegate() = default;
......@@ -90,37 +69,18 @@ void HoldingSpaceDownloadsDelegate::OnManagerInitialized() {
download::SimpleDownloadManager::DownloadVector downloads;
download_manager->GetAllDownloads(&downloads);
std::vector<base::FilePath> file_paths;
for (auto* download : downloads) {
switch (download->GetState()) {
case download::DownloadItem::COMPLETE:
if (IsRecentEnough(profile(), download))
file_paths.push_back(download->GetFullPath());
break;
case download::DownloadItem::IN_PROGRESS:
download_item_observer_.Add(download);
break;
case download::DownloadItem::COMPLETE:
case download::DownloadItem::CANCELLED:
case download::DownloadItem::INTERRUPTED:
case download::DownloadItem::MAX_DOWNLOAD_STATE:
break;
}
}
holding_space_util::PartitionFilePathsByExistence(
profile(), file_paths,
base::BindOnce(
[](const base::WeakPtr<HoldingSpaceDownloadsDelegate>& weak_ptr,
std::vector<base::FilePath> existing_file_paths,
std::vector<base::FilePath> non_existing_file_paths) {
if (weak_ptr) {
for (const auto& existing_file_path : existing_file_paths)
weak_ptr->OnDownloadCompleted(existing_file_path);
std::move(weak_ptr->downloads_restored_callback_).Run();
}
},
weak_factory_.GetWeakPtr()));
}
void HoldingSpaceDownloadsDelegate::ManagerGoingDown(
......
......@@ -30,14 +30,10 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate,
using ItemDownloadedCallback =
base::RepeatingCallback<void(const base::FilePath&)>;
// Callback to invoke when all downloads have been restored to holding space.
using DownloadsRestoredCallback = base::OnceClosure;
HoldingSpaceDownloadsDelegate(
Profile* profile,
HoldingSpaceModel* model,
ItemDownloadedCallback item_downloaded_callback,
DownloadsRestoredCallback downloads_restored_callback);
ItemDownloadedCallback item_downloaded_callback);
HoldingSpaceDownloadsDelegate(const HoldingSpaceDownloadsDelegate&) = delete;
HoldingSpaceDownloadsDelegate& operator=(
const HoldingSpaceDownloadsDelegate&) = delete;
......@@ -72,9 +68,6 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate,
// Callback to invoke when a download is completed.
ItemDownloadedCallback item_downloaded_callback_;
// Callback to invoke when all downloads have been restored to holding space.
DownloadsRestoredCallback downloads_restored_callback_;
ScopedObserver<content::DownloadManager, content::DownloadManager::Observer>
download_manager_observer_{this};
......
......@@ -9,9 +9,7 @@
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_metrics.h"
#include "ash/public/cpp/holding_space/holding_space_prefs.h"
#include "base/barrier_closure.h"
#include "base/files/file_path.h"
#include "base/guid.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h"
......@@ -62,14 +60,6 @@ HoldingSpaceKeyedService::HoldingSpaceKeyedService(Profile* profile,
// the first time that holding space became available, this will no-op.
holding_space_prefs::MarkTimeOfFirstAvailability(profile_->GetPrefs());
// Model restoration is a multi-step process, currently consisting of a
// restoration from persistence followed by a restoration of downloads. Once
// all steps have indicated completion, `OnModelFullyRestored()` is invoked.
on_model_partially_restored_callback_ = base::BarrierClosure(
/*number_of_steps_before_fully_restored=*/2,
base::BindOnce(&HoldingSpaceKeyedService::OnModelFullyRestored,
base::Unretained(this)));
// The associated profile may not be ready yet. If it is, we can immediately
// proceed with profile dependent initialization.
ProfileManager* const profile_manager = GetProfileManager();
......@@ -205,10 +195,7 @@ void HoldingSpaceKeyedService::OnProfileReady() {
profile_, &holding_space_model_,
/*item_downloaded_callback=*/
base::BindRepeating(&HoldingSpaceKeyedService::AddDownload,
weak_factory_.GetWeakPtr()),
/*downloads_restored_callback=*/
base::BindOnce(&HoldingSpaceKeyedService::OnDownloadsRestored,
weak_factory_.GetWeakPtr())));
weak_factory_.GetWeakPtr())));
// The `HoldingSpaceFileSystemDelegate` monitors the file system for changes.
delegates_.push_back(std::make_unique<HoldingSpaceFileSystemDelegate>(
......@@ -243,19 +230,10 @@ void HoldingSpaceKeyedService::OnFileRemoved(const base::FilePath& file_path) {
std::cref(file_path)));
}
void HoldingSpaceKeyedService::OnDownloadsRestored() {
for (auto& delegate : delegates_)
delegate->NotifyDownloadsRestored();
on_model_partially_restored_callback_.Run();
}
void HoldingSpaceKeyedService::OnPersistenceRestored() {
for (auto& delegate : delegates_)
delegate->NotifyPersistenceRestored();
on_model_partially_restored_callback_.Run();
}
void HoldingSpaceKeyedService::OnModelFullyRestored() {
HoldingSpaceController::Get()->RegisterClientAndModelForUser(
account_id_, &holding_space_client_, &holding_space_model_);
}
......
......@@ -102,16 +102,9 @@ class HoldingSpaceKeyedService : public KeyedService,
// Invoked when the specified `file_path` is removed.
void OnFileRemoved(const base::FilePath& file_path);
// Invoked when all downloads have been restored to holding space.
void OnDownloadsRestored();
// Invoked when holding space persistence has been restored.
void OnPersistenceRestored();
// Invoked when the holding space model has been fully restored. This includes
// both holding space items restored from persistence as well as downloads.
void OnModelFullyRestored();
Profile* const profile_;
const AccountId account_id_;
......@@ -125,12 +118,6 @@ class HoldingSpaceKeyedService : public KeyedService,
// service. They operate autonomously of one another.
std::vector<std::unique_ptr<HoldingSpaceKeyedServiceDelegate>> delegates_;
// A `base::BarrierClosure` that is run when the holding space model has been
// partially restored. This will occur multiple times, after restoration from
// persistence and after restoration of downloads. Once all restoration steps
// have indicated completion, `OnModelFullyRestored()` is invoked.
base::RepeatingClosure on_model_partially_restored_callback_;
ScopedObserver<ProfileManager, ProfileManagerObserver>
profile_manager_observer_{this};
......
......@@ -21,12 +21,6 @@ HoldingSpaceKeyedServiceDelegate::~HoldingSpaceKeyedServiceDelegate() = default;
void HoldingSpaceKeyedServiceDelegate::Shutdown() {}
void HoldingSpaceKeyedServiceDelegate::NotifyDownloadsRestored() {
DCHECK(is_restoring_downloads_);
is_restoring_downloads_ = false;
OnDownloadsRestored();
}
void HoldingSpaceKeyedServiceDelegate::NotifyPersistenceRestored() {
DCHECK(is_restoring_persistence_);
is_restoring_persistence_ = false;
......@@ -48,8 +42,6 @@ void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemAdded(
void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemRemoved(
const HoldingSpaceItem* item) {}
void HoldingSpaceKeyedServiceDelegate::OnDownloadsRestored() {}
void HoldingSpaceKeyedServiceDelegate::OnPersistenceRestored() {}
} // namespace ash
......@@ -29,10 +29,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
// Delegates should perform any necessary clean up.
virtual void Shutdown();
// Invoked by `HoldingSpaceKeyedService` to notify delegates when all
// downloads have been restored to holding space.
void NotifyDownloadsRestored();
// Invoked by `HoldingSpaceKeyedService` to notify delegates when holding
// space persistence has been restored.
void NotifyPersistenceRestored();
......@@ -46,9 +42,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
// Returns the holding space model owned by `HoldingSpaceKeyedService`.
const HoldingSpaceModel* model() const { return model_; }
// Returns if downloads are being restored.
bool is_restoring_downloads() const { return is_restoring_downloads_; }
// Returns if persistence is being restored.
bool is_restoring_persistence() const { return is_restoring_persistence_; }
......@@ -57,18 +50,12 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
void OnHoldingSpaceItemAdded(const HoldingSpaceItem* item) override;
void OnHoldingSpaceItemRemoved(const HoldingSpaceItem* item) override;
// Invoked when all downloads have been restored to holding space.
virtual void OnDownloadsRestored();
// Invoked when holding space persistence has been restored.
virtual void OnPersistenceRestored();
Profile* const profile_;
const HoldingSpaceModel* const model_;
// If downloads are being restored.
bool is_restoring_downloads_ = true;
// If persistence is being restored.
bool is_restoring_persistence_ = true;
......
......@@ -49,10 +49,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemAdded(
if (is_restoring_persistence())
return;
// `kDownload` type holding space items have their own persistence mechanism.
if (item->type() == HoldingSpaceItem::Type::kDownload)
return;
// Write the new |item| to persistent storage.
ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath);
update->Append(item->Serialize());
......@@ -63,10 +59,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemRemoved(
if (is_restoring_persistence())
return;
// `kDownload` type holding space items have their own persistence mechanism.
if (item->type() == HoldingSpaceItem::Type::kDownload)
return;
// Remove the |item| from persistent storage.
ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath);
update->EraseListValueIf([&item](const base::Value& persisted_item) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment