1// Copyright (c) 2012 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/extensions/api/storage/settings_sync_util.h"
6
7#include "base/json/json_writer.h"
8#include "base/values.h"
9#include "chrome/browser/extensions/api/storage/sync_value_store_cache.h"
10#include "content/public/browser/browser_thread.h"
11#include "extensions/browser/api/storage/storage_frontend.h"
12#include "sync/protocol/app_setting_specifics.pb.h"
13#include "sync/protocol/extension_setting_specifics.pb.h"
14#include "sync/protocol/sync.pb.h"
15
16using content::BrowserThread;
17
18namespace extensions {
19
20namespace settings_sync_util {
21
22namespace {
23
24void PopulateExtensionSettingSpecifics(
25    const std::string& extension_id,
26    const std::string& key,
27    const base::Value& value,
28    sync_pb::ExtensionSettingSpecifics* specifics) {
29  specifics->set_extension_id(extension_id);
30  specifics->set_key(key);
31  {
32    std::string value_as_json;
33    base::JSONWriter::Write(&value, &value_as_json);
34    specifics->set_value(value_as_json);
35  }
36}
37
38void PopulateAppSettingSpecifics(
39    const std::string& extension_id,
40    const std::string& key,
41    const base::Value& value,
42    sync_pb::AppSettingSpecifics* specifics) {
43  PopulateExtensionSettingSpecifics(
44      extension_id, key, value, specifics->mutable_extension_setting());
45}
46
47}  // namespace
48
49syncer::SyncData CreateData(
50    const std::string& extension_id,
51    const std::string& key,
52    const base::Value& value,
53    syncer::ModelType type) {
54  sync_pb::EntitySpecifics specifics;
55  switch (type) {
56    case syncer::EXTENSION_SETTINGS:
57      PopulateExtensionSettingSpecifics(
58          extension_id,
59          key,
60          value,
61          specifics.mutable_extension_setting());
62      break;
63
64    case syncer::APP_SETTINGS:
65      PopulateAppSettingSpecifics(
66          extension_id,
67          key,
68          value,
69          specifics.mutable_app_setting());
70      break;
71
72    default:
73      NOTREACHED();
74  }
75
76  return syncer::SyncData::CreateLocalData(
77      extension_id + "/" + key, key, specifics);
78}
79
80syncer::SyncChange CreateAdd(
81    const std::string& extension_id,
82    const std::string& key,
83    const base::Value& value,
84    syncer::ModelType type) {
85  return syncer::SyncChange(
86      FROM_HERE,
87      syncer::SyncChange::ACTION_ADD,
88      CreateData(extension_id, key, value, type));
89}
90
91syncer::SyncChange CreateUpdate(
92    const std::string& extension_id,
93    const std::string& key,
94    const base::Value& value,
95    syncer::ModelType type) {
96  return syncer::SyncChange(
97      FROM_HERE,
98      syncer::SyncChange::ACTION_UPDATE,
99      CreateData(extension_id, key, value, type));
100}
101
102syncer::SyncChange CreateDelete(
103    const std::string& extension_id,
104    const std::string& key,
105    syncer::ModelType type) {
106  base::DictionaryValue no_value;
107  return syncer::SyncChange(
108      FROM_HERE,
109      syncer::SyncChange::ACTION_DELETE,
110      CreateData(extension_id, key, no_value, type));
111}
112
113syncer::SyncableService* GetSyncableService(content::BrowserContext* context,
114                                            syncer::ModelType type) {
115  DCHECK_CURRENTLY_ON(BrowserThread::FILE);
116  DCHECK(type == syncer::APP_SETTINGS || type == syncer::EXTENSION_SETTINGS);
117  StorageFrontend* frontend = StorageFrontend::Get(context);
118  SyncValueStoreCache* sync_cache = static_cast<SyncValueStoreCache*>(
119      frontend->GetValueStoreCache(settings_namespace::SYNC));
120  return sync_cache->GetSyncableService(type);
121}
122
123}  // namespace settings_sync_util
124
125}  // namespace extensions
126