blob: a3dfece1944530895f499bac4c3640a0275811ba [file] [log] [blame]
// Copyright 2015 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/password_manager/password_store_proxy_mac.h"
#include "base/metrics/histogram_macros.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "content/public/browser/browser_thread.h"
using password_manager::MigrationStatus;
PasswordStoreProxyMac::PasswordStoreProxyMac(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
std::unique_ptr<password_manager::LoginDatabase> login_db,
PrefService* prefs)
: PasswordStoreDefault(main_thread_runner, nullptr, std::move(login_db)) {
migration_status_.Init(password_manager::prefs::kKeychainMigrationStatus,
prefs);
}
bool PasswordStoreProxyMac::Init(
const syncer::SyncableService::StartSyncFlare& flare,
PrefService* prefs) {
// Set up a background thread.
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
if (!thread_->Start()) {
thread_.reset();
return false;
}
if (PasswordStoreDefault::Init(flare, prefs)) {
return ScheduleTask(
base::Bind(&PasswordStoreProxyMac::InitOnBackgroundThread, this,
static_cast<MigrationStatus>(migration_status_.GetValue())));
}
return false;
}
void PasswordStoreProxyMac::ShutdownOnUIThread() {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
PasswordStoreDefault::ShutdownOnUIThread();
thread_->Stop();
// Unsubscribe the observer, otherwise it's too late in the destructor.
migration_status_.Destroy();
}
scoped_refptr<base::SingleThreadTaskRunner>
PasswordStoreProxyMac::GetBackgroundTaskRunner() {
return thread_ ? thread_->task_runner() : nullptr;
}
PasswordStoreProxyMac::~PasswordStoreProxyMac() = default;
void PasswordStoreProxyMac::InitOnBackgroundThread(MigrationStatus status) {
DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread());
if (login_db() && (status == MigrationStatus::NOT_STARTED ||
status == MigrationStatus::FAILED_ONCE ||
status == MigrationStatus::FAILED_TWICE)) {
// Migration isn't possible due to Chrome changing the certificate. Just
// drop the entries in the DB because they don't have passwords anyway.
login_db()->RemoveLoginsCreatedBetween(base::Time(), base::Time());
status = MigrationStatus::MIGRATION_STOPPED;
main_thread_runner_->PostTask(
FROM_HERE,
base::Bind(&PasswordStoreProxyMac::UpdateStatusPref, this, status));
}
UMA_HISTOGRAM_ENUMERATION(
"PasswordManager.KeychainMigration.Status", static_cast<int>(status),
static_cast<int>(MigrationStatus::MIGRATION_STATUS_COUNT));
}
void PasswordStoreProxyMac::UpdateStatusPref(MigrationStatus status) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
// The method can be called after ShutdownOnUIThread().
if (migration_status_.prefs())
migration_status_.SetValue(static_cast<int>(status));
}