blob: 2c681259b3344c16f856585f693565d2ec84a8dd [file] [log] [blame]
// Copyright (c) 2012 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 "sync/sessions/session_state.h"
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/base64.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "sync/protocol/proto_enum_conversions.h"
using std::set;
using std::vector;
namespace browser_sync {
namespace sessions {
SyncSourceInfo::SyncSourceInfo()
: updates_source(sync_pb::GetUpdatesCallerInfo::UNKNOWN) {}
SyncSourceInfo::SyncSourceInfo(
const syncable::ModelTypePayloadMap& t)
: updates_source(sync_pb::GetUpdatesCallerInfo::UNKNOWN), types(t) {}
SyncSourceInfo::SyncSourceInfo(
const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& u,
const syncable::ModelTypePayloadMap& t)
: updates_source(u), types(t) {}
SyncSourceInfo::~SyncSourceInfo() {}
DictionaryValue* SyncSourceInfo::ToValue() const {
DictionaryValue* value = new DictionaryValue();
value->SetString("updatesSource",
GetUpdatesSourceString(updates_source));
value->Set("types", syncable::ModelTypePayloadMapToValue(types));
return value;
}
SyncerStatus::SyncerStatus()
: invalid_store(false),
num_successful_commits(0),
num_successful_bookmark_commits(0),
num_updates_downloaded_total(0),
num_tombstone_updates_downloaded_total(0),
num_local_overwrites(0),
num_server_overwrites(0) {
}
SyncerStatus::~SyncerStatus() {
}
DictionaryValue* SyncerStatus::ToValue() const {
DictionaryValue* value = new DictionaryValue();
value->SetBoolean("invalidStore", invalid_store);
value->SetInteger("numSuccessfulCommits", num_successful_commits);
value->SetInteger("numSuccessfulBookmarkCommits",
num_successful_bookmark_commits);
value->SetInteger("numUpdatesDownloadedTotal",
num_updates_downloaded_total);
value->SetInteger("numTombstoneUpdatesDownloadedTotal",
num_tombstone_updates_downloaded_total);
value->SetInteger("numLocalOverwrites", num_local_overwrites);
value->SetInteger("numServerOverwrites", num_server_overwrites);
return value;
}
DictionaryValue* DownloadProgressMarkersToValue(
const std::string
(&download_progress_markers)[syncable::MODEL_TYPE_COUNT]) {
DictionaryValue* value = new DictionaryValue();
for (int i = syncable::FIRST_REAL_MODEL_TYPE;
i < syncable::MODEL_TYPE_COUNT; ++i) {
// TODO(akalin): Unpack the value into a protobuf.
std::string base64_marker;
bool encoded =
base::Base64Encode(download_progress_markers[i], &base64_marker);
DCHECK(encoded);
value->SetString(
syncable::ModelTypeToString(syncable::ModelTypeFromInt(i)),
base64_marker);
}
return value;
}
ErrorCounters::ErrorCounters()
: last_download_updates_result(UNSET),
last_post_commit_result(UNSET),
last_process_commit_response_result(UNSET) {
}
SyncSessionSnapshot::SyncSessionSnapshot(
const SyncerStatus& syncer_status,
const ErrorCounters& errors,
int64 num_server_changes_remaining,
bool is_share_usable,
syncable::ModelTypeSet initial_sync_ended,
const std::string
(&download_progress_markers)[syncable::MODEL_TYPE_COUNT],
bool more_to_sync,
bool is_silenced,
int64 unsynced_count,
int num_encryption_conflicts,
int num_hierarchy_conflicts,
int num_simple_conflicts,
int num_server_conflicts,
bool did_commit_items,
const SyncSourceInfo& source,
size_t num_entries,
base::Time sync_start_time,
bool retry_scheduled)
: syncer_status(syncer_status),
errors(errors),
num_server_changes_remaining(num_server_changes_remaining),
is_share_usable(is_share_usable),
initial_sync_ended(initial_sync_ended),
download_progress_markers(),
has_more_to_sync(more_to_sync),
is_silenced(is_silenced),
unsynced_count(unsynced_count),
num_encryption_conflicts(num_encryption_conflicts),
num_hierarchy_conflicts(num_hierarchy_conflicts),
num_simple_conflicts(num_simple_conflicts),
num_server_conflicts(num_server_conflicts),
did_commit_items(did_commit_items),
source(source),
num_entries(num_entries),
sync_start_time(sync_start_time),
retry_scheduled(retry_scheduled) {
for (int i = syncable::FIRST_REAL_MODEL_TYPE;
i < syncable::MODEL_TYPE_COUNT; ++i) {
const_cast<std::string&>(this->download_progress_markers[i]).assign(
download_progress_markers[i]);
}
}
SyncSessionSnapshot::~SyncSessionSnapshot() {}
DictionaryValue* SyncSessionSnapshot::ToValue() const {
DictionaryValue* value = new DictionaryValue();
value->Set("syncerStatus", syncer_status.ToValue());
// We don't care too much if we lose precision here.
value->SetInteger("numServerChangesRemaining",
static_cast<int>(num_server_changes_remaining));
value->SetBoolean("isShareUsable", is_share_usable);
value->Set("initialSyncEnded",
syncable::ModelTypeSetToValue(initial_sync_ended));
value->Set("downloadProgressMarkers",
DownloadProgressMarkersToValue(download_progress_markers));
value->SetBoolean("hasMoreToSync", has_more_to_sync);
value->SetBoolean("isSilenced", is_silenced);
// We don't care too much if we lose precision here, also.
value->SetInteger("unsyncedCount",
static_cast<int>(unsynced_count));
value->SetInteger("numEncryptionConflicts",
num_encryption_conflicts);
value->SetInteger("numHierarchyConflicts",
num_hierarchy_conflicts);
value->SetInteger("numSimpleConflicts",
num_simple_conflicts);
value->SetInteger("numServerConflicts",
num_server_conflicts);
value->SetBoolean("didCommitItems", did_commit_items);
value->SetInteger("numEntries", num_entries);
value->Set("source", source.ToValue());
return value;
}
std::string SyncSessionSnapshot::ToString() const {
scoped_ptr<DictionaryValue> value(ToValue());
std::string json;
base::JSONWriter::WriteWithOptions(value.get(),
base::JSONWriter::OPTIONS_PRETTY_PRINT,
&json);
return json;
}
ConflictProgress::ConflictProgress(bool* dirty_flag)
: num_server_conflicting_items(0), num_hierarchy_conflicting_items(0),
num_encryption_conflicting_items(0), dirty_(dirty_flag) {
}
ConflictProgress::~ConflictProgress() {
}
bool ConflictProgress::HasSimpleConflictItem(const syncable::Id& id) const {
return simple_conflicting_item_ids_.count(id) > 0;
}
std::set<syncable::Id>::const_iterator
ConflictProgress::SimpleConflictingItemsBegin() const {
return simple_conflicting_item_ids_.begin();
}
std::set<syncable::Id>::const_iterator
ConflictProgress::SimpleConflictingItemsEnd() const {
return simple_conflicting_item_ids_.end();
}
void ConflictProgress::AddSimpleConflictingItemById(
const syncable::Id& the_id) {
std::pair<std::set<syncable::Id>::iterator, bool> ret =
simple_conflicting_item_ids_.insert(the_id);
if (ret.second)
*dirty_ = true;
}
void ConflictProgress::EraseSimpleConflictingItemById(
const syncable::Id& the_id) {
int items_erased = simple_conflicting_item_ids_.erase(the_id);
if (items_erased != 0)
*dirty_ = true;
}
void ConflictProgress::AddEncryptionConflictingItemById(
const syncable::Id& the_id) {
std::pair<std::set<syncable::Id>::iterator, bool> ret =
unresolvable_conflicting_item_ids_.insert(the_id);
if (ret.second) {
num_encryption_conflicting_items++;
*dirty_ = true;
}
}
void ConflictProgress::AddHierarchyConflictingItemById(
const syncable::Id& the_id) {
std::pair<std::set<syncable::Id>::iterator, bool> ret =
unresolvable_conflicting_item_ids_.insert(the_id);
if (ret.second) {
num_hierarchy_conflicting_items++;
*dirty_ = true;
}
}
void ConflictProgress::AddServerConflictingItemById(
const syncable::Id& the_id) {
std::pair<std::set<syncable::Id>::iterator, bool> ret =
unresolvable_conflicting_item_ids_.insert(the_id);
if (ret.second) {
num_server_conflicting_items++;
*dirty_ = true;
}
}
UpdateProgress::UpdateProgress() {}
UpdateProgress::~UpdateProgress() {}
void UpdateProgress::AddVerifyResult(const VerifyResult& verify_result,
const sync_pb::SyncEntity& entity) {
verified_updates_.push_back(std::make_pair(verify_result, entity));
}
void UpdateProgress::AddAppliedUpdate(const UpdateAttemptResponse& response,
const syncable::Id& id) {
applied_updates_.push_back(std::make_pair(response, id));
}
std::vector<AppliedUpdate>::iterator UpdateProgress::AppliedUpdatesBegin() {
return applied_updates_.begin();
}
std::vector<VerifiedUpdate>::const_iterator
UpdateProgress::VerifiedUpdatesBegin() const {
return verified_updates_.begin();
}
std::vector<AppliedUpdate>::const_iterator
UpdateProgress::AppliedUpdatesEnd() const {
return applied_updates_.end();
}
std::vector<VerifiedUpdate>::const_iterator
UpdateProgress::VerifiedUpdatesEnd() const {
return verified_updates_.end();
}
int UpdateProgress::SuccessfullyAppliedUpdateCount() const {
int count = 0;
for (std::vector<AppliedUpdate>::const_iterator it =
applied_updates_.begin();
it != applied_updates_.end();
++it) {
if (it->first == SUCCESS)
count++;
}
return count;
}
// Returns true if at least one update application failed due to a conflict
// during this sync cycle.
bool UpdateProgress::HasConflictingUpdates() const {
std::vector<AppliedUpdate>::const_iterator it;
for (it = applied_updates_.begin(); it != applied_updates_.end(); ++it) {
if (it->first != SUCCESS) {
return true;
}
}
return false;
}
AllModelTypeState::AllModelTypeState(bool* dirty_flag)
: unsynced_handles(dirty_flag),
syncer_status(dirty_flag),
error(dirty_flag),
num_server_changes_remaining(dirty_flag, 0),
commit_set(ModelSafeRoutingInfo()) {
}
AllModelTypeState::~AllModelTypeState() {}
PerModelSafeGroupState::PerModelSafeGroupState(bool* dirty_flag)
: conflict_progress(dirty_flag) {
}
PerModelSafeGroupState::~PerModelSafeGroupState() {
}
} // namespace sessions
} // namespace browser_sync