#include "google_apis/gcm/engine/gcm_store_impl.h"
#include <string_view>
#include <utility>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/scoped_thread_priority.h"
#include "base/time/time.h"
#include "google_apis/gcm/base/encryptor.h"
#include "google_apis/gcm/base/gcm_constants.h"
#include "google_apis/gcm/base/gcm_features.h"
#include "google_apis/gcm/base/mcs_message.h"
#include "google_apis/gcm/base/mcs_util.h"
#include "google_apis/gcm/protocol/mcs.pb.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/leveldb_chrome.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace gcm {
namespace {
enum LoadStatus { … };
const int kMessagesPerAppLimit = …;
constexpr char kIncomingMsgSeparator[] = …;
const char kDeviceAIDKey[] = …;
const char kDeviceTokenKey[] = …;
const char kRegistrationKeyStart[] = …;
const char kRegistrationKeyEnd[] = …;
const char kIncomingMsgKeyStart[] = …;
const char kIncomingMsgKeyEnd[] = …;
const char kOutgoingMsgKeyStart[] = …;
const char kOutgoingMsgKeyEnd[] = …;
const char kGServiceSettingKeyStart[] = …;
const char kGServiceSettingKeyEnd[] = …;
const char kGServiceSettingsDigestKey[] = …;
const char kLastCheckinAccountsKey[] = …;
const char kLastCheckinTimeKey[] = …;
const char kAccountKeyStart[] = …;
const char kAccountKeyEnd[] = …;
const char kHeartbeatKeyStart[] = …;
const char kHeartbeatKeyEnd[] = …;
const char kLastTokenFetchTimeKey[] = …;
const char kInstanceIDKeyStart[] = …;
const char kInstanceIDKeyEnd[] = …;
std::string MakeRegistrationKey(const std::string& app_id) { … }
std::string ParseRegistrationKey(const std::string& key) { … }
std::string MakeIncomingKey(const std::string& persistent_id) { … }
std::string MakeIncomingData(const std::string& persistent_id) { … }
std::string MakeOutgoingKey(const std::string& persistent_id) { … }
std::string ParseOutgoingKey(const std::string& key) { … }
std::string MakeGServiceSettingKey(const std::string& setting_name) { … }
std::string ParseGServiceSettingKey(const std::string& key) { … }
std::string MakeAccountKey(const CoreAccountId& account_id) { … }
CoreAccountId ParseAccountKey(const std::string& key) { … }
std::string MakeHeartbeatKey(const std::string& scope) { … }
std::string ParseHeartbeatKey(const std::string& key) { … }
std::string MakeInstanceIDKey(const std::string& app_id) { … }
std::string ParseInstanceIDKey(const std::string& key) { … }
leveldb::Slice MakeSlice(std::string_view s) { … }
}
class GCMStoreImpl::Backend
: public base::RefCountedThreadSafe<GCMStoreImpl::Backend> { … };
GCMStoreImpl::Backend::Backend(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> foreground_task_runner,
std::unique_ptr<Encryptor> encryptor)
: … { … }
GCMStoreImpl::Backend::~Backend() { … }
LoadStatus GCMStoreImpl::Backend::OpenStoreAndLoadData(StoreOpenMode open_mode,
LoadResult* result) { … }
void GCMStoreImpl::Backend::Load(StoreOpenMode open_mode,
LoadCallback callback) { … }
void GCMStoreImpl::Backend::Close() { … }
void GCMStoreImpl::Backend::Destroy(UpdateCallback callback) { … }
void GCMStoreImpl::Backend::SetDeviceCredentials(uint64_t device_android_id,
uint64_t device_security_token,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddRegistration(const std::string& serialized_key,
const std::string& serialized_value,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveRegistration(
const std::string& serialized_key,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddIncomingMessage(const std::string& persistent_id,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveIncomingMessages(
const PersistentIdList& persistent_ids,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddOutgoingMessage(const std::string& persistent_id,
const MCSMessage& message,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveOutgoingMessages(
const PersistentIdList& persistent_ids,
base::OnceCallback<void(bool, const AppIdToMessageCountMap&)> callback) { … }
void GCMStoreImpl::Backend::SetLastCheckinInfo(
const base::Time& time,
const std::set<std::string>& accounts,
UpdateCallback callback) { … }
void GCMStoreImpl::AddInstanceIDData(const std::string& app_id,
const std::string& instance_id_data,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveInstanceIDData(const std::string& app_id,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::SetGServicesSettings(
const std::map<std::string, std::string>& settings,
const std::string& settings_digest,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddAccountMapping(
const AccountMapping& account_mapping,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveAccountMapping(
const CoreAccountId& account_id,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::SetLastTokenFetchTime(const base::Time& time,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddHeartbeatInterval(const std::string& scope,
int interval_ms,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveHeartbeatInterval(const std::string& scope,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::AddInstanceIDData(
const std::string& app_id,
const std::string& instance_id_data,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::RemoveInstanceIDData(const std::string& app_id,
UpdateCallback callback) { … }
void GCMStoreImpl::Backend::SetValue(const std::string& key,
const std::string& value,
UpdateCallback callback) { … }
bool GCMStoreImpl::Backend::LoadDeviceCredentials(uint64_t* android_id,
uint64_t* security_token) { … }
bool GCMStoreImpl::Backend::LoadRegistrations(
std::map<std::string, std::string>* registrations) { … }
bool GCMStoreImpl::Backend::LoadIncomingMessages(
std::vector<std::string>* incoming_messages) { … }
bool GCMStoreImpl::Backend::LoadOutgoingMessages(
OutgoingMessageMap* outgoing_messages) { … }
bool GCMStoreImpl::Backend::LoadLastCheckinInfo(
base::Time* last_checkin_time,
std::set<std::string>* accounts) { … }
bool GCMStoreImpl::Backend::LoadGServicesSettings(
std::map<std::string, std::string>* settings,
std::string* digest) { … }
bool GCMStoreImpl::Backend::LoadAccountMappingInfo(
AccountMappings* account_mappings) { … }
bool GCMStoreImpl::Backend::LoadLastTokenFetchTime(
base::Time* last_token_fetch_time) { … }
bool GCMStoreImpl::Backend::LoadHeartbeatIntervals(
std::map<std::string, int>* heartbeat_intervals) { … }
bool GCMStoreImpl::Backend::LoadInstanceIDData(
std::map<std::string, std::string>* instance_id_data) { … }
GCMStoreImpl::GCMStoreImpl(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
std::unique_ptr<Encryptor> encryptor)
: … { … }
GCMStoreImpl::~GCMStoreImpl() { … }
void GCMStoreImpl::Load(StoreOpenMode open_mode, LoadCallback callback) { … }
void GCMStoreImpl::Close() { … }
void GCMStoreImpl::Destroy(UpdateCallback callback) { … }
void GCMStoreImpl::SetDeviceCredentials(uint64_t device_android_id,
uint64_t device_security_token,
UpdateCallback callback) { … }
void GCMStoreImpl::AddRegistration(const std::string& serialized_key,
const std::string& serialized_value,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveRegistration(const std::string& app_id,
UpdateCallback callback) { … }
void GCMStoreImpl::AddIncomingMessage(const std::string& persistent_id,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveIncomingMessage(const std::string& persistent_id,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveIncomingMessages(
const PersistentIdList& persistent_ids,
UpdateCallback callback) { … }
bool GCMStoreImpl::AddOutgoingMessage(const std::string& persistent_id,
const MCSMessage& message,
UpdateCallback callback) { … }
void GCMStoreImpl::OverwriteOutgoingMessage(const std::string& persistent_id,
const MCSMessage& message,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveOutgoingMessage(const std::string& persistent_id,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveOutgoingMessages(
const PersistentIdList& persistent_ids,
UpdateCallback callback) { … }
void GCMStoreImpl::SetLastCheckinInfo(const base::Time& time,
const std::set<std::string>& accounts,
UpdateCallback callback) { … }
void GCMStoreImpl::SetGServicesSettings(
const std::map<std::string, std::string>& settings,
const std::string& digest,
UpdateCallback callback) { … }
void GCMStoreImpl::AddAccountMapping(const AccountMapping& account_mapping,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveAccountMapping(const CoreAccountId& account_id,
UpdateCallback callback) { … }
void GCMStoreImpl::SetLastTokenFetchTime(const base::Time& time,
UpdateCallback callback) { … }
void GCMStoreImpl::AddHeartbeatInterval(const std::string& scope,
int interval_ms,
UpdateCallback callback) { … }
void GCMStoreImpl::RemoveHeartbeatInterval(const std::string& scope,
UpdateCallback callback) { … }
void GCMStoreImpl::SetValueForTesting(const std::string& key,
const std::string& value,
UpdateCallback callback) { … }
void GCMStoreImpl::LoadContinuation(LoadCallback callback,
std::unique_ptr<LoadResult> result) { … }
void GCMStoreImpl::AddOutgoingMessageContinuation(UpdateCallback callback,
const std::string& app_id,
bool success) { … }
void GCMStoreImpl::RemoveOutgoingMessagesContinuation(
UpdateCallback callback,
bool success,
const AppIdToMessageCountMap& removed_message_counts) { … }
}