Home | History | Annotate | Download | only in glue
      1 // Copyright (c) 2011 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 "chrome/browser/sync/glue/theme_model_associator.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/logging.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/sync/engine/syncapi.h"
     11 #include "chrome/browser/sync/glue/sync_backend_host.h"
     12 #include "chrome/browser/sync/glue/theme_util.h"
     13 #include "chrome/browser/sync/profile_sync_service.h"
     14 #include "chrome/browser/sync/protocol/theme_specifics.pb.h"
     15 
     16 namespace browser_sync {
     17 
     18 namespace {
     19 
     20 static const char kThemesTag[] = "google_chrome_themes";
     21 static const char kCurrentThemeNodeTitle[] = "Current Theme";
     22 
     23 static const char kNoThemesFolderError[] =
     24     "Server did not create the top-level themes node. We "
     25     "might be running against an out-of-date server.";
     26 
     27 }  // namespace
     28 
     29 ThemeModelAssociator::ThemeModelAssociator(
     30     ProfileSyncService* sync_service)
     31     : sync_service_(sync_service) {
     32   DCHECK(sync_service_);
     33 }
     34 
     35 ThemeModelAssociator::~ThemeModelAssociator() {}
     36 
     37 bool ThemeModelAssociator::AssociateModels() {
     38   sync_api::WriteTransaction trans(sync_service_->GetUserShare());
     39   sync_api::ReadNode root(&trans);
     40   if (!root.InitByTagLookup(kThemesTag)) {
     41     LOG(ERROR) << kNoThemesFolderError;
     42     return false;
     43   }
     44 
     45   Profile* profile = sync_service_->profile();
     46   sync_api::WriteNode node(&trans);
     47   // TODO(akalin): When we have timestamps, we may want to do
     48   // something more intelligent than preferring the sync data over our
     49   // local data.
     50   if (node.InitByClientTagLookup(syncable::THEMES, kCurrentThemeClientTag)) {
     51     // Update the current theme from the sync data.
     52     // TODO(akalin): If the sync data does not have
     53     // use_system_theme_by_default and we do, update that flag on the
     54     // sync data.
     55     sync_pb::ThemeSpecifics theme_specifics = node.GetThemeSpecifics();
     56     if (UpdateThemeSpecificsOrSetCurrentThemeIfNecessary(profile,
     57                                                          &theme_specifics))
     58       node.SetThemeSpecifics(theme_specifics);
     59   } else {
     60     // Set the sync data from the current theme.
     61     sync_api::WriteNode node(&trans);
     62     if (!node.InitUniqueByCreation(syncable::THEMES, root,
     63                                    kCurrentThemeClientTag)) {
     64       LOG(ERROR) << "Could not create current theme node.";
     65       return false;
     66     }
     67     node.SetIsFolder(false);
     68     node.SetTitle(UTF8ToWide(kCurrentThemeNodeTitle));
     69     sync_pb::ThemeSpecifics theme_specifics;
     70     GetThemeSpecificsFromCurrentTheme(profile, &theme_specifics);
     71     node.SetThemeSpecifics(theme_specifics);
     72   }
     73   return true;
     74 }
     75 
     76 bool ThemeModelAssociator::DisassociateModels() {
     77   // We don't maintain any association state, so nothing to do.
     78   return true;
     79 }
     80 
     81 bool ThemeModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) {
     82   DCHECK(has_nodes);
     83   *has_nodes = false;
     84   sync_api::ReadTransaction trans(sync_service_->GetUserShare());
     85   sync_api::ReadNode root(&trans);
     86   if (!root.InitByTagLookup(kThemesTag)) {
     87     LOG(ERROR) << kNoThemesFolderError;
     88     return false;
     89   }
     90   // The sync model has user created nodes iff the themes folder has
     91   // any children.
     92   *has_nodes = root.GetFirstChildId() != sync_api::kInvalidId;
     93   return true;
     94 }
     95 
     96 bool ThemeModelAssociator::CryptoReadyIfNecessary() {
     97   // We only access the cryptographer while holding a transaction.
     98   sync_api::ReadTransaction trans(sync_service_->GetUserShare());
     99   syncable::ModelTypeSet encrypted_types;
    100   sync_service_->GetEncryptedDataTypes(&encrypted_types);
    101   return encrypted_types.count(syncable::THEMES) == 0 ||
    102          sync_service_->IsCryptographerReady(&trans);
    103 }
    104 
    105 }  // namespace browser_sync
    106