summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorcsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-11 13:48:20 +0000
committercsharp@chromium.org <csharp@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-11 13:48:20 +0000
commit5db9adad6560d8097712114ebee730be072d97f9 (patch)
tree87d2a6f637d16ea49d441ec79c378087284a9d7f /chrome/browser
parent12aea7f4b5963426318368b50d1813f5ea159b2e (diff)
downloadchromium_src-5db9adad6560d8097712114ebee730be072d97f9.zip
chromium_src-5db9adad6560d8097712114ebee730be072d97f9.tar.gz
chromium_src-5db9adad6560d8097712114ebee730be072d97f9.tar.bz2
Create New AppSyncData Class
Remove the application specific functionality from ExtensionSyncData and move it into its own new class. BUG=107729 TEST=All ExtensionSyncData and AppSyncData unit tests pass Review URL: http://codereview.chromium.org/9701076 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131760 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/app_sync_bundle.cc158
-rw-r--r--chrome/browser/extensions/app_sync_bundle.h101
-rw-r--r--chrome/browser/extensions/app_sync_data.cc99
-rw-r--r--chrome/browser/extensions/app_sync_data.h83
-rw-r--r--chrome/browser/extensions/app_sync_data_unittest.cc119
-rw-r--r--chrome/browser/extensions/extension_service.cc405
-rw-r--r--chrome/browser/extensions/extension_service.h84
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc41
-rw-r--r--chrome/browser/extensions/extension_sync_bundle.cc161
-rw-r--r--chrome/browser/extensions/extension_sync_bundle.h101
-rw-r--r--chrome/browser/extensions/extension_sync_data.cc120
-rw-r--r--chrome/browser/extensions/extension_sync_data.h54
-rw-r--r--chrome/browser/extensions/extension_sync_data_unittest.cc112
13 files changed, 1124 insertions, 514 deletions
diff --git a/chrome/browser/extensions/app_sync_bundle.cc b/chrome/browser/extensions/app_sync_bundle.cc
new file mode 100644
index 0000000..43ceb98
--- /dev/null
+++ b/chrome/browser/extensions/app_sync_bundle.cc
@@ -0,0 +1,158 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/app_sync_bundle.h"
+
+#include "base/location.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_sorting.h"
+#include "chrome/browser/sync/api/sync_change_processor.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_set.h"
+
+namespace extensions {
+
+AppSyncBundle::AppSyncBundle(ExtensionService* extension_service)
+ : extension_service_(extension_service),
+ sync_processor_(NULL) {}
+
+AppSyncBundle::~AppSyncBundle() {}
+
+void AppSyncBundle::SetupSync(SyncChangeProcessor* sync_change_processor,
+ const SyncDataList& initial_sync_data) {
+ sync_processor_.reset(sync_change_processor);
+
+ for (SyncDataList::const_iterator i = initial_sync_data.begin();
+ i != initial_sync_data.end();
+ ++i) {
+ AppSyncData app_sync_data(*i);
+ AddApp(app_sync_data.id());
+ extension_service_->ProcessAppSyncData(app_sync_data);
+ }
+}
+
+void AppSyncBundle::Reset() {
+ sync_processor_.reset();
+ synced_apps_.clear();
+ pending_sync_data_.clear();
+}
+
+SyncChange AppSyncBundle::CreateSyncChangeToDelete(const Extension* extension)
+ const {
+ AppSyncData sync_data = extension_service_->GetAppSyncData(*extension);
+ return sync_data.GetSyncChange(SyncChange::ACTION_DELETE);
+}
+
+void AppSyncBundle::ProcessDeletion(std::string extension_id,
+ const SyncChange& sync_change) {
+ RemoveApp(extension_id);
+ sync_processor_->ProcessSyncChanges(FROM_HERE,
+ SyncChangeList(1, sync_change));
+}
+
+SyncChange AppSyncBundle::CreateSyncChange(const SyncData& sync_data) {
+ if (HasExtensionId(sync_data.GetTag())) {
+ return SyncChange(SyncChange::ACTION_UPDATE, sync_data);
+ } else {
+ AddApp(sync_data.GetTag());
+ return SyncChange(SyncChange::ACTION_ADD, sync_data);
+ }
+}
+
+SyncDataList AppSyncBundle::GetAllSyncData() const {
+ std::vector<AppSyncData> app_sync_data =
+ extension_service_->GetAppSyncDataList();
+ SyncDataList result(app_sync_data.size());
+ for (int i = 0; i < static_cast<int>(app_sync_data.size()); ++i) {
+ result[i] = app_sync_data[i].GetSyncData();
+ }
+ return result;
+}
+
+void AppSyncBundle::SyncChangeIfNeeded(const Extension& extension) {
+ AppSyncData app_sync_data = extension_service_->GetAppSyncData(extension);
+
+ SyncChangeList sync_change_list(1, app_sync_data.GetSyncChange(
+ HasExtensionId(extension.id()) ?
+ SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD));
+ sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list);
+ MarkPendingAppSynced(extension.id());
+}
+
+void AppSyncBundle::ProcessSyncChange(AppSyncData app_sync_data) {
+ if (app_sync_data.uninstalled())
+ RemoveApp(app_sync_data.id());
+ else
+ AddApp(app_sync_data.id());
+ extension_service_->ProcessAppSyncData(app_sync_data);
+}
+
+void AppSyncBundle::ProcessSyncChangeList(SyncChangeList sync_change_list) {
+ sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list);
+ extension_service_->extension_prefs()->extension_sorting()->
+ FixNTPOrdinalCollisions();
+}
+
+bool AppSyncBundle::HasExtensionId(const std::string& id) const {
+ return synced_apps_.find(id) != synced_apps_.end();
+}
+
+bool AppSyncBundle::HasPendingExtensionId(const std::string& id) const {
+ return pending_sync_data_.find(id) != pending_sync_data_.end();
+}
+
+void AppSyncBundle::AddPendingApp(const std::string& id,
+ const AppSyncData& app_sync_data) {
+ pending_sync_data_[id] = app_sync_data;
+}
+
+bool AppSyncBundle::HandlesApp(const Extension& extension) const {
+ return sync_processor_ != NULL &&
+ extension.GetSyncType() == Extension::SYNC_TYPE_APP;
+}
+
+std::vector<AppSyncData> AppSyncBundle::GetPendingData() const {
+ std::vector<AppSyncData> pending_apps;
+ for (std::map<std::string, AppSyncData>::const_iterator
+ i = pending_sync_data_.begin();
+ i != pending_sync_data_.end();
+ ++i) {
+ pending_apps.push_back(i->second);
+ }
+
+ return pending_apps;
+}
+
+void AppSyncBundle::GetAppSyncDataListHelper(
+ const ExtensionSet& extensions,
+ std::vector<AppSyncData>* sync_data_list) const {
+ for (ExtensionSet::const_iterator it = extensions.begin();
+ it != extensions.end(); ++it) {
+ const Extension& extension = **it;
+ // If we have pending app data for this app, then this
+ // version is out of date. We'll sync back the version we got from
+ // sync.
+ if (HandlesApp(extension) &&
+ !HasPendingExtensionId(extension.id())) {
+ sync_data_list->push_back(extension_service_->GetAppSyncData(extension));
+ }
+ }
+}
+
+void AppSyncBundle::AddApp(const std::string& id) {
+ synced_apps_.insert(id);
+}
+
+void AppSyncBundle::RemoveApp(const std::string& id) {
+ synced_apps_.erase(id);
+}
+
+
+void AppSyncBundle::MarkPendingAppSynced(const std::string& id) {
+ pending_sync_data_.erase(id);
+ synced_apps_.insert(id);
+}
+
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/app_sync_bundle.h b/chrome/browser/extensions/app_sync_bundle.h
new file mode 100644
index 0000000..9872e9d
--- /dev/null
+++ b/chrome/browser/extensions/app_sync_bundle.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_APP_SYNC_BUNDLE_H_
+#define CHROME_BROWSER_EXTENSIONS_APP_SYNC_BUNDLE_H_
+#pragma once
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/app_sync_data.h"
+#include "chrome/browser/sync/api/syncable_service.h"
+
+class SyncChangeProcessor;
+class Extension;
+class ExtensionService;
+class ExtensionSet;
+
+namespace extensions {
+
+// Bundle of app specific sync stuff.
+class AppSyncBundle {
+ public:
+ explicit AppSyncBundle(ExtensionService* extension_service);
+ virtual ~AppSyncBundle();
+
+ // Setup this bundle to be sync application data.
+ void SetupSync(SyncChangeProcessor* sync_proccessor,
+ const SyncDataList& initial_sync_data);
+
+ // Resets this class back to it default values, which will disable all syncing
+ // until a new sync processor is set.
+ void Reset();
+
+ // Returns a SyncChange that will delete the given application.
+ SyncChange CreateSyncChangeToDelete(const Extension* extension) const;
+
+ // Process the sync deletion of the given application.
+ void ProcessDeletion(std::string extension_id, const SyncChange& sync_change);
+
+ // Create a sync change based on |sync_data|.
+ SyncChange CreateSyncChange(const SyncData& sync_data);
+
+ // Get all the sync data contained in this bundle.
+ SyncDataList GetAllSyncData() const;
+
+ // Sync a newly-installed application or change an existing one.
+ void SyncChangeIfNeeded(const Extension& extension);
+
+ // Process the given sync change and apply it.
+ void ProcessSyncChange(AppSyncData app_sync_data);
+
+ // Process the list of sync changes.
+ void ProcessSyncChangeList(SyncChangeList sync_change_list);
+
+ // Check to see if the given |id| is either synced or pending to be synced.
+ bool HasExtensionId(const std::string& id) const;
+ bool HasPendingExtensionId(const std::string& id) const;
+
+ // Add a pending app to be synced.
+ void AddPendingApp(const std::string& id,
+ const AppSyncData& app_sync_data);
+
+ // Returns true if |extension| should be handled by this sync bundle.
+ bool HandlesApp(const Extension& extension) const;
+
+ // Returns a vector of all the pending sync data.
+ std::vector<AppSyncData> GetPendingData() const;
+
+ // Appends sync data objects for every app in |extensions|.
+ void GetAppSyncDataListHelper(
+ const ExtensionSet& extensions,
+ std::vector<extensions::AppSyncData>* sync_data_list) const;
+
+ private:
+ // Add a synced app.
+ void AddApp(const std::string& id);
+
+ // Remove a synced app.
+ void RemoveApp(const std::string& id); // make private
+
+ // Change an app from being pending to synced.
+ void MarkPendingAppSynced(const std::string& id);
+
+ ExtensionService* extension_service_; // Own us.
+ scoped_ptr<SyncChangeProcessor> sync_processor_;
+
+ std::set<std::string> synced_apps_;
+ std::map<std::string, AppSyncData> pending_sync_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppSyncBundle);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_APP_SYNC_BUNDLE_H_
diff --git a/chrome/browser/extensions/app_sync_data.cc b/chrome/browser/extensions/app_sync_data.cc
new file mode 100644
index 0000000..8145b0a
--- /dev/null
+++ b/chrome/browser/extensions/app_sync_data.cc
@@ -0,0 +1,99 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/app_sync_data.h"
+
+#include "chrome/browser/sync/api/sync_data.h"
+#include "chrome/common/extensions/extension.h"
+#include "sync/protocol/app_specifics.pb.h"
+#include "sync/protocol/sync.pb.h"
+
+namespace extensions {
+
+AppSyncData::AppSyncData() : notifications_disabled_(false) {}
+
+AppSyncData::AppSyncData(const SyncData& sync_data)
+ : notifications_disabled_(false) {
+ PopulateFromSyncData(sync_data);
+}
+
+AppSyncData::AppSyncData(const SyncChange& sync_change)
+ : notifications_disabled_(false) {
+ PopulateFromSyncData(sync_change.sync_data());
+ extension_sync_data_.set_uninstalled(
+ sync_change.change_type() == SyncChange::ACTION_DELETE);
+}
+
+AppSyncData::AppSyncData(const Extension& extension,
+ bool enabled,
+ bool incognito_enabled,
+ const std::string& notifications_client_id,
+ bool notifications_disabled,
+ const StringOrdinal& app_launch_ordinal,
+ const StringOrdinal& page_ordinal)
+ : extension_sync_data_(extension, enabled, incognito_enabled),
+ notifications_client_id_(notifications_client_id),
+ notifications_disabled_(notifications_disabled),
+ app_launch_ordinal_(app_launch_ordinal),
+ page_ordinal_(page_ordinal) {
+}
+
+AppSyncData::~AppSyncData() {}
+
+SyncData AppSyncData::GetSyncData() const {
+ sync_pb::EntitySpecifics specifics;
+ PopulateAppSpecifics(specifics.mutable_app());
+
+ return SyncData::CreateLocalData(extension_sync_data_.id(),
+ extension_sync_data_.name(),
+ specifics);
+}
+
+SyncChange AppSyncData::GetSyncChange(SyncChange::SyncChangeType change_type)
+ const {
+ return SyncChange(change_type, GetSyncData());
+}
+
+void AppSyncData::PopulateAppSpecifics(sync_pb::AppSpecifics* specifics) const {
+ DCHECK(specifics);
+ sync_pb::AppNotificationSettings* notification_settings =
+ specifics->mutable_notification_settings();
+ if (!notifications_client_id_.empty())
+ notification_settings->set_oauth_client_id(notifications_client_id_);
+ notification_settings->set_disabled(notifications_disabled_);
+
+ // Only sync the ordinal values if they are valid.
+ if (app_launch_ordinal_.IsValid())
+ specifics->set_app_launch_ordinal(app_launch_ordinal_.ToString());
+ if (page_ordinal_.IsValid())
+ specifics->set_page_ordinal(page_ordinal_.ToString());
+
+ extension_sync_data_.PopulateExtensionSpecifics(
+ specifics->mutable_extension());
+}
+
+void AppSyncData::PopulateFromAppSpecifics(
+ const sync_pb::AppSpecifics& specifics) {
+ extension_sync_data_.PopulateFromExtensionSpecifics(specifics.extension());
+
+ if (specifics.has_notification_settings() &&
+ specifics.notification_settings().has_oauth_client_id()) {
+ notifications_client_id_ =
+ specifics.notification_settings().oauth_client_id();
+ }
+
+ notifications_disabled_ =
+ specifics.has_notification_settings() &&
+ specifics.notification_settings().has_disabled() &&
+ specifics.notification_settings().disabled();
+
+ app_launch_ordinal_ = StringOrdinal(specifics.app_launch_ordinal());
+ page_ordinal_ = StringOrdinal(specifics.page_ordinal());
+}
+
+void AppSyncData::PopulateFromSyncData(const SyncData& sync_data) {
+ PopulateFromAppSpecifics(sync_data.GetSpecifics().app());
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/app_sync_data.h b/chrome/browser/extensions/app_sync_data.h
new file mode 100644
index 0000000..a77ef39
--- /dev/null
+++ b/chrome/browser/extensions/app_sync_data.h
@@ -0,0 +1,83 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_APP_SYNC_DATA_H_
+#define CHROME_BROWSER_EXTENSIONS_APP_SYNC_DATA_H_
+#pragma once
+
+#include "chrome/browser/extensions/extension_sync_data.h"
+#include "chrome/browser/sync/api/sync_change.h"
+#include "chrome/common/string_ordinal.h"
+
+class Extension;
+class SyncData;
+namespace sync_pb {
+class AppSpecifics;
+}
+
+namespace extensions {
+
+class ExtensionSyncData;
+
+// A class that encapsulates the synced properties of an Application.
+class AppSyncData {
+ public:
+ AppSyncData();
+ explicit AppSyncData(const SyncData& sync_data);
+ explicit AppSyncData(const SyncChange& sync_change);
+ AppSyncData(const Extension& extension,
+ bool enabled,
+ bool incognito_enabled,
+ const std::string& notifications_client_id,
+ bool notifications_disabled,
+ const StringOrdinal& app_launch_ordinal,
+ const StringOrdinal& page_ordinal);
+ ~AppSyncData();
+
+ // Retrive sync data from this class.
+ SyncData GetSyncData() const;
+ SyncChange GetSyncChange(SyncChange::SyncChangeType change_type) const;
+
+ const std::string& id() const { return extension_sync_data_.id(); }
+
+ bool uninstalled() const { return extension_sync_data_.uninstalled(); }
+
+ const std::string& notifications_client_id() const {
+ return notifications_client_id_;
+ }
+
+ bool notifications_disabled() const {
+ return notifications_disabled_;
+ }
+
+ // These ordinals aren't necessarily valid. Some applications don't have
+ // valid ordinals because they don't appear on the new tab page.
+ const StringOrdinal& app_launch_ordinal() const {
+ return app_launch_ordinal_;
+ }
+ const StringOrdinal& page_ordinal() const { return page_ordinal_; }
+
+ const ExtensionSyncData& extension_sync_data() const {
+ return extension_sync_data_;
+ }
+
+ private:
+ // Convert an AppSyncData back out to a sync structure.
+ void PopulateAppSpecifics(sync_pb::AppSpecifics* specifics) const;
+
+ // Populate this class from sync inputs.
+ void PopulateFromAppSpecifics(
+ const sync_pb::AppSpecifics& specifics);
+ void PopulateFromSyncData(const SyncData& sync_data);
+
+ ExtensionSyncData extension_sync_data_;
+ std::string notifications_client_id_;
+ bool notifications_disabled_;
+ StringOrdinal app_launch_ordinal_;
+ StringOrdinal page_ordinal_;
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_APP_SYNC_DATA_H_
diff --git a/chrome/browser/extensions/app_sync_data_unittest.cc b/chrome/browser/extensions/app_sync_data_unittest.cc
new file mode 100644
index 0000000..0a86964
--- /dev/null
+++ b/chrome/browser/extensions/app_sync_data_unittest.cc
@@ -0,0 +1,119 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/app_sync_data.h"
+
+#include "sync/protocol/app_specifics.pb.h"
+#include "sync/protocol/sync.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+namespace {
+
+const char kValidId[] = "abcdefghijklmnopabcdefghijklmnop";
+const char kName[] = "MyExtension";
+const char kValidVersion[] = "0.0.0.0";
+const char kValidUpdateUrl[] =
+ "http://clients2.google.com/service/update2/crx";
+const char kOAuthClientId[] = "1234abcd";
+
+} // namespace
+
+class AppSyncDataTest : public testing::Test {
+ public:
+ AppSyncDataTest() {}
+ virtual ~AppSyncDataTest() {}
+
+ void SetRequiredExtensionValues(
+ sync_pb::ExtensionSpecifics* extension_specifics) {
+ extension_specifics->set_id(kValidId);
+ extension_specifics->set_update_url(kValidUpdateUrl);
+ extension_specifics->set_version(kValidVersion);
+ extension_specifics->set_enabled(false);
+ extension_specifics->set_incognito_enabled(true);
+ extension_specifics->set_name(kName);
+ }
+};
+
+TEST_F(AppSyncDataTest, SyncDataToExtensionSyncDataForApp) {
+ sync_pb::EntitySpecifics entity;
+ sync_pb::AppSpecifics* app_specifics = entity.mutable_app();
+ app_specifics->set_app_launch_ordinal(
+ StringOrdinal::CreateInitialOrdinal().ToString());
+ app_specifics->set_page_ordinal(
+ StringOrdinal::CreateInitialOrdinal().ToString());
+ sync_pb::AppNotificationSettings* notif_settings =
+ app_specifics->mutable_notification_settings();
+ notif_settings->set_oauth_client_id(kOAuthClientId);
+ notif_settings->set_disabled(true);
+
+ SetRequiredExtensionValues(app_specifics->mutable_extension());
+
+ SyncData sync_data =
+ SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
+
+ AppSyncData app_sync_data(sync_data);
+ EXPECT_EQ(app_specifics->app_launch_ordinal(),
+ app_sync_data.app_launch_ordinal().ToString());
+ EXPECT_EQ(app_specifics->page_ordinal(),
+ app_sync_data.page_ordinal().ToString());
+ EXPECT_EQ(notif_settings->oauth_client_id(),
+ app_sync_data.notifications_client_id());
+ EXPECT_EQ(notif_settings->disabled(),
+ app_sync_data.notifications_disabled());
+}
+
+
+
+TEST_F(AppSyncDataTest, ExtensionSyncDataToSyncDataForApp) {
+ sync_pb::EntitySpecifics entity;
+ sync_pb::AppSpecifics* input_specifics = entity.mutable_app();
+ input_specifics->set_app_launch_ordinal(
+ StringOrdinal::CreateInitialOrdinal().ToString());
+ input_specifics->set_page_ordinal(
+ StringOrdinal::CreateInitialOrdinal().ToString());
+ sync_pb::AppNotificationSettings* notif_settings =
+ input_specifics->mutable_notification_settings();
+ notif_settings->set_oauth_client_id(kOAuthClientId);
+ notif_settings->set_disabled(true);
+
+ SetRequiredExtensionValues(input_specifics->mutable_extension());
+
+ SyncData sync_data =
+ SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
+ AppSyncData app_sync_data(sync_data);
+
+ SyncData output_sync_data = app_sync_data.GetSyncData();
+ EXPECT_TRUE(sync_data.GetSpecifics().has_app());
+ const sync_pb::AppSpecifics& output_specifics =
+ output_sync_data.GetSpecifics().app();
+ EXPECT_EQ(input_specifics->SerializeAsString(),
+ output_specifics.SerializeAsString());
+}
+
+// Ensures that invalid StringOrdinals don't break ExtensionSyncData.
+TEST_F(AppSyncDataTest, ExtensionSyncDataInvalidOrdinal) {
+ sync_pb::EntitySpecifics entity;
+ sync_pb::AppSpecifics* app_specifics = entity.mutable_app();
+ // Set the ordinals as invalid.
+ app_specifics->set_app_launch_ordinal("");
+ app_specifics->set_page_ordinal("");
+
+ sync_pb::AppNotificationSettings* notif_settings =
+ app_specifics->mutable_notification_settings();
+ notif_settings->set_oauth_client_id(kOAuthClientId);
+ notif_settings->set_disabled(true);
+
+ SetRequiredExtensionValues(app_specifics->mutable_extension());
+
+ SyncData sync_data =
+ SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
+
+ // There should be no issue loading the sync data.
+ AppSyncData app_sync_data(sync_data);
+ app_sync_data.GetSyncData();
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 27bc442..891290e 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -33,11 +33,13 @@
#include "chrome/browser/download/download_extension_api.h"
#include "chrome/browser/extensions/api/api_resource_controller.h"
#include "chrome/browser/extensions/app_notification_manager.h"
+#include "chrome/browser/extensions/app_sync_data.h"
#include "chrome/browser/extensions/apps_promo.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h"
+#include "chrome/browser/extensions/app_sync_data.h"
#include "chrome/browser/extensions/default_apps_trial.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_cookies_api.h"
@@ -391,6 +393,8 @@ ExtensionService::ExtensionService(Profile* profile,
app_notification_manager_(new AppNotificationManager(profile)),
apps_promo_(profile->GetPrefs()),
event_routers_initialized_(false),
+ app_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
+ extension_sync_bundle_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
extension_warnings_(profile),
api_resource_controller_(NULL),
app_shortcut_manager_(profile) {
@@ -777,20 +781,11 @@ bool ExtensionService::UninstallExtension(
// Extract the data we need for sync now, but don't actually sync until we've
// completed the uninstallation.
- SyncBundle* sync_bundle = GetSyncBundleForExtension(*extension);
-
SyncChange sync_change;
- if (sync_bundle) {
- ExtensionSyncData extension_sync_data(
- *extension,
- IsExtensionEnabled(extension_id),
- IsIncognitoEnabled(extension_id),
- extension_prefs_->GetAppNotificationClientId(extension_id),
- extension_prefs_->IsAppNotificationDisabled(extension_id),
- extension_prefs_->extension_sorting()->
- GetAppLaunchOrdinal(extension_id),
- extension_prefs_->extension_sorting()->GetPageOrdinal(extension_id));
- sync_change = extension_sync_data.GetSyncChange(SyncChange::ACTION_DELETE);
+ if (app_sync_bundle_.HandlesApp(*extension)) {
+ sync_change = app_sync_bundle_.CreateSyncChangeToDelete(extension);
+ } else if (extension_sync_bundle_.HandlesExtension(*extension)) {
+ sync_change = extension_sync_bundle_.CreateSyncChangeToDelete(extension);
}
UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType",
@@ -844,10 +839,12 @@ bool ExtensionService::UninstallExtension(
content::Source<Profile>(profile_),
content::Details<const std::string>(&extension_id));
- if (sync_bundle && sync_bundle->HasExtensionId(extension_id)) {
- sync_bundle->sync_processor->ProcessSyncChanges(
- FROM_HERE, SyncChangeList(1, sync_change));
- sync_bundle->synced_extensions.erase(extension_id);
+ if (app_sync_bundle_.HasExtensionId(extension_id) &&
+ sync_change.sync_data().GetDataType() == syncable::APPS) {
+ app_sync_bundle_.ProcessDeletion(extension_id, sync_change);
+ } else if (extension_sync_bundle_.HasExtensionId(extension_id) &&
+ sync_change.sync_data().GetDataType() == syncable::EXTENSIONS) {
+ extension_sync_bundle_.ProcessDeletion(extension_id, sync_change);
}
// Track the uninstallation.
@@ -1271,115 +1268,25 @@ void ExtensionService::CheckForUpdatesSoon() {
}
}
-namespace {
- bool IsSyncableNone(const Extension& extension) { return false; }
-} // namespace
-
-ExtensionService::SyncBundle::SyncBundle()
- : filter(IsSyncableNone) {
-}
-
-ExtensionService::SyncBundle::~SyncBundle() {
-}
-
-void ExtensionService::SyncBundle::Reset() {
- filter = IsSyncableNone;
- synced_extensions.clear();
- pending_sync_data.clear();
- sync_processor.reset();
-}
-
-bool ExtensionService::SyncBundle::HasExtensionId(const std::string& id) const {
- return synced_extensions.find(id) != synced_extensions.end();
-}
-
-bool ExtensionService::SyncBundle::HasPendingExtensionId(const std::string& id)
- const {
- return pending_sync_data.find(id) != pending_sync_data.end();
-}
-
-ExtensionService::SyncBundle* ExtensionService::GetSyncBundleForExtension(
- const Extension& extension) {
- if (app_sync_bundle_.filter(extension))
- return &app_sync_bundle_;
- else if (extension_sync_bundle_.filter(extension))
- return &extension_sync_bundle_;
- else
- return NULL;
-}
-
-ExtensionService::SyncBundle*
- ExtensionService::GetSyncBundleForExtensionSyncData(
- const ExtensionSyncData& extension_sync_data) {
- switch (extension_sync_data.type()) {
- case Extension::SYNC_TYPE_APP:
- return &app_sync_bundle_;
- case Extension::SYNC_TYPE_EXTENSION:
- return &extension_sync_bundle_;
- default:
- NOTREACHED();
- return NULL;
- }
-}
-
-#define GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY() \
- do { \
- switch (type) { \
- case syncable::APPS: \
- return &app_sync_bundle_; \
- case syncable::EXTENSIONS: \
- return &extension_sync_bundle_; \
- default: \
- NOTREACHED(); \
- return NULL; \
- } \
- } while (0)
-
-const ExtensionService::SyncBundle*
- ExtensionService::GetSyncBundleForModelTypeConst(
- syncable::ModelType type) const {
- GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY();
-}
-
-ExtensionService::SyncBundle* ExtensionService::GetSyncBundleForModelType(
- syncable::ModelType type) {
- GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY();
-}
-
-#undef GET_SYNC_BUNDLE_FOR_MODEL_TYPE_BODY
-
SyncError ExtensionService::MergeDataAndStartSyncing(
syncable::ModelType type,
const SyncDataList& initial_sync_data,
scoped_ptr<SyncChangeProcessor> sync_processor) {
- SyncBundle* bundle = NULL;
+ CHECK(sync_processor.get());
switch (type) {
case syncable::EXTENSIONS:
- bundle = &extension_sync_bundle_;
- bundle->filter = IsSyncableExtension;
+ extension_sync_bundle_.SetupSync(sync_processor.release(),
+ initial_sync_data);
break;
case syncable::APPS:
- bundle = &app_sync_bundle_;
- bundle->filter = IsSyncableApp;
+ app_sync_bundle_.SetupSync(sync_processor.release(), initial_sync_data);
break;
default:
LOG(FATAL) << "Got " << type << " ModelType";
}
- DCHECK(!bundle->sync_processor.get());
- DCHECK(sync_processor.get());
- bundle->sync_processor = sync_processor.Pass();
-
- // Process extensions from sync.
- for (SyncDataList::const_iterator i = initial_sync_data.begin();
- i != initial_sync_data.end();
- ++i) {
- ExtensionSyncData extension_sync_data = ExtensionSyncData(*i);
- bundle->synced_extensions.insert(extension_sync_data.id());
- ProcessExtensionSyncData(extension_sync_data, *bundle);
- }
// Process local extensions.
// TODO(yoz): Determine whether pending extensions should be considered too.
@@ -1389,35 +1296,49 @@ SyncError ExtensionService::MergeDataAndStartSyncing(
for (SyncDataList::const_iterator i = sync_data_list.begin();
i != sync_data_list.end();
++i) {
- if (bundle->HasExtensionId(i->GetTag())) {
- sync_change_list.push_back(SyncChange(SyncChange::ACTION_UPDATE, *i));
- } else {
- bundle->synced_extensions.insert(i->GetTag());
- sync_change_list.push_back(SyncChange(SyncChange::ACTION_ADD, *i));
- }
+ switch (type) {
+ case syncable::EXTENSIONS:
+ sync_change_list.push_back(
+ extension_sync_bundle_.CreateSyncChange(*i));
+ break;
+ case syncable::APPS:
+ sync_change_list.push_back(app_sync_bundle_.CreateSyncChange(*i));
+ break;
+ default:
+ LOG(FATAL) << "Got " << type << " ModelType";
+ }
}
- bundle->sync_processor->ProcessSyncChanges(FROM_HERE, sync_change_list);
- extension_prefs_->extension_sorting()->FixNTPOrdinalCollisions();
+
+ if (type == syncable::EXTENSIONS) {
+ extension_sync_bundle_.ProcessSyncChangeList(sync_change_list);
+ } else if (type == syncable::APPS) {
+ app_sync_bundle_.ProcessSyncChangeList(sync_change_list);
+ }
return SyncError();
}
void ExtensionService::StopSyncing(syncable::ModelType type) {
- SyncBundle* bundle = GetSyncBundleForModelType(type);
- CHECK(bundle);
- bundle->Reset();
+ if (type == syncable::APPS) {
+ app_sync_bundle_.Reset();
+ } else if (type == syncable::EXTENSIONS) {
+ extension_sync_bundle_.Reset();
+ }
}
SyncDataList ExtensionService::GetAllSyncData(syncable::ModelType type) const {
- const SyncBundle* bundle = GetSyncBundleForModelTypeConst(type);
- CHECK(bundle);
- std::vector<ExtensionSyncData> extension_sync_data = GetSyncDataList(*bundle);
- SyncDataList result(extension_sync_data.size());
- for (int i = 0; i < static_cast<int>(extension_sync_data.size()); ++i) {
- result[i] = extension_sync_data[i].GetSyncData();
+ if (type == syncable::EXTENSIONS) {
+ return extension_sync_bundle_.GetAllSyncData();
+
+ } else if (type == syncable::APPS) {
+ return app_sync_bundle_.GetAllSyncData();
}
- return result;
+
+ // We should only get sync data for extensions and apps.
+ NOTREACHED();
+
+ return SyncDataList();
}
SyncError ExtensionService::ProcessSyncChanges(
@@ -1426,15 +1347,13 @@ SyncError ExtensionService::ProcessSyncChanges(
for (SyncChangeList::const_iterator i = change_list.begin();
i != change_list.end();
++i) {
- ExtensionSyncData extension_sync_data = ExtensionSyncData(*i);
- SyncBundle* bundle = GetSyncBundleForExtensionSyncData(extension_sync_data);
- CHECK(bundle);
-
- if (extension_sync_data.uninstalled())
- bundle->synced_extensions.erase(extension_sync_data.id());
- else
- bundle->synced_extensions.insert(extension_sync_data.id());
- ProcessExtensionSyncData(extension_sync_data, *bundle);
+ syncable::ModelType type = i->sync_data().GetDataType();
+ if (type == syncable::EXTENSIONS) {
+ extension_sync_bundle_.ProcessSyncChange(
+ extensions::ExtensionSyncData(*i));
+ } else if (type == syncable::APPS) {
+ app_sync_bundle_.ProcessSyncChange(extensions::AppSyncData(*i));
+ }
}
extension_prefs()->extension_sorting()->FixNTPOrdinalCollisions();
@@ -1442,60 +1361,134 @@ SyncError ExtensionService::ProcessSyncChanges(
return SyncError();
}
-void ExtensionService::GetSyncDataListHelper(
- const ExtensionSet& extensions,
- const SyncBundle& bundle,
- std::vector<ExtensionSyncData>* sync_data_list) const {
- for (ExtensionSet::const_iterator it = extensions.begin();
- it != extensions.end(); ++it) {
- const Extension& extension = **it;
- if (bundle.filter(extension) &&
- // If we have pending extension data for this extension, then this
- // version is out of date. We'll sync back the version we got from
- // sync.
- !bundle.HasPendingExtensionId(extension.id())) {
- sync_data_list->push_back(ExtensionSyncData(
- extension,
- IsExtensionEnabled(extension.id()),
- IsIncognitoEnabled(extension.id()),
- extension_prefs_->GetAppNotificationClientId(extension.id()),
- extension_prefs_->IsAppNotificationDisabled(extension.id()),
- extension_prefs_->extension_sorting()->
- GetAppLaunchOrdinal(extension.id()),
- extension_prefs_->extension_sorting()->
- GetPageOrdinal(extension.id())));
- }
+extensions::ExtensionSyncData ExtensionService::GetExtensionSyncData(
+ const Extension& extension) const {
+ return extensions::ExtensionSyncData(extension,
+ IsExtensionEnabled(extension.id()),
+ IsIncognitoEnabled(extension.id()));
+}
+
+extensions::AppSyncData ExtensionService::GetAppSyncData(
+ const Extension& extension) const {
+ return extensions::AppSyncData(
+ extension,
+ IsExtensionEnabled(extension.id()),
+ IsIncognitoEnabled(extension.id()),
+ extension_prefs_->GetAppNotificationClientId(extension.id()),
+ extension_prefs_->IsAppNotificationDisabled(extension.id()),
+ extension_prefs_->extension_sorting()->GetAppLaunchOrdinal(
+ extension.id()),
+ extension_prefs_->extension_sorting()->GetPageOrdinal(extension.id()));
+}
+
+std::vector<extensions::ExtensionSyncData>
+ ExtensionService::GetExtensionSyncDataList() const {
+ std::vector<extensions::ExtensionSyncData> extension_sync_list;
+ extension_sync_bundle_.GetExtensionSyncDataListHelper(extensions_,
+ &extension_sync_list);
+ extension_sync_bundle_.GetExtensionSyncDataListHelper(disabled_extensions_,
+ &extension_sync_list);
+ extension_sync_bundle_.GetExtensionSyncDataListHelper(terminated_extensions_,
+ &extension_sync_list);
+
+ std::vector<extensions::ExtensionSyncData> pending_extensions =
+ extension_sync_bundle_.GetPendingData();
+ extension_sync_list.insert(extension_sync_list.begin(),
+ pending_extensions.begin(),
+ pending_extensions.end());
+
+ return extension_sync_list;
+}
+
+std::vector<extensions::AppSyncData> ExtensionService::GetAppSyncDataList()
+ const {
+ std::vector<extensions::AppSyncData> app_sync_list;
+ app_sync_bundle_.GetAppSyncDataListHelper(extensions_, &app_sync_list);
+ app_sync_bundle_.GetAppSyncDataListHelper(disabled_extensions_,
+ &app_sync_list);
+ app_sync_bundle_.GetAppSyncDataListHelper(terminated_extensions_,
+ &app_sync_list);
+
+ std::vector<extensions::AppSyncData> pending_apps =
+ app_sync_bundle_.GetPendingData();
+ app_sync_list.insert(app_sync_list.begin(),
+ pending_apps.begin(),
+ pending_apps.end());
+
+ return app_sync_list;
+}
+
+bool ExtensionService::ProcessExtensionSyncData(
+ const extensions::ExtensionSyncData& extension_sync_data) {
+ if (!ProcessExtensionSyncDataHelper(extension_sync_data,
+ syncable::EXTENSIONS)) {
+ extension_sync_bundle_.AddPendingExtension(extension_sync_data.id(),
+ extension_sync_data);
+ CheckForUpdatesSoon();
+ return false;
}
+
+ return true;
}
-std::vector<ExtensionSyncData> ExtensionService::GetSyncDataList(
- const SyncBundle& bundle) const {
- std::vector<ExtensionSyncData> extension_sync_list;
- GetSyncDataListHelper(extensions_, bundle, &extension_sync_list);
- GetSyncDataListHelper(disabled_extensions_, bundle, &extension_sync_list);
- GetSyncDataListHelper(terminated_extensions_, bundle, &extension_sync_list);
+bool ExtensionService::ProcessAppSyncData(
+ const extensions::AppSyncData& app_sync_data) {
+ const std::string& id = app_sync_data.id();
+ const Extension* extension = GetInstalledExtension(id);
+ bool extension_installed = (extension != NULL);
- for (std::map<std::string, ExtensionSyncData>::const_iterator i =
- bundle.pending_sync_data.begin();
- i != bundle.pending_sync_data.end();
- ++i) {
- extension_sync_list.push_back(i->second);
+ if (app_sync_data.app_launch_ordinal().IsValid() &&
+ app_sync_data.page_ordinal().IsValid()) {
+ extension_prefs_->extension_sorting()->SetAppLaunchOrdinal(
+ id,
+ app_sync_data.app_launch_ordinal());
+ extension_prefs_->extension_sorting()->SetPageOrdinal(
+ id,
+ app_sync_data.page_ordinal());
}
- return extension_sync_list;
+ if (extension_installed) {
+ if (app_sync_data.notifications_disabled() !=
+ extension_prefs_->IsAppNotificationDisabled(id)) {
+ extension_prefs_->SetAppNotificationDisabled(
+ id, app_sync_data.notifications_disabled());
+ }
+ }
+
+ if (!ProcessExtensionSyncDataHelper(app_sync_data.extension_sync_data(),
+ syncable::APPS)) {
+ app_sync_bundle_.AddPendingApp(id, app_sync_data);
+ CheckForUpdatesSoon();
+ return false;
+ }
+
+ return true;
}
-void ExtensionService::ProcessExtensionSyncData(
- const ExtensionSyncData& extension_sync_data,
- SyncBundle& bundle) {
+bool ExtensionService::IsCorrectSyncType(const Extension& extension,
+ syncable::ModelType type) const {
+ if (type == syncable::EXTENSIONS &&
+ extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION)
+ return true;
+
+ if (type == syncable::APPS &&
+ extension.GetSyncType() == Extension::SYNC_TYPE_APP)
+ return true;
+
+ return false;
+}
+
+bool ExtensionService::ProcessExtensionSyncDataHelper(
+ const extensions::ExtensionSyncData& extension_sync_data,
+ syncable::ModelType type) {
const std::string& id = extension_sync_data.id();
const Extension* extension = GetInstalledExtension(id);
// TODO(bolms): we should really handle this better. The particularly bad
// case is where an app becomes an extension or vice versa, and we end up with
// a zombie extension that won't go away.
- if (extension && !bundle.filter(*extension))
- return;
+ if (extension && !IsCorrectSyncType(*extension, type))
+ return true;
// Handle uninstalls first.
if (extension_sync_data.uninstalled()) {
@@ -1504,7 +1497,7 @@ void ExtensionService::ProcessExtensionSyncData(
LOG(WARNING) << "Could not uninstall extension " << id
<< " for sync";
}
- return;
+ return true;
}
// Set user settings.
@@ -1523,37 +1516,25 @@ void ExtensionService::ProcessExtensionSyncData(
SetIsIncognitoEnabled(id, extension_sync_data.incognito_enabled());
extension = NULL; // No longer safe to use.
- if (extension_sync_data.app_launch_ordinal().IsValid() &&
- extension_sync_data.page_ordinal().IsValid()) {
- extension_prefs_->extension_sorting()->SetAppLaunchOrdinal(
- id,
- extension_sync_data.app_launch_ordinal());
- extension_prefs_->extension_sorting()->SetPageOrdinal(
- id,
- extension_sync_data.page_ordinal());
- }
-
if (extension_installed) {
// If the extension is already installed, check if it's outdated.
if (result < 0) {
// Extension is outdated.
- bundle.pending_sync_data[extension_sync_data.id()] = extension_sync_data;
- CheckForUpdatesSoon();
- }
- if (extension_sync_data.type() == Extension::SYNC_TYPE_APP &&
- extension_sync_data.notifications_disabled() !=
- extension_prefs_->IsAppNotificationDisabled(id)) {
- extension_prefs_->SetAppNotificationDisabled(
- id, extension_sync_data.notifications_disabled());
+ return false;
}
} else {
// TODO(akalin): Replace silent update with a list of enabled
// permissions.
const bool kInstallSilently = true;
+
+ CHECK(type == syncable::EXTENSIONS || type == syncable::APPS);
+ ExtensionFilter filter =
+ (type == syncable::APPS) ? IsSyncableApp : IsSyncableExtension;
+
if (!pending_extension_manager()->AddFromSync(
id,
extension_sync_data.update_url(),
- bundle.filter,
+ filter,
kInstallSilently)) {
LOG(WARNING) << "Could not add pending extension for " << id;
// This means that the extension is already pending installation, with a
@@ -1562,9 +1543,10 @@ void ExtensionService::ProcessExtensionSyncData(
// extension), so that GetAllSyncData() continues to send it.
}
// Track pending extensions so that we can return them in GetAllSyncData().
- bundle.pending_sync_data[extension_sync_data.id()] = extension_sync_data;
- CheckForUpdatesSoon();
+ return false;
}
+
+ return true;
}
bool ExtensionService::IsIncognitoEnabled(
@@ -1972,25 +1954,10 @@ void ExtensionService::GarbageCollectExtensions() {
}
void ExtensionService::SyncExtensionChangeIfNeeded(const Extension& extension) {
- SyncBundle* sync_bundle = GetSyncBundleForExtension(extension);
- if (sync_bundle) {
- ExtensionSyncData extension_sync_data(
- extension,
- IsExtensionEnabled(extension.id()),
- IsIncognitoEnabled(extension.id()),
- extension_prefs_->GetAppNotificationClientId(extension.id()),
- extension_prefs_->IsAppNotificationDisabled(extension.id()),
- extension_prefs_->extension_sorting()->
- GetAppLaunchOrdinal(extension.id()),
- extension_prefs_->extension_sorting()->GetPageOrdinal(extension.id()));
-
- SyncChangeList sync_change_list(1, extension_sync_data.GetSyncChange(
- sync_bundle->HasExtensionId(extension.id()) ?
- SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD));
- sync_bundle->sync_processor->ProcessSyncChanges(
- FROM_HERE, sync_change_list);
- sync_bundle->synced_extensions.insert(extension.id());
- sync_bundle->pending_sync_data.erase(extension.id());
+ if (app_sync_bundle_.HandlesApp(extension)) {
+ app_sync_bundle_.SyncChangeIfNeeded(extension);
+ } else if (extension_sync_bundle_.HandlesExtension(extension)) {
+ extension_sync_bundle_.SyncChangeIfNeeded(extension);
}
}
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h
index 14e7412..b24b7bb8 100644
--- a/chrome/browser/extensions/extension_service.h
+++ b/chrome/browser/extensions/extension_service.h
@@ -23,12 +23,13 @@
#include "base/time.h"
#include "base/tuple.h"
#include "chrome/browser/extensions/app_shortcut_manager.h"
+#include "chrome/browser/extensions/app_sync_bundle.h"
#include "chrome/browser/extensions/apps_promo.h"
#include "chrome/browser/extensions/extension_icon_manager.h"
#include "chrome/browser/extensions/extension_menu_manager.h"
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_process_manager.h"
-#include "chrome/browser/extensions/extension_sync_data.h"
+#include "chrome/browser/extensions/extension_sync_bundle.h"
#include "chrome/browser/extensions/extension_toolbar_model.h"
#include "chrome/browser/extensions/extension_warning_set.h"
#include "chrome/browser/extensions/extensions_quota_service.h"
@@ -73,7 +74,9 @@ class ExtensionInputMethodEventRouter;
namespace extensions {
class APIResourceController;
+class AppSyncData;
class ComponentLoader;
+class ExtensionSyncData;
class ExtensionUpdater;
class SettingsFrontend;
class WebNavigationEventRouter;
@@ -428,6 +431,30 @@ class ExtensionService
const tracked_objects::Location& from_here,
const SyncChangeList& change_list) OVERRIDE;
+ // Gets the sync data for the given extension, assuming that the extension is
+ // syncable.
+ extensions::ExtensionSyncData GetExtensionSyncData(
+ const Extension& extension) const;
+
+ // Gets the sync data for the given app, assuming that the app is
+ // syncable.
+ extensions::AppSyncData GetAppSyncData(const Extension& extension) const;
+
+ // Gets the ExtensionSyncData for all extensions.
+ std::vector<extensions::ExtensionSyncData> GetExtensionSyncDataList() const;
+
+ // Gets the AppSyncData for all extensions.
+ std::vector<extensions::AppSyncData> GetAppSyncDataList() const;
+
+ // Applies the change specified passed in by either ExtensionSyncData or
+ // AppSyncData to the current system.
+ // Returns false if the changes were not completely applied and were added
+ // to the pending list to be tried again.
+ bool ProcessExtensionSyncData(
+ const extensions::ExtensionSyncData& extension_sync_data);
+ bool ProcessAppSyncData(const extensions::AppSyncData& app_sync_data);
+
+
void set_extensions_enabled(bool enabled) { extensions_enabled_ = enabled; }
bool extensions_enabled() { return extensions_enabled_; }
@@ -586,23 +613,6 @@ class ExtensionService
AppShortcutManager* app_shortcut_manager() { return &app_shortcut_manager_; }
private:
- // Bundle of type (app or extension)-specific sync stuff.
- struct SyncBundle {
- SyncBundle();
- ~SyncBundle();
-
- void Reset();
-
- bool HasExtensionId(const std::string& id) const;
- bool HasPendingExtensionId(const std::string& id) const;
-
- // Note: all members of the struct need to be explicitly cleared in Reset().
- ExtensionFilter filter;
- std::set<std::string> synced_extensions;
- std::map<std::string, ExtensionSyncData> pending_sync_data;
- scoped_ptr<SyncChangeProcessor> sync_processor;
- };
-
// Contains Extension data that can change during the life of the process,
// but does not persist across restarts.
struct ExtensionRuntimeData {
@@ -632,33 +642,17 @@ class ExtensionService
};
typedef std::list<NaClModuleInfo> NaClModuleInfoList;
- // Get the appropriate SyncBundle, given some representation of Sync data.
- SyncBundle* GetSyncBundleForExtension(const Extension& extension);
- SyncBundle* GetSyncBundleForExtensionSyncData(
- const ExtensionSyncData& extension_sync_data);
- SyncBundle* GetSyncBundleForModelType(syncable::ModelType type);
- const SyncBundle* GetSyncBundleForModelTypeConst(syncable::ModelType type)
+ // Return true if the sync type of |extension| matches |type|.
+ bool IsCorrectSyncType(const Extension& extension, syncable::ModelType type)
const;
- // Gets the ExtensionSyncData for all extensions.
- std::vector<ExtensionSyncData> GetSyncDataList(
- const SyncBundle& bundle) const;
-
- // Gets the sync data for the given extension, assuming that the extension is
- // syncable.
- ExtensionSyncData GetSyncData(const Extension& extension) const;
-
- // Appends sync data objects for every extension in |extensions|
- // that passes |filter|.
- void GetSyncDataListHelper(
- const ExtensionSet& extensions,
- const SyncBundle& bundle,
- std::vector<ExtensionSyncData>* sync_data_list) const;
-
- // Applies the change specified in an ExtensionSyncData to the current system.
- void ProcessExtensionSyncData(
- const ExtensionSyncData& extension_sync_data,
- SyncBundle& bundle);
+ // Handles setting the extension specific values in |extension_sync_data| to
+ // the current system.
+ // Returns false if the changes were not completely applied and need to be
+ // tried again later.
+ bool ProcessExtensionSyncDataHelper(
+ const extensions::ExtensionSyncData& extension_sync_data,
+ syncable::ModelType type);
// Look up an extension by ID, optionally including either or both of enabled
// and disabled extensions.
@@ -828,8 +822,8 @@ class ExtensionService
NaClModuleInfoList nacl_module_list_;
- SyncBundle app_sync_bundle_;
- SyncBundle extension_sync_bundle_;
+ extensions::AppSyncBundle app_sync_bundle_;
+ extensions::ExtensionSyncBundle extension_sync_bundle_;
// Contains an entry for each warning that shall be currently shown.
ExtensionWarningSet extension_warnings_;
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 55e4867..a4925b2 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -27,6 +27,7 @@
#include "base/utf_string_conversions.h"
#include "base/version.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/app_sync_data.h"
#include "chrome/browser/extensions/component_loader.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_creator.h"
@@ -4008,7 +4009,7 @@ TEST_F(ExtensionServiceTest, GetSyncData) {
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_EQ(extension->id(), data.id());
EXPECT_FALSE(data.uninstalled());
EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
@@ -4031,7 +4032,7 @@ TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_EQ(extension->id(), data.id());
EXPECT_FALSE(data.uninstalled());
EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
@@ -4068,7 +4069,7 @@ TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_TRUE(data.enabled());
EXPECT_FALSE(data.incognito_enabled());
}
@@ -4077,7 +4078,7 @@ TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_FALSE(data.enabled());
EXPECT_FALSE(data.incognito_enabled());
}
@@ -4086,7 +4087,7 @@ TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_FALSE(data.enabled());
EXPECT_TRUE(data.incognito_enabled());
}
@@ -4095,7 +4096,7 @@ TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::EXTENSIONS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
+ extensions::ExtensionSyncData data(list[0]);
EXPECT_TRUE(data.enabled());
EXPECT_TRUE(data.incognito_enabled());
}
@@ -4116,9 +4117,10 @@ TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::APPS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
- EXPECT_TRUE(initial_ordinal.Equal(data.app_launch_ordinal()));
- EXPECT_TRUE(initial_ordinal.Equal(data.page_ordinal()));
+
+ extensions::AppSyncData app_sync_data(list[0]);
+ EXPECT_TRUE(initial_ordinal.Equal(app_sync_data.app_launch_ordinal()));
+ EXPECT_TRUE(initial_ordinal.Equal(app_sync_data.page_ordinal()));
}
ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
@@ -4126,18 +4128,20 @@ TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
{
SyncDataList list = service_->GetAllSyncData(syncable::APPS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
- EXPECT_TRUE(initial_ordinal.LessThan(data.app_launch_ordinal()));
- EXPECT_TRUE(initial_ordinal.Equal(data.page_ordinal()));
+
+ extensions::AppSyncData app_sync_data(list[0]);
+ EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
+ EXPECT_TRUE(initial_ordinal.Equal(app_sync_data.page_ordinal()));
}
sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
{
SyncDataList list = service_->GetAllSyncData(syncable::APPS);
ASSERT_EQ(list.size(), 1U);
- ExtensionSyncData data(list[0]);
- EXPECT_TRUE(initial_ordinal.LessThan(data.app_launch_ordinal()));
- EXPECT_TRUE(initial_ordinal.LessThan(data.page_ordinal()));
+
+ extensions::AppSyncData app_sync_data(list[0]);
+ EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
+ EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
}
}
@@ -4161,9 +4165,12 @@ TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
{
SyncDataList list = service_->GetAllSyncData(syncable::APPS);
ASSERT_EQ(list.size(), 3U);
- ExtensionSyncData data[kAppCount];
+
+ extensions::AppSyncData data[kAppCount];
for (size_t i = 0; i < kAppCount; ++i)
- data[i] = ExtensionSyncData(list[i]);
+ {
+ data[i] = extensions::AppSyncData(list[i]);
+ }
// The sync data is not always in the same order our apps were installed in,
// so we do that sorting here so we can make sure the values are changed as
diff --git a/chrome/browser/extensions/extension_sync_bundle.cc b/chrome/browser/extensions/extension_sync_bundle.cc
new file mode 100644
index 0000000..d4f5f5b
--- /dev/null
+++ b/chrome/browser/extensions/extension_sync_bundle.cc
@@ -0,0 +1,161 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_sync_bundle.h"
+
+#include "base/location.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_sorting.h"
+#include "chrome/browser/sync/api/sync_change_processor.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_set.h"
+
+namespace extensions {
+
+ExtensionSyncBundle::ExtensionSyncBundle(ExtensionService* extension_service)
+ : extension_service_(extension_service), sync_processor_(NULL) {}
+
+ExtensionSyncBundle::~ExtensionSyncBundle() {}
+
+void ExtensionSyncBundle::SetupSync(SyncChangeProcessor* sync_processor,
+ const SyncDataList& initial_sync_data) {
+ sync_processor_.reset(sync_processor);
+
+ for (SyncDataList::const_iterator i = initial_sync_data.begin();
+ i != initial_sync_data.end();
+ ++i) {
+ ExtensionSyncData extension_sync_data(*i);
+ AddExtension(extension_sync_data.id());
+ extension_service_->ProcessExtensionSyncData(extension_sync_data);
+ }
+}
+
+void ExtensionSyncBundle::Reset() {
+ sync_processor_.reset();
+ synced_extensions_.clear();
+ pending_sync_data_.clear();
+}
+
+SyncChange ExtensionSyncBundle::CreateSyncChangeToDelete(
+ const Extension* extension) const {
+ extensions::ExtensionSyncData sync_data =
+ extension_service_->GetExtensionSyncData(*extension);
+ return sync_data.GetSyncChange(SyncChange::ACTION_DELETE);
+}
+
+void ExtensionSyncBundle::ProcessDeletion(std::string extension_id,
+ const SyncChange& sync_change) {
+ RemoveExtension(extension_id);
+ sync_processor_->ProcessSyncChanges(FROM_HERE,
+ SyncChangeList(1, sync_change));
+}
+
+SyncChange ExtensionSyncBundle::CreateSyncChange(const SyncData& sync_data) {
+ if (HasExtensionId(sync_data.GetTag())) {
+ return SyncChange(SyncChange::ACTION_UPDATE, sync_data);
+ } else {
+ AddExtension(sync_data.GetTag());
+ return SyncChange(SyncChange::ACTION_ADD, sync_data);
+ }
+}
+
+SyncDataList ExtensionSyncBundle::GetAllSyncData() const {
+ std::vector<ExtensionSyncData> extension_sync_data =
+ extension_service_->GetExtensionSyncDataList();
+ SyncDataList result(extension_sync_data.size());
+ for (int i = 0; i < static_cast<int>(extension_sync_data.size()); ++i) {
+ result[i] = extension_sync_data[i].GetSyncData();
+ }
+ return result;
+}
+
+void ExtensionSyncBundle::SyncChangeIfNeeded(const Extension& extension) {
+ ExtensionSyncData extension_sync_data =
+ extension_service_->GetExtensionSyncData(extension);
+
+ SyncChangeList sync_change_list(1, extension_sync_data.GetSyncChange(
+ HasExtensionId(extension.id()) ?
+ SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD));
+ sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list);
+ MarkPendingExtensionSynced(extension.id());
+}
+
+void ExtensionSyncBundle::ProcessSyncChange(
+ ExtensionSyncData extension_sync_data) {
+ if (extension_sync_data.uninstalled())
+ RemoveExtension(extension_sync_data.id());
+ else
+ AddExtension(extension_sync_data.id());
+ extension_service_->ProcessExtensionSyncData(extension_sync_data);
+}
+
+void ExtensionSyncBundle::ProcessSyncChangeList(
+ SyncChangeList sync_change_list) {
+ sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list);
+}
+
+bool ExtensionSyncBundle::HasExtensionId(
+ const std::string& id) const {
+ return synced_extensions_.find(id) != synced_extensions_.end();
+}
+
+bool ExtensionSyncBundle::HasPendingExtensionId(
+ const std::string& id) const {
+ return pending_sync_data_.find(id) != pending_sync_data_.end();
+}
+
+void ExtensionSyncBundle::AddPendingExtension(
+ const std::string& id,
+ const ExtensionSyncData& extension_sync_data) {
+ pending_sync_data_[id] = extension_sync_data;
+}
+
+bool ExtensionSyncBundle::HandlesExtension(const Extension& extension) const {
+ return sync_processor_ != NULL &&
+ extension.GetSyncType() == Extension::SYNC_TYPE_EXTENSION;
+}
+
+std::vector<ExtensionSyncData> ExtensionSyncBundle::GetPendingData() const {
+ std::vector<ExtensionSyncData> pending_extensions;
+ for (std::map<std::string, ExtensionSyncData>::const_iterator
+ i = pending_sync_data_.begin();
+ i != pending_sync_data_.end();
+ ++i) {
+ pending_extensions.push_back(i->second);
+ }
+
+ return pending_extensions;
+}
+
+void ExtensionSyncBundle::GetExtensionSyncDataListHelper(
+ const ExtensionSet& extensions,
+ std::vector<ExtensionSyncData>* sync_data_list) const {
+ for (ExtensionSet::const_iterator it = extensions.begin();
+ it != extensions.end(); ++it) {
+ const Extension& extension = **it;
+ // If we have pending extension data for this extension, then this
+ // version is out of date. We'll sync back the version we got from
+ // sync.
+ if (HandlesExtension(extension) &&
+ !HasPendingExtensionId(extension.id())) {
+ sync_data_list->push_back(
+ extension_service_->GetExtensionSyncData(extension));
+ }
+ }
+}
+
+void ExtensionSyncBundle::AddExtension(const std::string& id) {
+ synced_extensions_.insert(id);
+}
+
+void ExtensionSyncBundle::RemoveExtension(const std::string& id) {
+ synced_extensions_.erase(id);
+}
+
+void ExtensionSyncBundle::MarkPendingExtensionSynced(const std::string& id) {
+ pending_sync_data_.erase(id);
+ synced_extensions_.insert(id);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_sync_bundle.h b/chrome/browser/extensions/extension_sync_bundle.h
new file mode 100644
index 0000000..9c79eb8
--- /dev/null
+++ b/chrome/browser/extensions/extension_sync_bundle.h
@@ -0,0 +1,101 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_BUNDLE_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_BUNDLE_H_
+#pragma once
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/extensions/extension_sync_data.h"
+#include "chrome/browser/sync/api/syncable_service.h"
+
+class SyncChangeProcessor;
+class Extension;
+class ExtensionService;
+class ExtensionSet;
+
+namespace extensions {
+
+// Bundle of extension specific sync stuff.
+class ExtensionSyncBundle {
+ public:
+ explicit ExtensionSyncBundle(ExtensionService* extension_service);
+ ~ExtensionSyncBundle();
+
+ // Setup this bundle to be sync extension data.
+ void SetupSync(SyncChangeProcessor* sync_processor,
+ const SyncDataList& initial_sync_data);
+
+ // Resets this class back to it default values, which will disable all syncing
+ // until a new sync processor is set.
+ void Reset();
+
+ // Returns a SyncChange that will delete the given extension.
+ SyncChange CreateSyncChangeToDelete(const Extension* extension) const;
+
+ // Process the sync deletion of the given extension.
+ void ProcessDeletion(std::string extension_id, const SyncChange& sync_change);
+
+ // Create a sync change based on |sync_data|.
+ SyncChange CreateSyncChange(const SyncData& sync_data);
+
+ // Get all the sync data contained in this bundle.
+ SyncDataList GetAllSyncData() const;
+
+ // Process the given sync change and apply it.
+ void ProcessSyncChange(ExtensionSyncData extension_sync_data);
+
+ // Sync a newly-installed extension or change an existing one.
+ void SyncChangeIfNeeded(const Extension& extension);
+
+ // Process the list of sync changes.
+ void ProcessSyncChangeList(SyncChangeList sync_change_list);
+
+ // Check to see if the given |id| is either synced or pending to be synced.
+ bool HasExtensionId(const std::string& id) const;
+ bool HasPendingExtensionId(const std::string& id) const;
+
+ // Add a pending extension to be synced.
+ void AddPendingExtension(const std::string& id,
+ const ExtensionSyncData& extension_sync_data);
+
+ // Returns true if |extension| should be handled by this sync bundle.
+ bool HandlesExtension(const Extension& extension) const;
+
+ // Returns a vector of all the pending sync data.
+ std::vector<ExtensionSyncData> GetPendingData() const;
+
+ // Appends sync data objects for every extension in |extensions|.
+ void GetExtensionSyncDataListHelper(
+ const ExtensionSet& extensions,
+ std::vector<extensions::ExtensionSyncData>* sync_data_list) const;
+
+ private:
+ // Add a synced extension.
+ void AddExtension(const std::string& id);
+
+ // Remove a synced extension.
+ void RemoveExtension(const std::string& id);
+
+ // Change an extension from being pending to synced.
+ void MarkPendingExtensionSynced(const std::string& id);
+
+ ExtensionService* extension_service_; // Owns us.
+ scoped_ptr<SyncChangeProcessor> sync_processor_;
+
+ std::set<std::string> synced_extensions_;
+ std::map<std::string, ExtensionSyncData> pending_sync_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionSyncBundle);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_BUNDLE_H_
diff --git a/chrome/browser/extensions/extension_sync_data.cc b/chrome/browser/extensions/extension_sync_data.cc
index c2095ad..52d54a1 100644
--- a/chrome/browser/extensions/extension_sync_data.cc
+++ b/chrome/browser/extensions/extension_sync_data.cc
@@ -5,102 +5,52 @@
#include "chrome/browser/extensions/extension_sync_data.h"
#include "base/logging.h"
+#include "chrome/browser/extensions/app_sync_data.h"
#include "chrome/browser/extensions/extension_service.h"
-#include "sync/protocol/app_specifics.pb.h"
+#include "chrome/browser/sync/api/sync_data.h"
+#include "chrome/common/extensions/extension.h"
#include "sync/protocol/extension_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
+namespace extensions {
+
ExtensionSyncData::ExtensionSyncData()
: uninstalled_(false),
enabled_(false),
- incognito_enabled_(false),
- type_(Extension::SYNC_TYPE_NONE),
- notifications_disabled_(false) {
+ incognito_enabled_(false) {
}
ExtensionSyncData::ExtensionSyncData(const SyncData& sync_data)
: uninstalled_(false),
enabled_(false),
- incognito_enabled_(false),
- type_(Extension::SYNC_TYPE_NONE),
- notifications_disabled_(false) {
+ incognito_enabled_(false) {
PopulateFromSyncData(sync_data);
}
ExtensionSyncData::ExtensionSyncData(const SyncChange& sync_change)
: uninstalled_(sync_change.change_type() == SyncChange::ACTION_DELETE),
enabled_(false),
- incognito_enabled_(false),
- type_(Extension::SYNC_TYPE_NONE),
- notifications_disabled_(false) {
+ incognito_enabled_(false) {
PopulateFromSyncData(sync_change.sync_data());
}
ExtensionSyncData::ExtensionSyncData(const Extension& extension,
bool enabled,
- bool incognito_enabled,
- const std::string& notifications_client_id,
- bool notifications_disabled,
- const StringOrdinal& app_launch_ordinal,
- const StringOrdinal& page_ordinal)
- : id_(extension.id()),
- uninstalled_(false),
- enabled_(enabled),
- incognito_enabled_(incognito_enabled),
- type_(extension.GetSyncType()),
- version_(*extension.version()),
- update_url_(extension.update_url()),
- name_(extension.name()),
- notifications_client_id_(notifications_client_id),
- notifications_disabled_(notifications_disabled),
- app_launch_ordinal_(app_launch_ordinal),
- page_ordinal_(page_ordinal) {
+ bool incognito_enabled)
+ : id_(extension.id()),
+ uninstalled_(false),
+ enabled_(enabled),
+ incognito_enabled_(incognito_enabled),
+ version_(*extension.version()),
+ update_url_(extension.update_url()),
+ name_(extension.name()) {
}
ExtensionSyncData::~ExtensionSyncData() {}
-void ExtensionSyncData::PopulateAppSpecifics(
- sync_pb::AppSpecifics* specifics) const {
- DCHECK(specifics);
- sync_pb::AppNotificationSettings* notif_settings =
- specifics->mutable_notification_settings();
- if (!notifications_client_id_.empty())
- notif_settings->set_oauth_client_id(notifications_client_id_);
- notif_settings->set_disabled(notifications_disabled_);
-
- // Only sync the ordinal values if they are valid.
- if (app_launch_ordinal_.IsValid())
- specifics->set_app_launch_ordinal(app_launch_ordinal_.ToString());
- if (page_ordinal_.IsValid())
- specifics->set_page_ordinal(page_ordinal_.ToString());
-
- PopulateExtensionSpecifics(specifics->mutable_extension());
-}
-
-void ExtensionSyncData::PopulateExtensionSpecifics(
- sync_pb::ExtensionSpecifics* specifics) const {
- DCHECK(Extension::IdIsValid(id_));
- specifics->set_id(id_);
- specifics->set_update_url(update_url_.spec());
- specifics->set_version(version_.GetString());
- specifics->set_enabled(enabled_);
- specifics->set_incognito_enabled(incognito_enabled_);
- specifics->set_name(name_);
-}
-
SyncData ExtensionSyncData::GetSyncData() const {
sync_pb::EntitySpecifics specifics;
-
- switch (type_) {
- case Extension::SYNC_TYPE_EXTENSION:
- PopulateExtensionSpecifics(specifics.mutable_extension());
- break;
- case Extension::SYNC_TYPE_APP:
- PopulateAppSpecifics(specifics.mutable_app());
- break;
- default:
- LOG(FATAL) << "Attempt to get non-syncable data.";
- }
+ PopulateExtensionSpecifics(specifics.mutable_extension());
return SyncData::CreateLocalData(id_, name_, specifics);
}
@@ -110,23 +60,15 @@ SyncChange ExtensionSyncData::GetSyncChange(
return SyncChange(change_type, GetSyncData());
}
-void ExtensionSyncData::PopulateFromAppSpecifics(
- const sync_pb::AppSpecifics& specifics) {
- PopulateFromExtensionSpecifics(specifics.extension());
-
- if (specifics.has_notification_settings() &&
- specifics.notification_settings().has_oauth_client_id()) {
- notifications_client_id_ =
- specifics.notification_settings().oauth_client_id();
- }
-
- notifications_disabled_ =
- specifics.has_notification_settings() &&
- specifics.notification_settings().has_disabled() &&
- specifics.notification_settings().disabled();
-
- app_launch_ordinal_ = StringOrdinal(specifics.app_launch_ordinal());
- page_ordinal_ = StringOrdinal(specifics.page_ordinal());
+void ExtensionSyncData::PopulateExtensionSpecifics(
+ sync_pb::ExtensionSpecifics* specifics) const {
+ DCHECK(Extension::IdIsValid(id_));
+ specifics->set_id(id_);
+ specifics->set_update_url(update_url_.spec());
+ specifics->set_version(version_.GetString());
+ specifics->set_enabled(enabled_);
+ specifics->set_incognito_enabled(incognito_enabled_);
+ specifics->set_name(name_);
}
void ExtensionSyncData::PopulateFromExtensionSpecifics(
@@ -153,16 +95,18 @@ void ExtensionSyncData::PopulateFromExtensionSpecifics(
name_ = specifics.name();
}
+void ExtensionSyncData::set_uninstalled(bool uninstalled) {
+ uninstalled_ = uninstalled;
+}
+
void ExtensionSyncData::PopulateFromSyncData(const SyncData& sync_data) {
const sync_pb::EntitySpecifics& entity_specifics = sync_data.GetSpecifics();
if (entity_specifics.has_extension()) {
PopulateFromExtensionSpecifics(entity_specifics.extension());
- type_ = Extension::SYNC_TYPE_EXTENSION;
- } else if (entity_specifics.has_app()) {
- PopulateFromAppSpecifics(entity_specifics.app());
- type_ = Extension::SYNC_TYPE_APP;
} else {
LOG(FATAL) << "Attempt to sync bad EntitySpecifics.";
}
}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_sync_data.h b/chrome/browser/extensions/extension_sync_data.h
index a9b07af..cdd56ed 100644
--- a/chrome/browser/extensions/extension_sync_data.h
+++ b/chrome/browser/extensions/extension_sync_data.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,19 +10,17 @@
#include "base/version.h"
#include "chrome/browser/sync/api/sync_change.h"
-#include "chrome/browser/sync/api/sync_data.h"
-#include "chrome/common/extensions/extension.h"
#include "chrome/common/string_ordinal.h"
#include "googleurl/src/gurl.h"
+class Extension;
class SyncData;
+
namespace sync_pb {
-class AppSpecifics;
class ExtensionSpecifics;
}
-// TODO(csharp): Split this class up into AppSyncData and ExtensionsSyncData.
-// crbug.com/107729
+namespace extensions {
// A class that encapsulates the synced properties of an Extension.
class ExtensionSyncData {
@@ -32,19 +30,22 @@ class ExtensionSyncData {
explicit ExtensionSyncData(const SyncChange& sync_change);
ExtensionSyncData(const Extension& extension,
bool enabled,
- bool incognito_enabled,
- const std::string& notifications_client_id,
- bool notifications_disabled,
- const StringOrdinal& app_launch_ordinal,
- const StringOrdinal& page_ordinal);
+ bool incognito_enabled);
~ExtensionSyncData();
- // Convert an ExtensionSyncData back out to a sync structure.
- void PopulateAppSpecifics(sync_pb::AppSpecifics* specifics) const;
- void PopulateExtensionSpecifics(sync_pb::ExtensionSpecifics* specifics) const;
+ // Retrieve sync data from this class.
SyncData GetSyncData() const;
SyncChange GetSyncChange(SyncChange::SyncChangeType change_type) const;
+ // Convert an ExtensionSyncData back out to a sync structure.
+ void PopulateExtensionSpecifics(sync_pb::ExtensionSpecifics* specifics) const;
+
+ // Populate this class from sync inputs.
+ void PopulateFromExtensionSpecifics(
+ const sync_pb::ExtensionSpecifics& specifics);
+
+ void set_uninstalled(bool uninstalled);
+
const std::string& id() const { return id_; }
// Version-independent properties (i.e., used even when the
@@ -53,11 +54,6 @@ class ExtensionSyncData {
bool uninstalled() const { return uninstalled_; }
bool enabled() const { return enabled_; }
bool incognito_enabled() const { return incognito_enabled_; }
- Extension::SyncType type() const { return type_; }
- // These ordinals aren't necessarily valid.
- const StringOrdinal& app_launch_ordinal() const {
- return app_launch_ordinal_; }
- const StringOrdinal& page_ordinal() const {return page_ordinal_; }
// Version-dependent properties (i.e., should be used only when the
// version of the currenty-installed extension matches |version|).
@@ -66,33 +62,19 @@ class ExtensionSyncData {
// Used only for debugging.
const std::string& name() const { return name_; }
- const std::string& notifications_client_id() const {
- return notifications_client_id_;
- }
-
- bool notifications_disabled() const {
- return notifications_disabled_;
- }
-
private:
- void PopulateFromAppSpecifics(
- const sync_pb::AppSpecifics& specifics);
- void PopulateFromExtensionSpecifics(
- const sync_pb::ExtensionSpecifics& specifics);
+ // Populate this class from sync inputs.
void PopulateFromSyncData(const SyncData& sync_data);
std::string id_;
bool uninstalled_;
bool enabled_;
bool incognito_enabled_;
- Extension::SyncType type_;
Version version_;
GURL update_url_;
std::string name_;
- std::string notifications_client_id_;
- bool notifications_disabled_;
- StringOrdinal app_launch_ordinal_;
- StringOrdinal page_ordinal_;
};
+} // namespace extensions
+
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SYNC_DATA_H_
diff --git a/chrome/browser/extensions/extension_sync_data_unittest.cc b/chrome/browser/extensions/extension_sync_data_unittest.cc
index b269137..e92b74f 100644
--- a/chrome/browser/extensions/extension_sync_data_unittest.cc
+++ b/chrome/browser/extensions/extension_sync_data_unittest.cc
@@ -4,10 +4,10 @@
#include "chrome/browser/extensions/extension_sync_data.h"
+#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/version.h"
#include "googleurl/src/gurl.h"
-#include "sync/protocol/app_specifics.pb.h"
#include "sync/protocol/extension_specifics.pb.h"
#include "sync/protocol/sync.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -31,7 +31,6 @@ const char kValidUpdateUrl2[] =
"https://clients2.google.com/service/update2/crx";
const char kName[] = "MyExtension";
const char kName2[] = "MyExtension2";
-const char kOAuthClientId[] = "1234abcd";
class ExtensionSyncDataTest : public testing::Test {
};
@@ -48,7 +47,7 @@ TEST_F(ExtensionSyncDataTest, SyncDataToExtensionSyncDataForExtension) {
SyncData sync_data =
SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
- ExtensionSyncData extension_sync_data(sync_data);
+ extensions::ExtensionSyncData extension_sync_data(sync_data);
EXPECT_EQ(extension_specifics->id(), extension_sync_data.id());
EXPECT_EQ(extension_specifics->version(),
extension_sync_data.version().GetString());
@@ -72,7 +71,7 @@ TEST_F(ExtensionSyncDataTest, ExtensionSyncDataToSyncDataForExtension) {
input_extension->set_name(kName);
SyncData sync_data =
SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
- ExtensionSyncData extension_sync_data(sync_data);
+ extensions::ExtensionSyncData extension_sync_data(sync_data);
SyncData output_sync_data = extension_sync_data.GetSyncData();
const sync_pb::ExtensionSpecifics& output_specifics =
@@ -88,109 +87,4 @@ TEST_F(ExtensionSyncDataTest, ExtensionSyncDataToSyncDataForExtension) {
EXPECT_EQ(extension_sync_data.name(), output_specifics.name());
}
-TEST_F(ExtensionSyncDataTest, SyncDataToExtensionSyncDataForApp) {
- sync_pb::EntitySpecifics entity;
- sync_pb::AppSpecifics* app_specifics = entity.mutable_app();
- app_specifics->set_app_launch_ordinal(
- StringOrdinal::CreateInitialOrdinal().ToString());
- app_specifics->set_page_ordinal(
- StringOrdinal::CreateInitialOrdinal().ToString());
-
- sync_pb::ExtensionSpecifics* extension_specifics =
- app_specifics->mutable_extension();
- extension_specifics->set_id(kValidId);
- extension_specifics->set_update_url(kValidUpdateUrl2);
- extension_specifics->set_enabled(false);
- extension_specifics->set_incognito_enabled(true);
- extension_specifics->set_version(kVersion1);
- extension_specifics->set_name(kName);
- sync_pb::AppNotificationSettings* notif_settings =
- app_specifics->mutable_notification_settings();
- notif_settings->set_oauth_client_id(kOAuthClientId);
- notif_settings->set_disabled(true);
- SyncData sync_data =
- SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
-
- ExtensionSyncData extension_sync_data(sync_data);
- EXPECT_EQ(app_specifics->app_launch_ordinal(),
- extension_sync_data.app_launch_ordinal().ToString());
- EXPECT_EQ(app_specifics->page_ordinal(),
- extension_sync_data.page_ordinal().ToString());
- EXPECT_EQ(extension_specifics->id(), extension_sync_data.id());
- EXPECT_EQ(extension_specifics->version(),
- extension_sync_data.version().GetString());
- EXPECT_EQ(extension_specifics->update_url(),
- extension_sync_data.update_url().spec());
- EXPECT_EQ(extension_specifics->enabled(), extension_sync_data.enabled());
- EXPECT_EQ(extension_specifics->incognito_enabled(),
- extension_sync_data.incognito_enabled());
- EXPECT_EQ(extension_specifics->name(), extension_sync_data.name());
- EXPECT_FALSE(extension_sync_data.uninstalled());
- EXPECT_EQ(notif_settings->oauth_client_id(),
- extension_sync_data.notifications_client_id());
- EXPECT_EQ(notif_settings->disabled(),
- extension_sync_data.notifications_disabled());
-}
-
-TEST_F(ExtensionSyncDataTest, ExtensionSyncDataToSyncDataForApp) {
- sync_pb::EntitySpecifics entity;
- sync_pb::AppSpecifics* input_specifics = entity.mutable_app();
- input_specifics->set_app_launch_ordinal(
- StringOrdinal::CreateInitialOrdinal().ToString());
- input_specifics->set_page_ordinal(
- StringOrdinal::CreateInitialOrdinal().ToString());
-
- sync_pb::ExtensionSpecifics* input_extension =
- input_specifics->mutable_extension();
- input_extension->set_id(kValidId);
- input_extension->set_update_url(kValidUpdateUrl2);
- input_extension->set_enabled(true);
- input_extension->set_incognito_enabled(false);
- input_extension->set_version(kVersion1);
- input_extension->set_name(kName);
- sync_pb::AppNotificationSettings* notif_settings =
- input_specifics->mutable_notification_settings();
- notif_settings->set_oauth_client_id(kOAuthClientId);
- notif_settings->set_disabled(true);
- SyncData sync_data =
- SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
- ExtensionSyncData extension_sync_data(sync_data);
-
- SyncData output_sync_data = extension_sync_data.GetSyncData();
- EXPECT_TRUE(sync_data.GetSpecifics().has_app());
- const sync_pb::AppSpecifics& output_specifics =
- output_sync_data.GetSpecifics().app();
- EXPECT_EQ(input_specifics->SerializeAsString(),
- output_specifics.SerializeAsString());
-}
-
-// Ensures that invalid StringOrdinals don't break ExtensionSyncData.
-TEST_F(ExtensionSyncDataTest, ExtensionSyncDataInvalidOrdinal) {
- sync_pb::EntitySpecifics entity;
- sync_pb::AppSpecifics* app_specifics = entity.mutable_app();
- // Set the ordinals as invalid.
- app_specifics->set_app_launch_ordinal("");
- app_specifics->set_page_ordinal("");
-
- sync_pb::ExtensionSpecifics* extension_specifics =
- app_specifics->mutable_extension();
- extension_specifics->set_id(kValidId);
- extension_specifics->set_update_url(kValidUpdateUrl2);
- extension_specifics->set_enabled(false);
- extension_specifics->set_incognito_enabled(true);
- extension_specifics->set_version(kVersion1);
- extension_specifics->set_name(kName);
- sync_pb::AppNotificationSettings* notif_settings =
- app_specifics->mutable_notification_settings();
- notif_settings->set_oauth_client_id(kOAuthClientId);
- notif_settings->set_disabled(true);
- SyncData sync_data =
- SyncData::CreateLocalData("sync_tag", "non_unique_title", entity);
-
- ExtensionSyncData extension_sync_data(sync_data);
-
- // Try loading the synced data back out, there should be no problems.
- extension_sync_data.PopulateAppSpecifics(app_specifics);
-}
-
} // namespace