Commit 894a4599 authored by fgorski@chromium.org's avatar fgorski@chromium.org

[GCM] Adding status to AccountMapping structure

* Renaming AccountInfo to AccountMapping.
* Adding status and timestamp of it's last change
* Removing last message timestamp, as with introduction of
  message ack event, it is no longer needed

BUG=374969
R=zea@chromium.org

Review URL: https://codereview.chromium.org/443573002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287919 0039d316-1c4b-4281-b951-d872f2087c98
parent 1781a2df
...@@ -12,8 +12,8 @@ component("gcm") { ...@@ -12,8 +12,8 @@ component("gcm") {
"base/mcs_util.h", "base/mcs_util.h",
"base/socket_stream.cc", "base/socket_stream.cc",
"base/socket_stream.h", "base/socket_stream.h",
"engine/account_info.cc", "engine/account_mapping.cc",
"engine/account_info.h", "engine/account_mapping.h",
"engine/checkin_request.cc", "engine/checkin_request.cc",
"engine/checkin_request.h", "engine/checkin_request.h",
"engine/connection_factory.cc", "engine/connection_factory.cc",
...@@ -107,7 +107,7 @@ test("gcm_unit_tests") { ...@@ -107,7 +107,7 @@ test("gcm_unit_tests") {
"base/mcs_message_unittest.cc", "base/mcs_message_unittest.cc",
"base/mcs_util_unittest.cc", "base/mcs_util_unittest.cc",
"base/socket_stream_unittest.cc", "base/socket_stream_unittest.cc",
"engine/account_info_unittest.cc", "engine/account_mapping_unittest.cc",
"engine/checkin_request_unittest.cc", "engine/checkin_request_unittest.cc",
"engine/connection_factory_impl_unittest.cc", "engine/connection_factory_impl_unittest.cc",
"engine/connection_handler_impl_unittest.cc", "engine/connection_handler_impl_unittest.cc",
......
// Copyright 2014 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 <string>
#include "google_apis/gcm/engine/account_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace gcm {
namespace {
TEST(AccountInfoTest, SerializeAccountInfo) {
AccountInfo account_info;
account_info.account_id = "acc_id";
account_info.email = "test@example.com";
account_info.last_message_id = "last_message_id_1";
account_info.last_message_type = AccountInfo::MSG_ADD;
account_info.last_message_timestamp = base::Time::FromInternalValue(
1305797421259935LL); // Arbitrary timestamp.
EXPECT_EQ("test@example.com&add&last_message_id_1&1305797421259935",
account_info.SerializeAsString());
account_info.account_id = "acc_id2";
account_info.email = "test@gmail.com";
account_info.last_message_id = "last_message_id_2";
account_info.last_message_type = AccountInfo::MSG_REMOVE;
account_info.last_message_timestamp =
base::Time::FromInternalValue(1305734521259935LL); // Other timestamp.
EXPECT_EQ("test@gmail.com&remove&last_message_id_2&1305734521259935",
account_info.SerializeAsString());
account_info.last_message_type = AccountInfo::MSG_NONE;
EXPECT_EQ("test@gmail.com&none", account_info.SerializeAsString());
}
TEST(AccountInfoTest, DeserializeAccountInfo) {
AccountInfo account_info;
account_info.account_id = "acc_id";
EXPECT_TRUE(account_info.ParseFromString(
"test@example.com&add&last_message_id_1&1305797421259935"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@example.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_ADD, account_info.last_message_type);
EXPECT_EQ("last_message_id_1", account_info.last_message_id);
EXPECT_EQ(base::Time::FromInternalValue(1305797421259935LL),
account_info.last_message_timestamp);
EXPECT_TRUE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id_2&1305734521259935"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@gmail.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_REMOVE, account_info.last_message_type);
EXPECT_EQ("last_message_id_2", account_info.last_message_id);
EXPECT_EQ(base::Time::FromInternalValue(1305734521259935LL),
account_info.last_message_timestamp);
EXPECT_TRUE(account_info.ParseFromString("test@gmail.com&none"));
EXPECT_EQ("acc_id", account_info.account_id);
EXPECT_EQ("test@gmail.com", account_info.email);
EXPECT_EQ(AccountInfo::MSG_NONE, account_info.last_message_type);
EXPECT_EQ("", account_info.last_message_id);
EXPECT_EQ(base::Time(), account_info.last_message_timestamp);
}
TEST(AccountInfoTest, DeserializeAccountInfoInvalidInput) {
AccountInfo account_info;
account_info.account_id = "acc_id";
// Too many agruments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com&add&last_message_id_1&1305797421259935&stuff_here"));
// Too few arguments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com&remove&last_message_id_1"));
// Too few arguments.
EXPECT_FALSE(account_info.ParseFromString(
"test@example.com"));
// Missing email.
EXPECT_FALSE(account_info.ParseFromString(
"&remove&last_message_id_2&1305734521259935"));
// Missing message type.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&&last_message_id_2&1305734521259935"));
// Unkown message type.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&random&last_message_id_2&1305734521259935"));
// Message type is none when message details specified.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&none&last_message_id_2&1305734521259935"));
// Message type is messed up, but we have no message -- that's OK.
EXPECT_TRUE(account_info.ParseFromString(
"test@gmail.com&random"));
// Missing last message ID.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&&1305734521259935"));
// Missing last message timestamp.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id&"));
// Last message timestamp not parseable.
EXPECT_FALSE(account_info.ParseFromString(
"test@gmail.com&remove&last_message_id&asdfjlk"));
}
} // namespace
} // namespace gcm
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "google_apis/gcm/engine/account_info.h" #include "google_apis/gcm/engine/account_mapping.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -13,58 +13,68 @@ namespace { ...@@ -13,58 +13,68 @@ namespace {
const char kSeparator[] = "&"; const char kSeparator[] = "&";
uint32 kEmailIndex = 0; uint32 kEmailIndex = 0;
uint32 kMessageTypeIndex = 1; uint32 kMappingChangeTimestampIndex = 1;
uint32 kMessageIdIndex = 2; uint32 kMessageTypeIndex = 2;
uint32 kMessageTimestampIndex = 3; uint32 kMessageIdIndex = 3;
uint32 kSizeWithNoMessage = kMessageTypeIndex + 1; uint32 kSizeWithNoMessage = kMessageTypeIndex + 1;
uint32 kSizeWithMessage = kMessageTimestampIndex + 1; uint32 kSizeWithMessage = kMessageIdIndex + 1;
std::string MessageTypeToString(AccountInfo::MessageType type) { const char kMessageTypeNoneString[] = "none";
const char kMessageTypeAddString[] = "add";
const char kMessageTypeRemoveString[] = "remove";
std::string MessageTypeToString(AccountMapping::MessageType type) {
switch (type) { switch (type) {
case AccountInfo::MSG_NONE: case AccountMapping::MSG_NONE:
return "none"; return kMessageTypeNoneString;
case AccountInfo::MSG_ADD: case AccountMapping::MSG_ADD:
return "add"; return kMessageTypeAddString;
case AccountInfo::MSG_REMOVE: case AccountMapping::MSG_REMOVE:
return "remove"; return kMessageTypeRemoveString;
default: default:
NOTREACHED(); NOTREACHED();
} }
return ""; return std::string();
} }
AccountInfo::MessageType StringToMessageType(const std::string& type) { bool StringToMessageType(const std::string& type_str,
if (type.compare("add") == 0) AccountMapping::MessageType* type) {
return AccountInfo::MSG_ADD; if (type_str.compare(kMessageTypeAddString) == 0)
if (type.compare("remove") == 0) *type = AccountMapping::MSG_ADD;
return AccountInfo::MSG_REMOVE; else if (type_str.compare(kMessageTypeRemoveString) == 0)
return AccountInfo::MSG_NONE; *type = AccountMapping::MSG_REMOVE;
else if (type_str.compare(kMessageTypeNoneString) == 0)
*type = AccountMapping::MSG_NONE;
else
return false;
return true;
} }
} // namespace } // namespace
AccountInfo::AccountInfo() { AccountMapping::AccountMapping() {
} }
AccountInfo::~AccountInfo() { AccountMapping::~AccountMapping() {
} }
std::string AccountInfo::SerializeAsString() const { std::string AccountMapping::SerializeAsString() const {
std::string value; std::string value;
value.append(email); value.append(email);
value.append(kSeparator); value.append(kSeparator);
value.append(base::Int64ToString(status_change_timestamp.ToInternalValue()));
value.append(kSeparator);
value.append(MessageTypeToString(last_message_type)); value.append(MessageTypeToString(last_message_type));
if (last_message_type != MSG_NONE) { if (last_message_type != MSG_NONE) {
value.append(kSeparator); value.append(kSeparator);
value.append(last_message_id); value.append(last_message_id);
value.append(kSeparator);
value.append(base::Int64ToString(last_message_timestamp.ToInternalValue()));
} }
return value; return value;
} }
bool AccountInfo::ParseFromString(const std::string& value) { bool AccountMapping::ParseFromString(const std::string& value) {
std::vector<std::string> values; std::vector<std::string> values;
Tokenize(value, kSeparator, &values); Tokenize(value, kSeparator, &values);
if (values.size() != kSizeWithNoMessage && if (values.size() != kSizeWithNoMessage &&
...@@ -73,35 +83,48 @@ bool AccountInfo::ParseFromString(const std::string& value) { ...@@ -73,35 +83,48 @@ bool AccountInfo::ParseFromString(const std::string& value) {
} }
if (values[kEmailIndex].empty() || if (values[kEmailIndex].empty() ||
values[kMappingChangeTimestampIndex].empty() ||
values[kMessageTypeIndex].empty()) { values[kMessageTypeIndex].empty()) {
return false; return false;
} }
if (values.size() == kSizeWithMessage && if (values.size() == kSizeWithMessage && values[kMessageIdIndex].empty()) {
(values[kMessageIdIndex].empty() ||
values[kMessageTimestampIndex].empty())) {
return false; return false;
} }
if (values.size() == kSizeWithMessage) { MessageType message_type;
int64 timestamp = 0LL; if (!StringToMessageType(values[kMessageTypeIndex], &message_type))
if (!base::StringToInt64(values[kMessageTimestampIndex], &timestamp))
return false; return false;
MessageType message_type = StringToMessageType(values[kMessageTypeIndex]); if ((message_type == MSG_NONE && values.size() == kSizeWithMessage) ||
if (message_type == MSG_NONE) (message_type != MSG_NONE && values.size() != kSizeWithMessage)) {
return false; return false;
}
last_message_type = message_type; last_message_type = message_type;
int64 status_change_ts_internal = 0LL;
if (!base::StringToInt64(values[kMappingChangeTimestampIndex],
&status_change_ts_internal)) {
return false;
}
if (status_change_ts_internal == 0LL)
status = ADDING;
else if (last_message_type == MSG_REMOVE)
status = REMOVING;
else
status = MAPPED;
if (values.size() == kSizeWithMessage)
last_message_id = values[kMessageIdIndex]; last_message_id = values[kMessageIdIndex];
last_message_timestamp = base::Time::FromInternalValue(timestamp); else
} else {
last_message_type = MSG_NONE;
last_message_id.clear(); last_message_id.clear();
last_message_timestamp = base::Time();
}
email = values[kEmailIndex]; email = values[kEmailIndex];
status_change_timestamp =
base::Time::FromInternalValue(status_change_ts_internal);
access_token.clear();
return true; return true;
} }
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_ #ifndef GOOGLE_APIS_GCM_ENGINE_ACCOUNT_MAPPING_H_
#define GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_ #define GOOGLE_APIS_GCM_ENGINE_ACCOUNT_MAPPING_H_
#include <string> #include <string>
...@@ -13,9 +13,22 @@ ...@@ -13,9 +13,22 @@
namespace gcm { namespace gcm {
// Stores information about Account and a last message sent with the information // Stores information about Account mapping and a last message sent regarding
// about that account. // that mapping.
struct GCM_EXPORT AccountInfo { struct GCM_EXPORT AccountMapping {
// Status of the account mapping.
enum MappingStatus {
NEW, // This is a new account mapping entry.
ADDING, // A mapping message has been sent, but it has not been confirmed
// yet.
MAPPED, // Account is mapped. At least one message has been confirmed to
// reached the GCM.
REMOVING, // Account is removed, but a message removing the mapping has not
// been confirmed yet.
REMOVED, // Account is removed, and at least one message has been
// confirmed to have reached the GCM.
};
// Indicates whether a message, if sent, was adding or removing account // Indicates whether a message, if sent, was adding or removing account
// mapping. // mapping.
enum MessageType { enum MessageType {
...@@ -24,26 +37,32 @@ struct GCM_EXPORT AccountInfo { ...@@ -24,26 +37,32 @@ struct GCM_EXPORT AccountInfo {
MSG_REMOVE, // Account mapping to device was removed by the message. MSG_REMOVE, // Account mapping to device was removed by the message.
}; };
AccountInfo(); AccountMapping();
~AccountInfo(); ~AccountMapping();
// Serializes account info to string without |account_id|. // Serializes account mapping to string without |account_id|, |status| or
// |access_token|.
std::string SerializeAsString() const; std::string SerializeAsString() const;
// Parses account info from store, without |account_id|. // Parses account mapping from store, without |account_id| or |access_token|.
// |status| is infered.
bool ParseFromString(const std::string& value); bool ParseFromString(const std::string& value);
// Gaia ID of the account. // Gaia ID of the account. (Acts as key for persistence.)
std::string account_id; std::string account_id;
// Email address of the tracked account. // Email address of the tracked account.
std::string email; std::string email;
// OAuth2 access token used to authenticate mappings (not persisted).
std::string access_token;
// Status of the account mapping (not persisted).
MappingStatus status;
// Time of the mapping status change.
base::Time status_change_timestamp;
// Type of the last mapping message sent to GCM. // Type of the last mapping message sent to GCM.
MessageType last_message_type; MessageType last_message_type;
// ID of the last mapping message sent to GCM. // ID of the last mapping message sent to GCM.
std::string last_message_id; std::string last_message_id;
// Timestamp of when the last mapping message was sent to GCM.
base::Time last_message_timestamp;
}; };
} // namespace gcm } // namespace gcm
#endif // GOOGLE_APIS_GCM_ENGINE_ACCOUNT_INFO_H_ #endif // GOOGLE_APIS_GCM_ENGINE_ACCOUNT_MAPPING_H_
// Copyright 2014 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 "google_apis/gcm/engine/account_mapping.h"
#include <string>
#include "testing/gtest/include/gtest/gtest.h"
namespace gcm {
namespace {
TEST(AccountMappingTest, SerializeAccountMapping) {
AccountMapping account_mapping;
account_mapping.account_id = "acc_id";
account_mapping.email = "test@example.com";
account_mapping.access_token = "access_token";
account_mapping.status = AccountMapping::ADDING;
account_mapping.status_change_timestamp = base::Time();
account_mapping.last_message_id = "last_message_id_1";
account_mapping.last_message_type = AccountMapping::MSG_ADD;
EXPECT_EQ("test@example.com&0&add&last_message_id_1",
account_mapping.SerializeAsString());
account_mapping.account_id = "acc_id2";
account_mapping.email = "test@gmail.com";
account_mapping.access_token = "access_token"; // should be ignored.
account_mapping.status = AccountMapping::MAPPED; // should be ignored.
account_mapping.status_change_timestamp =
base::Time::FromInternalValue(1305797421259977LL);
account_mapping.last_message_id = "last_message_id_2";
account_mapping.last_message_type = AccountMapping::MSG_REMOVE;
EXPECT_EQ("test@gmail.com&1305797421259977&remove&last_message_id_2",
account_mapping.SerializeAsString());
account_mapping.last_message_type = AccountMapping::MSG_NONE;
EXPECT_EQ("test@gmail.com&1305797421259977&none",
account_mapping.SerializeAsString());
}
TEST(AccountMappingTest, DeserializeAccountMapping) {
AccountMapping account_mapping;
account_mapping.account_id = "acc_id";
EXPECT_TRUE(account_mapping.ParseFromString(
"test@example.com&0&add&last_message_id_1"));
EXPECT_EQ("acc_id", account_mapping.account_id);
EXPECT_EQ("test@example.com", account_mapping.email);
EXPECT_TRUE(account_mapping.access_token.empty());
EXPECT_EQ(AccountMapping::ADDING, account_mapping.status);
EXPECT_EQ(base::Time(), account_mapping.status_change_timestamp);
EXPECT_EQ(AccountMapping::MSG_ADD, account_mapping.last_message_type);
EXPECT_EQ("last_message_id_1", account_mapping.last_message_id);
EXPECT_TRUE(account_mapping.ParseFromString(
"test@gmail.com&1305797421259977&remove&last_message_id_2"));
EXPECT_EQ("acc_id", account_mapping.account_id);
EXPECT_EQ("test@gmail.com", account_mapping.email);
EXPECT_TRUE(account_mapping.access_token.empty());
EXPECT_EQ(AccountMapping::REMOVING, account_mapping.status);
EXPECT_EQ(base::Time::FromInternalValue(1305797421259977LL),
account_mapping.status_change_timestamp);
EXPECT_EQ(AccountMapping::MSG_REMOVE, account_mapping.last_message_type);
EXPECT_EQ("last_message_id_2", account_mapping.last_message_id);
EXPECT_TRUE(account_mapping.ParseFromString(
"test@gmail.com&1305797421259977&none"));
EXPECT_EQ("acc_id", account_mapping.account_id);
EXPECT_EQ("test@gmail.com", account_mapping.email);
EXPECT_TRUE(account_mapping.access_token.empty());
EXPECT_EQ(AccountMapping::MAPPED, account_mapping.status);
EXPECT_EQ(base::Time::FromInternalValue(1305797421259977LL),
account_mapping.status_change_timestamp);
EXPECT_EQ(AccountMapping::MSG_NONE, account_mapping.last_message_type);
EXPECT_EQ("", account_mapping.last_message_id);
}
TEST(AccountMappingTest, DeserializeAccountMappingInvalidInput) {
AccountMapping account_mapping;
account_mapping.account_id = "acc_id";
// Too many agruments.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935"
"&add&last_message_id_1&stuff_here"));
// Too few arguments.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&remove"));
// Too few arguments.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935"));
// Missing email.
EXPECT_FALSE(account_mapping.ParseFromString(
"&1305797421259935&remove&last_message_id_2"));
// Missing mapping status change timestamp.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@gmail.com&&remove&last_message_id_2"));
// Last mapping status change timestamp not parseable.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@gmail.com&remove&asdfjkl&last_message_id_2"));
// Missing message type.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&&last_message_id_2"));
// Unkown message type.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&random&last_message_id_2"));
// Message type is none when message details specified.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&none&last_message_id_2"));
// Message type is messed up.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&random"));
// Missing last message ID.
EXPECT_FALSE(account_mapping.ParseFromString(
"test@example.com&1305797421259935&remove&"));
}
} // namespace
} // namespace gcm
...@@ -24,7 +24,7 @@ void GCMStore::LoadResult::Reset() { ...@@ -24,7 +24,7 @@ void GCMStore::LoadResult::Reset() {
gservices_digest.clear(); gservices_digest.clear();
last_checkin_time = base::Time::FromInternalValue(0LL); last_checkin_time = base::Time::FromInternalValue(0LL);
last_checkin_accounts.clear(); last_checkin_accounts.clear();
account_infos.clear(); account_mappings.clear();
success = false; success = false;
} }
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "google_apis/gcm/base/gcm_export.h" #include "google_apis/gcm/base/gcm_export.h"
#include "google_apis/gcm/engine/account_info.h" #include "google_apis/gcm/engine/account_mapping.h"
#include "google_apis/gcm/engine/registration_info.h" #include "google_apis/gcm/engine/registration_info.h"
namespace gcm { namespace gcm {
...@@ -35,7 +35,7 @@ class GCM_EXPORT GCMStore { ...@@ -35,7 +35,7 @@ class GCM_EXPORT GCMStore {
OutgoingMessageMap; OutgoingMessageMap;
// Map of account id to account info for account mappings. // Map of account id to account info for account mappings.
typedef std::map<std::string, AccountInfo> AccountInfoMap; typedef std::map<std::string, AccountMapping> AccountMappingMap;
// Container for Load(..) results. // Container for Load(..) results.
struct GCM_EXPORT LoadResult { struct GCM_EXPORT LoadResult {
...@@ -54,7 +54,7 @@ class GCM_EXPORT GCMStore { ...@@ -54,7 +54,7 @@ class GCM_EXPORT GCMStore {
std::string gservices_digest; std::string gservices_digest;
base::Time last_checkin_time; base::Time last_checkin_time;
std::set<std::string> last_checkin_accounts; std::set<std::string> last_checkin_accounts;
AccountInfoMap account_infos; AccountMappingMap account_mappings;
}; };
typedef std::vector<std::string> PersistentIdList; typedef std::vector<std::string> PersistentIdList;
...@@ -123,7 +123,7 @@ class GCM_EXPORT GCMStore { ...@@ -123,7 +123,7 @@ class GCM_EXPORT GCMStore {
const UpdateCallback& callback) = 0; const UpdateCallback& callback) = 0;
// Sets the account information related to device to account mapping. // Sets the account information related to device to account mapping.
virtual void AddAccountMapping(const AccountInfo& account_info, virtual void AddAccountMapping(const AccountMapping& account_mapping,
const UpdateCallback& callback) = 0; const UpdateCallback& callback) = 0;
virtual void RemoveAccountMapping(const std::string& account_id, virtual void RemoveAccountMapping(const std::string& account_id,
const UpdateCallback& callback) = 0; const UpdateCallback& callback) = 0;
......
...@@ -162,7 +162,7 @@ class GCMStoreImpl::Backend ...@@ -162,7 +162,7 @@ class GCMStoreImpl::Backend
const std::map<std::string, std::string>& settings, const std::map<std::string, std::string>& settings,
const std::string& digest, const std::string& digest,
const UpdateCallback& callback); const UpdateCallback& callback);
void AddAccountMapping(const AccountInfo& account_info, void AddAccountMapping(const AccountMapping& account_mapping,
const UpdateCallback& callback); const UpdateCallback& callback);
void RemoveAccountMapping(const std::string& account_id, void RemoveAccountMapping(const std::string& account_id,
const UpdateCallback& callback); const UpdateCallback& callback);
...@@ -179,7 +179,7 @@ class GCMStoreImpl::Backend ...@@ -179,7 +179,7 @@ class GCMStoreImpl::Backend
std::set<std::string>* accounts); std::set<std::string>* accounts);
bool LoadGServicesSettings(std::map<std::string, std::string>* settings, bool LoadGServicesSettings(std::map<std::string, std::string>* settings,
std::string* digest); std::string* digest);
bool LoadAccountMappingInfo(AccountInfoMap* account_infos); bool LoadAccountMappingInfo(AccountMappingMap* account_mappings);
const base::FilePath path_; const base::FilePath path_;
scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_; scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
...@@ -234,7 +234,7 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) { ...@@ -234,7 +234,7 @@ void GCMStoreImpl::Backend::Load(const LoadCallback& callback) {
&result->last_checkin_accounts) || &result->last_checkin_accounts) ||
!LoadGServicesSettings(&result->gservices_settings, !LoadGServicesSettings(&result->gservices_settings,
&result->gservices_digest) || &result->gservices_digest) ||
!LoadAccountMappingInfo(&result->account_infos)) { !LoadAccountMappingInfo(&result->account_mappings)) {
result->Reset(); result->Reset();
foreground_task_runner_->PostTask(FROM_HERE, foreground_task_runner_->PostTask(FROM_HERE,
base::Bind(callback, base::Bind(callback,
...@@ -574,10 +574,11 @@ void GCMStoreImpl::Backend::SetGServicesSettings( ...@@ -574,10 +574,11 @@ void GCMStoreImpl::Backend::SetGServicesSettings(
foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok())); foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
} }
void GCMStoreImpl::Backend::AddAccountMapping(const AccountInfo& account_info, void GCMStoreImpl::Backend::AddAccountMapping(
const AccountMapping& account_mapping,
const UpdateCallback& callback) { const UpdateCallback& callback) {
DVLOG(1) << "Saving account info for account with email: " DVLOG(1) << "Saving account info for account with email: "
<< account_info.email; << account_mapping.email;
if (!db_.get()) { if (!db_.get()) {
LOG(ERROR) << "GCMStore db doesn't exist."; LOG(ERROR) << "GCMStore db doesn't exist.";
foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
...@@ -587,8 +588,8 @@ void GCMStoreImpl::Backend::AddAccountMapping(const AccountInfo& account_info, ...@@ -587,8 +588,8 @@ void GCMStoreImpl::Backend::AddAccountMapping(const AccountInfo& account_info,
leveldb::WriteOptions write_options; leveldb::WriteOptions write_options;
write_options.sync = true; write_options.sync = true;
std::string data = account_info.SerializeAsString(); std::string data = account_mapping.SerializeAsString();
std::string key = MakeAccountKey(account_info.account_id); std::string key = MakeAccountKey(account_mapping.account_id);
const leveldb::Status s = const leveldb::Status s =
db_->Put(write_options, MakeSlice(key), MakeSlice(data)); db_->Put(write_options, MakeSlice(key), MakeSlice(data));
if (!s.ok()) if (!s.ok())
...@@ -790,7 +791,7 @@ bool GCMStoreImpl::Backend::LoadGServicesSettings( ...@@ -790,7 +791,7 @@ bool GCMStoreImpl::Backend::LoadGServicesSettings(
} }
bool GCMStoreImpl::Backend::LoadAccountMappingInfo( bool GCMStoreImpl::Backend::LoadAccountMappingInfo(
AccountInfoMap* account_infos) { AccountMappingMap* account_mappings) {
leveldb::ReadOptions read_options; leveldb::ReadOptions read_options;
read_options.verify_checksums = true; read_options.verify_checksums = true;
...@@ -798,15 +799,15 @@ bool GCMStoreImpl::Backend::LoadAccountMappingInfo( ...@@ -798,15 +799,15 @@ bool GCMStoreImpl::Backend::LoadAccountMappingInfo(
for (iter->Seek(MakeSlice(kAccountKeyStart)); for (iter->Seek(MakeSlice(kAccountKeyStart));
iter->Valid() && iter->key().ToString() < kAccountKeyEnd; iter->Valid() && iter->key().ToString() < kAccountKeyEnd;
iter->Next()) { iter->Next()) {
AccountInfo account_info; AccountMapping account_mapping;
account_info.account_id = ParseAccountKey(iter->key().ToString()); account_mapping.account_id = ParseAccountKey(iter->key().ToString());
if (!account_info.ParseFromString(iter->value().ToString())) { if (!account_mapping.ParseFromString(iter->value().ToString())) {
DVLOG(1) << "Failed to parse account info with ID: " DVLOG(1) << "Failed to parse account info with ID: "
<< account_info.account_id; << account_mapping.account_id;
return false; return false;
} }
DVLOG(1) << "Found account mapping with ID: " << account_info.account_id; DVLOG(1) << "Found account mapping with ID: " << account_mapping.account_id;
(*account_infos)[account_info.account_id] = account_info; (*account_mappings)[account_mapping.account_id] = account_mapping;
} }
return true; return true;
...@@ -1011,13 +1012,13 @@ void GCMStoreImpl::SetGServicesSettings( ...@@ -1011,13 +1012,13 @@ void GCMStoreImpl::SetGServicesSettings(
callback)); callback));
} }
void GCMStoreImpl::AddAccountMapping(const AccountInfo& account_info, void GCMStoreImpl::AddAccountMapping(const AccountMapping& account_mapping,
const UpdateCallback& callback) { const UpdateCallback& callback) {
blocking_task_runner_->PostTask( blocking_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&GCMStoreImpl::Backend::AddAccountMapping, base::Bind(&GCMStoreImpl::Backend::AddAccountMapping,
backend_, backend_,
account_info, account_mapping,
callback)); callback));
} }
......
...@@ -88,7 +88,7 @@ class GCM_EXPORT GCMStoreImpl : public GCMStore { ...@@ -88,7 +88,7 @@ class GCM_EXPORT GCMStoreImpl : public GCMStore {
const UpdateCallback& callback) OVERRIDE; const UpdateCallback& callback) OVERRIDE;
// Sets the account information related to device to account mapping. // Sets the account information related to device to account mapping.
virtual void AddAccountMapping(const AccountInfo& account_info, virtual void AddAccountMapping(const AccountMapping& account_mapping,
const UpdateCallback& callback) OVERRIDE; const UpdateCallback& callback) OVERRIDE;
virtual void RemoveAccountMapping(const std::string& account_id, virtual void RemoveAccountMapping(const std::string& account_id,
const UpdateCallback& callback) OVERRIDE; const UpdateCallback& callback) OVERRIDE;
......
...@@ -507,27 +507,31 @@ TEST_F(GCMStoreImplTest, AccountMapping) { ...@@ -507,27 +507,31 @@ TEST_F(GCMStoreImplTest, AccountMapping) {
&GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
// Add account mappings. // Add account mappings.
AccountInfo account_info1; AccountMapping account_mapping1;
account_info1.account_id = "account_id_1"; account_mapping1.account_id = "account_id_1";
account_info1.email = "account_id_1@gmail.com"; account_mapping1.email = "account_id_1@gmail.com";
account_info1.last_message_type = AccountInfo::MSG_ADD; account_mapping1.access_token = "account_token1";
account_info1.last_message_id = "message_1"; account_mapping1.status = AccountMapping::ADDING;
account_info1.last_message_timestamp = account_mapping1.status_change_timestamp = base::Time();
base::Time::FromInternalValue(1305797421259935LL); account_mapping1.last_message_type = AccountMapping::MSG_ADD;
AccountInfo account_info2; account_mapping1.last_message_id = "message_1";
account_info2.account_id = "account_id_2";
account_info2.email = "account_id_2@gmail.com"; AccountMapping account_mapping2;
account_info2.last_message_type = AccountInfo::MSG_REMOVE; account_mapping2.account_id = "account_id_2";
account_info2.last_message_id = "message_2"; account_mapping2.email = "account_id_2@gmail.com";
account_info2.last_message_timestamp = account_mapping2.access_token = "account_token1";
account_mapping2.status = AccountMapping::REMOVING;
account_mapping2.status_change_timestamp =
base::Time::FromInternalValue(1305734521259935LL); base::Time::FromInternalValue(1305734521259935LL);
account_mapping2.last_message_type = AccountMapping::MSG_REMOVE;
account_mapping2.last_message_id = "message_2";
gcm_store->AddAccountMapping( gcm_store->AddAccountMapping(
account_info1, account_mapping1,
base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
PumpLoop(); PumpLoop();
gcm_store->AddAccountMapping( gcm_store->AddAccountMapping(
account_info2, account_mapping2,
base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
PumpLoop(); PumpLoop();
...@@ -536,26 +540,31 @@ TEST_F(GCMStoreImplTest, AccountMapping) { ...@@ -536,26 +540,31 @@ TEST_F(GCMStoreImplTest, AccountMapping) {
&GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
PumpLoop(); PumpLoop();
EXPECT_EQ(2UL, load_result->account_infos.size()); EXPECT_EQ(2UL, load_result->account_mappings.size());
GCMStore::AccountInfoMap::iterator iter = load_result->account_infos.begin(); GCMStore::AccountMappingMap::iterator iter =
load_result->account_mappings.begin();
EXPECT_EQ("account_id_1", iter->first); EXPECT_EQ("account_id_1", iter->first);
EXPECT_EQ(account_info1.account_id, iter->second.account_id); EXPECT_EQ(account_mapping1.account_id, iter->second.account_id);
EXPECT_EQ(account_info1.email, iter->second.email); EXPECT_EQ(account_mapping1.email, iter->second.email);
EXPECT_EQ(account_info1.last_message_type, iter->second.last_message_type); EXPECT_TRUE(iter->second.access_token.empty());
EXPECT_EQ(account_info1.last_message_id, iter->second.last_message_id); EXPECT_EQ(AccountMapping::ADDING, iter->second.status);
EXPECT_EQ(account_info1.last_message_timestamp, EXPECT_EQ(account_mapping1.status_change_timestamp,
iter->second.last_message_timestamp); iter->second.status_change_timestamp);
EXPECT_EQ(account_mapping1.last_message_type, iter->second.last_message_type);
EXPECT_EQ(account_mapping1.last_message_id, iter->second.last_message_id);
++iter; ++iter;
EXPECT_EQ("account_id_2", iter->first); EXPECT_EQ("account_id_2", iter->first);
EXPECT_EQ(account_info2.account_id, iter->second.account_id); EXPECT_EQ(account_mapping2.account_id, iter->second.account_id);
EXPECT_EQ(account_info2.email, iter->second.email); EXPECT_EQ(account_mapping2.email, iter->second.email);
EXPECT_EQ(account_info2.last_message_type, iter->second.last_message_type); EXPECT_TRUE(iter->second.access_token.empty());
EXPECT_EQ(account_info2.last_message_id, iter->second.last_message_id); EXPECT_EQ(AccountMapping::REMOVING, iter->second.status);
EXPECT_EQ(account_info2.last_message_timestamp, EXPECT_EQ(account_mapping2.status_change_timestamp,
iter->second.last_message_timestamp); iter->second.status_change_timestamp);
EXPECT_EQ(account_mapping2.last_message_type, iter->second.last_message_type);
EXPECT_EQ(account_mapping2.last_message_id, iter->second.last_message_id);
gcm_store->RemoveAccountMapping( gcm_store->RemoveAccountMapping(
account_info1.account_id, account_mapping1.account_id,
base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this))); base::Bind(&GCMStoreImplTest::UpdateCallback, base::Unretained(this)));
PumpLoop(); PumpLoop();
...@@ -564,15 +573,17 @@ TEST_F(GCMStoreImplTest, AccountMapping) { ...@@ -564,15 +573,17 @@ TEST_F(GCMStoreImplTest, AccountMapping) {
&GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result)); &GCMStoreImplTest::LoadCallback, base::Unretained(this), &load_result));
PumpLoop(); PumpLoop();
EXPECT_EQ(1UL, load_result->account_infos.size()); EXPECT_EQ(1UL, load_result->account_mappings.size());
iter = load_result->account_infos.begin(); iter = load_result->account_mappings.begin();
EXPECT_EQ("account_id_2", iter->first); EXPECT_EQ("account_id_2", iter->first);
EXPECT_EQ(account_info2.account_id, iter->second.account_id); EXPECT_EQ(account_mapping2.account_id, iter->second.account_id);
EXPECT_EQ(account_info2.email, iter->second.email); EXPECT_EQ(account_mapping2.email, iter->second.email);
EXPECT_EQ(account_info2.last_message_type, iter->second.last_message_type); EXPECT_TRUE(iter->second.access_token.empty());
EXPECT_EQ(account_info2.last_message_id, iter->second.last_message_id); EXPECT_EQ(AccountMapping::REMOVING, iter->second.status);
EXPECT_EQ(account_info2.last_message_timestamp, EXPECT_EQ(account_mapping2.status_change_timestamp,
iter->second.last_message_timestamp); iter->second.status_change_timestamp);
EXPECT_EQ(account_mapping2.last_message_type, iter->second.last_message_type);
EXPECT_EQ(account_mapping2.last_message_id, iter->second.last_message_id);
} }
// When the database is destroyed, all database updates should fail. At the // When the database is destroyed, all database updates should fail. At the
......
...@@ -45,8 +45,8 @@ ...@@ -45,8 +45,8 @@
'base/mcs_util.h', 'base/mcs_util.h',
'base/socket_stream.cc', 'base/socket_stream.cc',
'base/socket_stream.h', 'base/socket_stream.h',
'engine/account_info.cc', 'engine/account_mapping.cc',
'engine/account_info.h', 'engine/account_mapping.h',
'engine/checkin_request.cc', 'engine/checkin_request.cc',
'engine/checkin_request.h', 'engine/checkin_request.h',
'engine/connection_factory.cc', 'engine/connection_factory.cc',
...@@ -161,7 +161,7 @@ ...@@ -161,7 +161,7 @@
'base/mcs_message_unittest.cc', 'base/mcs_message_unittest.cc',
'base/mcs_util_unittest.cc', 'base/mcs_util_unittest.cc',
'base/socket_stream_unittest.cc', 'base/socket_stream_unittest.cc',
'engine/account_info_unittest.cc', 'engine/account_mapping_unittest.cc',
'engine/checkin_request_unittest.cc', 'engine/checkin_request_unittest.cc',
'engine/connection_factory_impl_unittest.cc', 'engine/connection_factory_impl_unittest.cc',
'engine/connection_handler_impl_unittest.cc', 'engine/connection_handler_impl_unittest.cc',
......
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