Commit d752ea96 authored by Kushagra Sinha's avatar Kushagra Sinha Committed by Commit Bot

Allow initializing crOS Account Manager in ephemeral mode

Some tests cannot create a proper task environment for running a real
instance of Chrome OS Account Manager.

Allow the creation and initialization of Chrome OS Account Manager in
ephemeral mode where it will not require a task environment for
initialization.

Bug: 1100833
Test: chromeos_components_unittests --gtest_filter="*AccountManager*Test*"
Change-Id: I181dbde347f91530ded431d4f8a505f9c6c30be8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2283305Reviewed-by: default avatarAnastasiia N <anastasiian@chromium.org>
Commit-Queue: Kush Sinha <sinhak@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790311}
parent f22d241c
......@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_forward.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
......@@ -168,6 +169,16 @@ void AccountManager::SetPrefService(PrefService* pref_service) {
pref_service_ = pref_service;
}
void AccountManager::InitializeInEphemeralMode(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
Initialize(/* home_dir= */ base::FilePath(), url_loader_factory,
/* delay_network_call_runner= */
base::BindRepeating(
[](base::OnceClosure closure) { std::move(closure).Run(); }),
/* task_runner= */ nullptr, /* initialization_callback= */
base::DoNothing());
}
void AccountManager::Initialize(
const base::FilePath& home_dir,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
......@@ -215,19 +226,28 @@ void AccountManager::Initialize(
task_runner_ = task_runner;
base::FilePath tokens_file_path;
if (!home_dir_.empty()) {
if (!IsEphemeralMode()) {
DCHECK(task_runner_);
tokens_file_path = home_dir_.Append(kTokensFileName);
writer_ = std::make_unique<base::ImportantFileWriter>(tokens_file_path,
task_runner_);
}
initialization_callbacks_.emplace_back(std::move(initialization_callback));
PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path),
base::BindOnce(
&AccountManager::InsertAccountsAndRunInitializationCallbacks,
weak_factory_.GetWeakPtr(), initialization_start_time));
if (!IsEphemeralMode()) {
DCHECK(task_runner_);
PostTaskAndReplyWithResult(
task_runner_.get(), FROM_HERE,
base::BindOnce(&AccountManager::LoadAccountsFromDisk, tokens_file_path),
base::BindOnce(
&AccountManager::InsertAccountsAndRunInitializationCallbacks,
weak_factory_.GetWeakPtr(), initialization_start_time));
} else {
// We are running in ephemeral mode. There is nothing to load from disk.
RecordTokenLoadStatus(TokenLoadStatus::kSuccess);
InsertAccountsAndRunInitializationCallbacks(initialization_start_time,
/* accounts= */ AccountMap{});
}
}
// static
......@@ -520,11 +540,12 @@ void AccountManager::UpsertAccountInternal(const AccountKey& account_key,
}
void AccountManager::PersistAccountsAsync() {
if (!writer_) {
if (IsEphemeralMode()) {
return;
}
// Schedule (immediately) a non-blocking write.
DCHECK(writer_);
writer_->WriteNow(std::make_unique<std::string>(GetSerializedAccounts()));
}
......@@ -656,6 +677,10 @@ void AccountManager::DeletePendingTokenRevocationRequest(
}
}
bool AccountManager::IsEphemeralMode() const {
return home_dir_.empty();
}
COMPONENT_EXPORT(ACCOUNT_MANAGER)
std::ostream& operator<<(std::ostream& os,
const AccountManager::AccountKey& account_key) {
......
......@@ -151,6 +151,12 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
DelayNetworkCallRunner delay_network_call_runner,
base::OnceClosure initialization_callback);
// Initializes |AccountManager| for ephemeral / in-memory usage.
// Useful for tests that cannot afford to write to disk and clean up after
// themselves.
void InitializeInEphemeralMode(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
// Returns |true| if |AccountManager| has been fully initialized.
bool IsInitialized() const;
......@@ -356,6 +362,10 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
// Deletes |request| from |pending_token_revocation_requests_|, if present.
void DeletePendingTokenRevocationRequest(GaiaTokenRevocationRequest* request);
// Returns |true| if |AccountManager| is operating in ephemeral / in-memory
// mode, and not persisting anything to disk.
bool IsEphemeralMode() const;
// Status of this object's initialization.
InitializationState init_state_ = InitializationState::kNotStarted;
......@@ -371,13 +381,16 @@ class COMPONENT_EXPORT(ACCOUNT_MANAGER) AccountManager {
PrefService* pref_service_ = nullptr;
// A task runner for disk I/O.
// Will be |nullptr| if |AccountManager| is operating in ephemeral mode.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Writes |AccountManager|'s state to disk. Will be |nullptr| if
// |AccountManager| is operating in-memory only.
// Writes |AccountManager|'s state to disk.
// Will be |nullptr| if |AccountManager| is operating in ephemeral mode.
std::unique_ptr<base::ImportantFileWriter> writer_;
// Cryptohome root.
// Will be |base::FilePath::empty()| if |AccountManager| is operating in
// ephemeral mode.
base::FilePath home_dir_;
// A map from |AccountKey|s to |AccountInfo|.
......
......@@ -151,6 +151,15 @@ class AccountManagerTest : public testing::Test {
std::move(initialization_callback));
}
// |account_manager| is a non-owning pointer.
void InitializeEphemeralAccountManager(AccountManager* account_manager) {
account_manager->InitializeInEphemeralMode(
test_url_loader_factory_.GetSafeWeakWrapper());
account_manager->SetPrefService(&pref_service_);
RunAllPendingTasks();
EXPECT_TRUE(account_manager->IsInitialized());
}
void RunAllPendingTasks() { task_environment_.RunUntilIdle(); }
// Returns an unowned pointer to |AccountManager|.
......@@ -358,6 +367,24 @@ TEST_F(AccountManagerTest, TestTokenTransience) {
EXPECT_EQ(0UL, accounts.size());
}
TEST_F(AccountManagerTest, TestEphemeralMode) {
{
// Create a scoped |AccountManager|.
AccountManager account_manager;
InitializeEphemeralAccountManager(&account_manager);
account_manager.UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken);
RunAllPendingTasks();
}
// Create another |AccountManager|.
AccountManager account_manager;
InitializeEphemeralAccountManager(&account_manager);
std::vector<AccountManager::Account> accounts =
GetAccountsBlocking(&account_manager);
EXPECT_EQ(0UL, accounts.size());
}
TEST_F(AccountManagerTest, TestAccountEmailPersistence) {
account_manager()->UpsertAccount(kGaiaAccountKey, kRawUserEmail, kGaiaToken);
RunAllPendingTasks();
......
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