Home | History | Annotate | Download | only in internal_api
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/internal_api/sync_backup_manager.h"
      6 
      7 #include "sync/internal_api/public/read_node.h"
      8 #include "sync/internal_api/public/write_transaction.h"
      9 #include "sync/syncable/directory.h"
     10 #include "sync/syncable/mutable_entry.h"
     11 #include "url/gurl.h"
     12 
     13 namespace syncer {
     14 
     15 SyncBackupManager::SyncBackupManager()
     16     : in_normalization_(false) {
     17 }
     18 
     19 SyncBackupManager::~SyncBackupManager() {
     20 }
     21 
     22 void SyncBackupManager::Init(InitArgs* args) {
     23   if (SyncRollbackManagerBase::InitInternal(
     24           args->database_location,
     25           args->internal_components_factory.get(),
     26           InternalComponentsFactory::STORAGE_ON_DISK_DEFERRED,
     27           args->unrecoverable_error_handler.Pass(),
     28           args->report_unrecoverable_error_function)) {
     29     GetUserShare()->directory->CollectMetaHandleCounts(
     30         &status_.num_entries_by_type, &status_.num_to_delete_entries_by_type);
     31 
     32     HideSyncPreference(PRIORITY_PREFERENCES);
     33     HideSyncPreference(PREFERENCES);
     34   }
     35 }
     36 
     37 void SyncBackupManager::SaveChanges() {
     38   if (initialized())
     39     NormalizeEntries();
     40 }
     41 
     42 SyncStatus SyncBackupManager::GetDetailedStatus() const {
     43   return status_;
     44 }
     45 
     46 ModelTypeSet SyncBackupManager::HandleTransactionEndingChangeEvent(
     47     const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
     48     syncable::BaseTransaction* trans) {
     49   ModelTypeSet types;
     50   if (in_normalization_) {
     51     // Skip if in our own WriteTransaction from NormalizeEntries().
     52     in_normalization_ = false;
     53     return types;
     54   }
     55 
     56   for (syncable::EntryKernelMutationMap::const_iterator it =
     57       write_transaction_info.Get().mutations.Get().begin();
     58       it != write_transaction_info.Get().mutations.Get().end(); ++it) {
     59     int64 id = it->first;
     60     if (unsynced_.find(id) == unsynced_.end()) {
     61       unsynced_.insert(id);
     62 
     63       const syncable::EntryKernel& e = it->second.mutated;
     64       ModelType type = e.GetModelType();
     65       types.Put(type);
     66       if (!e.ref(syncable::ID).ServerKnows())
     67         status_.num_entries_by_type[type]++;
     68       if (e.ref(syncable::IS_DEL))
     69         status_.num_to_delete_entries_by_type[type]++;
     70     }
     71   }
     72   return types;
     73 }
     74 
     75 void SyncBackupManager::NormalizeEntries() {
     76   WriteTransaction trans(FROM_HERE, GetUserShare());
     77   in_normalization_ = true;
     78   for (std::set<int64>::const_iterator it = unsynced_.begin();
     79       it != unsynced_.end(); ++it) {
     80     syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
     81                                  syncable::GET_BY_HANDLE, *it);
     82     CHECK(entry.good());
     83 
     84     if (!entry.GetId().ServerKnows())
     85       entry.PutId(syncable::Id::CreateFromServerId(entry.GetId().value()));
     86     if (!entry.GetParentId().ServerKnows()) {
     87       entry.PutParentIdPropertyOnly(syncable::Id::CreateFromServerId(
     88           entry.GetParentId().value()));
     89     }
     90     entry.PutBaseVersion(1);
     91     entry.PutIsUnsynced(false);
     92   }
     93   unsynced_.clear();
     94 }
     95 
     96 void SyncBackupManager::HideSyncPreference(ModelType type) {
     97   WriteTransaction trans(FROM_HERE, GetUserShare());
     98   ReadNode pref_root(&trans);
     99   if (BaseNode::INIT_OK != pref_root.InitTypeRoot(type))
    100     return;
    101 
    102   std::vector<int64> pref_ids;
    103   pref_root.GetChildIds(&pref_ids);
    104   for (uint32 i = 0; i < pref_ids.size(); ++i) {
    105     syncable::MutableEntry entry(trans.GetWrappedWriteTrans(),
    106                                  syncable::GET_BY_HANDLE, pref_ids[i]);
    107     if (entry.good()) {
    108       // HACKY: Set IS_DEL to true to remove entry from parent-children
    109       // index so that it's not returned when syncable service asks
    110       // for sync data. Syncable service then creates entry for local
    111       // model. Then the existing entry is undeleted and set to local value
    112       // because it has the same unique client tag.
    113       entry.PutIsDel(true);
    114       entry.PutIsUnsynced(false);
    115 
    116       // Don't persist on disk so that if backup is aborted before receiving
    117       // local preference values, values in sync DB are saved.
    118       GetUserShare()->directory->UnmarkDirtyEntry(
    119           trans.GetWrappedWriteTrans(), &entry);
    120     }
    121   }
    122 }
    123 
    124 void SyncBackupManager::ShutdownOnSyncThread(ShutdownReason reason) {
    125   if (reason == SWITCH_MODE_SYNC) {
    126     NormalizeEntries();
    127     GetUserShare()->directory->SaveChanges();
    128   }
    129 
    130   SyncRollbackManagerBase::ShutdownOnSyncThread(reason);
    131 }
    132 
    133 void SyncBackupManager::RegisterDirectoryTypeDebugInfoObserver(
    134     syncer::TypeDebugInfoObserver* observer) {}
    135 
    136 void SyncBackupManager::UnregisterDirectoryTypeDebugInfoObserver(
    137     syncer::TypeDebugInfoObserver* observer) {}
    138 
    139 bool SyncBackupManager::HasDirectoryTypeDebugInfoObserver(
    140     syncer::TypeDebugInfoObserver* observer) { return false; }
    141 
    142 void SyncBackupManager::RequestEmitDebugInfo() {}
    143 
    144 }  // namespace syncer
    145