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