blob: e6fbef3f7d357d80ded58bfab4cec7965d8d36fc [file] [log] [blame]
// Copyright 2018 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 "components/autofill/core/browser/legacy_strike_database.h"
#include <string>
#include <utility>
#include <vector>
#include "base/metrics/histogram_functions.h"
#include "base/task/post_task.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/proto/strike_data.pb.h"
#include "components/leveldb_proto/public/proto_database_provider.h"
namespace autofill {
namespace {
const char kLegacyDatabaseClientName[] = "StrikeService";
const char kLegacyDatabaseKeyDeliminator[] = "__";
const char kKeyPrefixForCreditCardSave[] = "creditCardSave";
} // namespace
LegacyStrikeDatabase::LegacyStrikeDatabase(const base::FilePath& database_dir)
: db_(leveldb_proto::ProtoDatabaseProvider::CreateUniqueDB<StrikeData>(
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}))),
weak_ptr_factory_(this) {
db_->Init(kLegacyDatabaseClientName, database_dir,
leveldb_proto::CreateSimpleOptions(),
base::BindRepeating(&LegacyStrikeDatabase::OnDatabaseInit,
weak_ptr_factory_.GetWeakPtr()));
}
LegacyStrikeDatabase::~LegacyStrikeDatabase() {}
void LegacyStrikeDatabase::GetStrikes(const std::string key,
const StrikesCallback& outer_callback) {
GetStrikeData(key, base::BindRepeating(&LegacyStrikeDatabase::OnGetStrikes,
base::Unretained(this),
std::move(outer_callback)));
}
void LegacyStrikeDatabase::AddStrike(const std::string key,
const StrikesCallback& outer_callback) {
GetStrikeData(key, base::BindRepeating(&LegacyStrikeDatabase::OnAddStrike,
base::Unretained(this),
std::move(outer_callback), key));
}
void LegacyStrikeDatabase::ClearAllStrikes(
const ClearStrikesCallback& outer_callback) {
// For deleting all, filter method always returns true.
db_->UpdateEntriesWithRemoveFilter(
std::make_unique<StrikeDataProto::KeyEntryVector>(),
base::BindRepeating([](const std::string& key) { return true; }),
base::BindRepeating(&LegacyStrikeDatabase::OnClearAllStrikes,
base::Unretained(this), outer_callback));
}
void LegacyStrikeDatabase::ClearAllStrikesForKey(
const std::string& key,
const ClearStrikesCallback& outer_callback) {
std::unique_ptr<std::vector<std::string>> keys_to_remove(
new std::vector<std::string>());
keys_to_remove->push_back(key);
db_->UpdateEntries(
/*entries_to_save=*/std::make_unique<
leveldb_proto::ProtoDatabase<StrikeData>::KeyEntryVector>(),
/*keys_to_remove=*/std::move(keys_to_remove),
base::BindRepeating(&LegacyStrikeDatabase::OnClearAllStrikesForKey,
base::Unretained(this), outer_callback));
}
std::string LegacyStrikeDatabase::GetKeyForCreditCardSave(
const std::string& card_last_four_digits) {
return CreateKey(GetKeyPrefixForCreditCardSave(), card_last_four_digits);
}
LegacyStrikeDatabase::LegacyStrikeDatabase()
: db_(nullptr), weak_ptr_factory_(this) {}
void LegacyStrikeDatabase::OnDatabaseInit(bool success) {}
void LegacyStrikeDatabase::GetStrikeData(const std::string key,
const GetValueCallback& callback) {
db_->GetEntry(key, callback);
}
void LegacyStrikeDatabase::SetStrikeData(const std::string& key,
const StrikeData& data,
const SetValueCallback& callback) {
std::unique_ptr<StrikeDataProto::KeyEntryVector> entries(
new StrikeDataProto::KeyEntryVector());
entries->push_back(std::make_pair(key, data));
db_->UpdateEntries(
/*entries_to_save=*/std::move(entries),
/*keys_to_remove=*/std::make_unique<std::vector<std::string>>(),
callback);
}
void LegacyStrikeDatabase::OnGetStrikes(
StrikesCallback callback,
bool success,
std::unique_ptr<StrikeData> strike_data) {
if (success && strike_data)
callback.Run(strike_data->num_strikes());
else
callback.Run(0);
}
void LegacyStrikeDatabase::OnAddStrike(
StrikesCallback callback,
std::string key,
bool success,
std::unique_ptr<StrikeData> strike_data) {
if (!success) {
// Failed to get strike data; abort adding strike.
callback.Run(0);
return;
}
int num_strikes = strike_data ? strike_data->num_strikes() + 1 : 1;
StrikeData data;
data.set_num_strikes(num_strikes);
data.set_last_update_timestamp(
base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
SetStrikeData(
key, data,
base::BindRepeating(&LegacyStrikeDatabase::OnAddStrikeComplete,
base::Unretained(this), callback, num_strikes, key));
}
void LegacyStrikeDatabase::OnAddStrikeComplete(StrikesCallback callback,
int num_strikes,
std::string key,
bool success) {
if (success) {
if (GetPrefixFromKey(key) == kKeyPrefixForCreditCardSave) {
base::UmaHistogramCounts1000(
"Autofill.StrikeDatabase.NthStrikeAdded.CreditCardSave", num_strikes);
}
callback.Run(num_strikes);
} else {
callback.Run(0);
}
}
void LegacyStrikeDatabase::OnClearAllStrikes(ClearStrikesCallback callback,
bool success) {
callback.Run(success);
}
void LegacyStrikeDatabase::OnClearAllStrikesForKey(
ClearStrikesCallback callback,
bool success) {
callback.Run(success);
}
void LegacyStrikeDatabase::LoadKeys(const LoadKeysCallback& callback) {
db_->LoadKeys(callback);
}
std::string LegacyStrikeDatabase::CreateKey(
const std::string& type_prefix,
const std::string& identifier_suffix) {
return type_prefix + kLegacyDatabaseKeyDeliminator + identifier_suffix;
}
std::string LegacyStrikeDatabase::GetKeyPrefixForCreditCardSave() {
return kKeyPrefixForCreditCardSave;
}
std::string LegacyStrikeDatabase::GetPrefixFromKey(const std::string& key) {
return key.substr(0, key.find(kLegacyDatabaseKeyDeliminator));
}
} // namespace autofill