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 @@ ...@@ -6,10 +6,7 @@
#include <vector> #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/profiles/profile.h"
#include "chrome/browser/ui/ash/holding_space/holding_space_util.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
namespace ash { namespace ash {
...@@ -18,22 +15,6 @@ namespace { ...@@ -18,22 +15,6 @@ namespace {
content::DownloadManager* download_manager_for_testing = nullptr; 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 } // namespace
// HoldingSpaceDownloadsDelegate ----------------------------------------------- // HoldingSpaceDownloadsDelegate -----------------------------------------------
...@@ -41,11 +22,9 @@ bool IsRecentEnough(Profile* profile, const download::DownloadItem* download) { ...@@ -41,11 +22,9 @@ bool IsRecentEnough(Profile* profile, const download::DownloadItem* download) {
HoldingSpaceDownloadsDelegate::HoldingSpaceDownloadsDelegate( HoldingSpaceDownloadsDelegate::HoldingSpaceDownloadsDelegate(
Profile* profile, Profile* profile,
HoldingSpaceModel* model, HoldingSpaceModel* model,
ItemDownloadedCallback item_downloaded_callback, ItemDownloadedCallback item_downloaded_callback)
DownloadsRestoredCallback downloads_restored_callback)
: HoldingSpaceKeyedServiceDelegate(profile, model), : HoldingSpaceKeyedServiceDelegate(profile, model),
item_downloaded_callback_(item_downloaded_callback), item_downloaded_callback_(item_downloaded_callback) {}
downloads_restored_callback_(std::move(downloads_restored_callback)) {}
HoldingSpaceDownloadsDelegate::~HoldingSpaceDownloadsDelegate() = default; HoldingSpaceDownloadsDelegate::~HoldingSpaceDownloadsDelegate() = default;
...@@ -90,37 +69,18 @@ void HoldingSpaceDownloadsDelegate::OnManagerInitialized() { ...@@ -90,37 +69,18 @@ void HoldingSpaceDownloadsDelegate::OnManagerInitialized() {
download::SimpleDownloadManager::DownloadVector downloads; download::SimpleDownloadManager::DownloadVector downloads;
download_manager->GetAllDownloads(&downloads); download_manager->GetAllDownloads(&downloads);
std::vector<base::FilePath> file_paths;
for (auto* download : downloads) { for (auto* download : downloads) {
switch (download->GetState()) { switch (download->GetState()) {
case download::DownloadItem::COMPLETE:
if (IsRecentEnough(profile(), download))
file_paths.push_back(download->GetFullPath());
break;
case download::DownloadItem::IN_PROGRESS: case download::DownloadItem::IN_PROGRESS:
download_item_observer_.Add(download); download_item_observer_.Add(download);
break; break;
case download::DownloadItem::COMPLETE:
case download::DownloadItem::CANCELLED: case download::DownloadItem::CANCELLED:
case download::DownloadItem::INTERRUPTED: case download::DownloadItem::INTERRUPTED:
case download::DownloadItem::MAX_DOWNLOAD_STATE: case download::DownloadItem::MAX_DOWNLOAD_STATE:
break; 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( void HoldingSpaceDownloadsDelegate::ManagerGoingDown(
......
...@@ -30,14 +30,10 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate, ...@@ -30,14 +30,10 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate,
using ItemDownloadedCallback = using ItemDownloadedCallback =
base::RepeatingCallback<void(const base::FilePath&)>; base::RepeatingCallback<void(const base::FilePath&)>;
// Callback to invoke when all downloads have been restored to holding space.
using DownloadsRestoredCallback = base::OnceClosure;
HoldingSpaceDownloadsDelegate( HoldingSpaceDownloadsDelegate(
Profile* profile, Profile* profile,
HoldingSpaceModel* model, HoldingSpaceModel* model,
ItemDownloadedCallback item_downloaded_callback, ItemDownloadedCallback item_downloaded_callback);
DownloadsRestoredCallback downloads_restored_callback);
HoldingSpaceDownloadsDelegate(const HoldingSpaceDownloadsDelegate&) = delete; HoldingSpaceDownloadsDelegate(const HoldingSpaceDownloadsDelegate&) = delete;
HoldingSpaceDownloadsDelegate& operator=( HoldingSpaceDownloadsDelegate& operator=(
const HoldingSpaceDownloadsDelegate&) = delete; const HoldingSpaceDownloadsDelegate&) = delete;
...@@ -72,9 +68,6 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate, ...@@ -72,9 +68,6 @@ class HoldingSpaceDownloadsDelegate : public HoldingSpaceKeyedServiceDelegate,
// Callback to invoke when a download is completed. // Callback to invoke when a download is completed.
ItemDownloadedCallback item_downloaded_callback_; 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> ScopedObserver<content::DownloadManager, content::DownloadManager::Observer>
download_manager_observer_{this}; download_manager_observer_{this};
......
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
#include "ash/public/cpp/holding_space/holding_space_item.h" #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_metrics.h"
#include "ash/public/cpp/holding_space/holding_space_prefs.h" #include "ash/public/cpp/holding_space/holding_space_prefs.h"
#include "base/barrier_closure.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/guid.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_manager/app_id.h"
#include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
...@@ -62,14 +60,6 @@ HoldingSpaceKeyedService::HoldingSpaceKeyedService(Profile* profile, ...@@ -62,14 +60,6 @@ HoldingSpaceKeyedService::HoldingSpaceKeyedService(Profile* profile,
// the first time that holding space became available, this will no-op. // the first time that holding space became available, this will no-op.
holding_space_prefs::MarkTimeOfFirstAvailability(profile_->GetPrefs()); 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 // The associated profile may not be ready yet. If it is, we can immediately
// proceed with profile dependent initialization. // proceed with profile dependent initialization.
ProfileManager* const profile_manager = GetProfileManager(); ProfileManager* const profile_manager = GetProfileManager();
...@@ -205,10 +195,7 @@ void HoldingSpaceKeyedService::OnProfileReady() { ...@@ -205,10 +195,7 @@ void HoldingSpaceKeyedService::OnProfileReady() {
profile_, &holding_space_model_, profile_, &holding_space_model_,
/*item_downloaded_callback=*/ /*item_downloaded_callback=*/
base::BindRepeating(&HoldingSpaceKeyedService::AddDownload, base::BindRepeating(&HoldingSpaceKeyedService::AddDownload,
weak_factory_.GetWeakPtr()), weak_factory_.GetWeakPtr())));
/*downloads_restored_callback=*/
base::BindOnce(&HoldingSpaceKeyedService::OnDownloadsRestored,
weak_factory_.GetWeakPtr())));
// The `HoldingSpaceFileSystemDelegate` monitors the file system for changes. // The `HoldingSpaceFileSystemDelegate` monitors the file system for changes.
delegates_.push_back(std::make_unique<HoldingSpaceFileSystemDelegate>( delegates_.push_back(std::make_unique<HoldingSpaceFileSystemDelegate>(
...@@ -243,19 +230,10 @@ void HoldingSpaceKeyedService::OnFileRemoved(const base::FilePath& file_path) { ...@@ -243,19 +230,10 @@ void HoldingSpaceKeyedService::OnFileRemoved(const base::FilePath& file_path) {
std::cref(file_path))); std::cref(file_path)));
} }
void HoldingSpaceKeyedService::OnDownloadsRestored() {
for (auto& delegate : delegates_)
delegate->NotifyDownloadsRestored();
on_model_partially_restored_callback_.Run();
}
void HoldingSpaceKeyedService::OnPersistenceRestored() { void HoldingSpaceKeyedService::OnPersistenceRestored() {
for (auto& delegate : delegates_) for (auto& delegate : delegates_)
delegate->NotifyPersistenceRestored(); delegate->NotifyPersistenceRestored();
on_model_partially_restored_callback_.Run();
}
void HoldingSpaceKeyedService::OnModelFullyRestored() {
HoldingSpaceController::Get()->RegisterClientAndModelForUser( HoldingSpaceController::Get()->RegisterClientAndModelForUser(
account_id_, &holding_space_client_, &holding_space_model_); account_id_, &holding_space_client_, &holding_space_model_);
} }
......
...@@ -102,16 +102,9 @@ class HoldingSpaceKeyedService : public KeyedService, ...@@ -102,16 +102,9 @@ class HoldingSpaceKeyedService : public KeyedService,
// Invoked when the specified `file_path` is removed. // Invoked when the specified `file_path` is removed.
void OnFileRemoved(const base::FilePath& file_path); 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. // Invoked when holding space persistence has been restored.
void OnPersistenceRestored(); 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_; Profile* const profile_;
const AccountId account_id_; const AccountId account_id_;
...@@ -125,12 +118,6 @@ class HoldingSpaceKeyedService : public KeyedService, ...@@ -125,12 +118,6 @@ class HoldingSpaceKeyedService : public KeyedService,
// service. They operate autonomously of one another. // service. They operate autonomously of one another.
std::vector<std::unique_ptr<HoldingSpaceKeyedServiceDelegate>> delegates_; 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> ScopedObserver<ProfileManager, ProfileManagerObserver>
profile_manager_observer_{this}; profile_manager_observer_{this};
......
...@@ -21,12 +21,6 @@ HoldingSpaceKeyedServiceDelegate::~HoldingSpaceKeyedServiceDelegate() = default; ...@@ -21,12 +21,6 @@ HoldingSpaceKeyedServiceDelegate::~HoldingSpaceKeyedServiceDelegate() = default;
void HoldingSpaceKeyedServiceDelegate::Shutdown() {} void HoldingSpaceKeyedServiceDelegate::Shutdown() {}
void HoldingSpaceKeyedServiceDelegate::NotifyDownloadsRestored() {
DCHECK(is_restoring_downloads_);
is_restoring_downloads_ = false;
OnDownloadsRestored();
}
void HoldingSpaceKeyedServiceDelegate::NotifyPersistenceRestored() { void HoldingSpaceKeyedServiceDelegate::NotifyPersistenceRestored() {
DCHECK(is_restoring_persistence_); DCHECK(is_restoring_persistence_);
is_restoring_persistence_ = false; is_restoring_persistence_ = false;
...@@ -48,8 +42,6 @@ void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemAdded( ...@@ -48,8 +42,6 @@ void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemAdded(
void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemRemoved( void HoldingSpaceKeyedServiceDelegate::OnHoldingSpaceItemRemoved(
const HoldingSpaceItem* item) {} const HoldingSpaceItem* item) {}
void HoldingSpaceKeyedServiceDelegate::OnDownloadsRestored() {}
void HoldingSpaceKeyedServiceDelegate::OnPersistenceRestored() {} void HoldingSpaceKeyedServiceDelegate::OnPersistenceRestored() {}
} // namespace ash } // namespace ash
...@@ -29,10 +29,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver { ...@@ -29,10 +29,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
// Delegates should perform any necessary clean up. // Delegates should perform any necessary clean up.
virtual void Shutdown(); 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 // Invoked by `HoldingSpaceKeyedService` to notify delegates when holding
// space persistence has been restored. // space persistence has been restored.
void NotifyPersistenceRestored(); void NotifyPersistenceRestored();
...@@ -46,9 +42,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver { ...@@ -46,9 +42,6 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
// Returns the holding space model owned by `HoldingSpaceKeyedService`. // Returns the holding space model owned by `HoldingSpaceKeyedService`.
const HoldingSpaceModel* model() const { return model_; } 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. // Returns if persistence is being restored.
bool is_restoring_persistence() const { return is_restoring_persistence_; } bool is_restoring_persistence() const { return is_restoring_persistence_; }
...@@ -57,18 +50,12 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver { ...@@ -57,18 +50,12 @@ class HoldingSpaceKeyedServiceDelegate : public HoldingSpaceModelObserver {
void OnHoldingSpaceItemAdded(const HoldingSpaceItem* item) override; void OnHoldingSpaceItemAdded(const HoldingSpaceItem* item) override;
void OnHoldingSpaceItemRemoved(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. // Invoked when holding space persistence has been restored.
virtual void OnPersistenceRestored(); virtual void OnPersistenceRestored();
Profile* const profile_; Profile* const profile_;
const HoldingSpaceModel* const model_; const HoldingSpaceModel* const model_;
// If downloads are being restored.
bool is_restoring_downloads_ = true;
// If persistence is being restored. // If persistence is being restored.
bool is_restoring_persistence_ = true; bool is_restoring_persistence_ = true;
......
...@@ -49,10 +49,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemAdded( ...@@ -49,10 +49,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemAdded(
if (is_restoring_persistence()) if (is_restoring_persistence())
return; 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. // Write the new |item| to persistent storage.
ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath); ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath);
update->Append(item->Serialize()); update->Append(item->Serialize());
...@@ -63,10 +59,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemRemoved( ...@@ -63,10 +59,6 @@ void HoldingSpacePersistenceDelegate::OnHoldingSpaceItemRemoved(
if (is_restoring_persistence()) if (is_restoring_persistence())
return; return;
// `kDownload` type holding space items have their own persistence mechanism.
if (item->type() == HoldingSpaceItem::Type::kDownload)
return;
// Remove the |item| from persistent storage. // Remove the |item| from persistent storage.
ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath); ListPrefUpdate update(profile()->GetPrefs(), kPersistencePath);
update->EraseListValueIf([&item](const base::Value& persisted_item) { 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