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/extension_sync_data.h"
6
7#include "base/logging.h"
8#include "chrome/browser/extensions/app_sync_data.h"
9#include "chrome/browser/extensions/extension_service.h"
10#include "chrome/common/extensions/manifest_url_handler.h"
11#include "components/crx_file/id_util.h"
12#include "extensions/common/extension.h"
13#include "sync/api/sync_data.h"
14#include "sync/protocol/extension_specifics.pb.h"
15#include "sync/protocol/sync.pb.h"
16
17namespace extensions {
18
19ExtensionSyncData::ExtensionSyncData()
20    : uninstalled_(false),
21      enabled_(false),
22      incognito_enabled_(false),
23      remote_install_(false),
24      installed_by_custodian_(false) {
25}
26
27ExtensionSyncData::ExtensionSyncData(const syncer::SyncData& sync_data)
28    : uninstalled_(false),
29      enabled_(false),
30      incognito_enabled_(false),
31      remote_install_(false),
32      installed_by_custodian_(false) {
33  PopulateFromSyncData(sync_data);
34}
35
36ExtensionSyncData::ExtensionSyncData(const syncer::SyncChange& sync_change)
37    : uninstalled_(sync_change.change_type() ==
38                   syncer::SyncChange::ACTION_DELETE),
39      enabled_(false),
40      incognito_enabled_(false),
41      remote_install_(false),
42      installed_by_custodian_(false) {
43  PopulateFromSyncData(sync_change.sync_data());
44}
45
46ExtensionSyncData::ExtensionSyncData(const Extension& extension,
47                                     bool enabled,
48                                     bool incognito_enabled,
49                                     bool remote_install)
50    : id_(extension.id()),
51      uninstalled_(false),
52      enabled_(enabled),
53      incognito_enabled_(incognito_enabled),
54      remote_install_(remote_install),
55      installed_by_custodian_(extension.was_installed_by_custodian()),
56      version_(extension.from_bookmark() ? base::Version("0")
57                                         : *extension.version()),
58      update_url_(ManifestURL::GetUpdateURL(&extension)),
59      name_(extension.non_localized_name()) {
60}
61
62ExtensionSyncData::~ExtensionSyncData() {}
63
64syncer::SyncData ExtensionSyncData::GetSyncData() const {
65  sync_pb::EntitySpecifics specifics;
66  PopulateExtensionSpecifics(specifics.mutable_extension());
67
68  return syncer::SyncData::CreateLocalData(id_, name_, specifics);
69}
70
71syncer::SyncChange ExtensionSyncData::GetSyncChange(
72    syncer::SyncChange::SyncChangeType change_type) const {
73  return syncer::SyncChange(FROM_HERE, change_type, GetSyncData());
74}
75
76void ExtensionSyncData::PopulateExtensionSpecifics(
77    sync_pb::ExtensionSpecifics* specifics) const {
78  DCHECK(crx_file::id_util::IdIsValid(id_));
79  specifics->set_id(id_);
80  specifics->set_update_url(update_url_.spec());
81  specifics->set_version(version_.GetString());
82  specifics->set_enabled(enabled_);
83  specifics->set_incognito_enabled(incognito_enabled_);
84  specifics->set_remote_install(remote_install_);
85  specifics->set_installed_by_custodian(installed_by_custodian_);
86  specifics->set_name(name_);
87}
88
89void ExtensionSyncData::PopulateFromExtensionSpecifics(
90    const sync_pb::ExtensionSpecifics& specifics) {
91  if (!crx_file::id_util::IdIsValid(specifics.id())) {
92    LOG(FATAL) << "Attempt to sync bad ExtensionSpecifics.";
93  }
94
95  Version specifics_version(specifics.version());
96  if (!specifics_version.IsValid())
97    LOG(FATAL) << "Attempt to sync bad ExtensionSpecifics.";
98
99  // The update URL must be either empty or valid.
100  GURL specifics_update_url(specifics.update_url());
101  if (!specifics_update_url.is_empty() && !specifics_update_url.is_valid()) {
102    LOG(FATAL) << "Attempt to sync bad ExtensionSpecifics.";
103  }
104
105  id_ = specifics.id();
106  update_url_ = specifics_update_url;
107  version_ = specifics_version;
108  enabled_ = specifics.enabled();
109  incognito_enabled_ = specifics.incognito_enabled();
110  remote_install_ = specifics.remote_install();
111  installed_by_custodian_ = specifics.installed_by_custodian();
112  name_ = specifics.name();
113}
114
115void ExtensionSyncData::set_uninstalled(bool uninstalled) {
116  uninstalled_ = uninstalled;
117}
118
119void ExtensionSyncData::PopulateFromSyncData(
120    const syncer::SyncData& sync_data) {
121  const sync_pb::EntitySpecifics& entity_specifics = sync_data.GetSpecifics();
122
123  if (entity_specifics.has_extension()) {
124    PopulateFromExtensionSpecifics(entity_specifics.extension());
125  } else {
126    LOG(FATAL) << "Attempt to sync bad EntitySpecifics.";
127  }
128}
129
130}  // namespace extensions
131