summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/glue/theme_util.cc
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-07-29 17:14:53 +0100
committerBen Murdoch <benm@google.com>2010-08-04 14:29:45 +0100
commitc407dc5cd9bdc5668497f21b26b09d988ab439de (patch)
tree7eaf8707c0309516bdb042ad976feedaf72b0bb1 /chrome/browser/sync/glue/theme_util.cc
parent0998b1cdac5733f299c12d88bc31ef9c8035b8fa (diff)
downloadexternal_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.zip
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.gz
external_chromium-c407dc5cd9bdc5668497f21b26b09d988ab439de.tar.bz2
Merge Chromium src@r53293
Change-Id: Ia79acf8670f385cee48c45b0a75371d8e950af34
Diffstat (limited to 'chrome/browser/sync/glue/theme_util.cc')
-rw-r--r--chrome/browser/sync/glue/theme_util.cc223
1 files changed, 223 insertions, 0 deletions
diff --git a/chrome/browser/sync/glue/theme_util.cc b/chrome/browser/sync/glue/theme_util.cc
new file mode 100644
index 0000000..d4ed722
--- /dev/null
+++ b/chrome/browser/sync/glue/theme_util.cc
@@ -0,0 +1,223 @@
+// Copyright (c) 2010 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/sync/glue/theme_util.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/version.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
+#include "chrome/browser/extensions/extension_updater.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#if defined(TOOLKIT_USES_GTK)
+#include "chrome/browser/gtk/gtk_theme_provider.h"
+#endif
+#include "chrome/browser/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/sync/protocol/theme_specifics.pb.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/pref_names.h"
+#include "googleurl/src/gurl.h"
+
+namespace browser_sync {
+
+const char kCurrentThemeClientTag[] = "current_theme";
+
+namespace {
+
+bool IsSystemThemeDistinctFromDefaultTheme() {
+#if defined(TOOLKIT_USES_GTK)
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool UseSystemTheme(Profile* profile) {
+#if defined(TOOLKIT_USES_GTK)
+ return GtkThemeProvider::GetFrom(profile)->UseGtkTheme();
+#else
+ return false;
+#endif
+}
+
+} // namespace
+
+bool AreThemeSpecificsEqual(const sync_pb::ThemeSpecifics& a,
+ const sync_pb::ThemeSpecifics& b) {
+ return AreThemeSpecificsEqualHelper(
+ a, b, IsSystemThemeDistinctFromDefaultTheme());
+}
+
+bool AreThemeSpecificsEqualHelper(
+ const sync_pb::ThemeSpecifics& a,
+ const sync_pb::ThemeSpecifics& b,
+ bool is_system_theme_distinct_from_default_theme) {
+ if (a.use_custom_theme() != b.use_custom_theme()) {
+ return false;
+ }
+
+ if (a.use_custom_theme()) {
+ // We're using a custom theme, so simply compare IDs since those
+ // are guaranteed unique.
+ return a.custom_theme_id() == b.custom_theme_id();
+ } else if (is_system_theme_distinct_from_default_theme) {
+ // We're not using a custom theme, but we care about system
+ // vs. default.
+ return a.use_system_theme_by_default() == b.use_system_theme_by_default();
+ } else {
+ // We're not using a custom theme, and we don't care about system
+ // vs. default.
+ return true;
+ }
+}
+
+void SetCurrentThemeFromThemeSpecifics(
+ const sync_pb::ThemeSpecifics& theme_specifics,
+ Profile* profile) {
+ DCHECK(profile);
+ if (theme_specifics.use_custom_theme()) {
+ // TODO(akalin): Figure out what to do about third-party themes
+ // (i.e., those not on either Google gallery).
+ std::string id(theme_specifics.custom_theme_id());
+ GURL update_url(theme_specifics.custom_theme_update_url());
+ LOG(INFO) << "Applying theme " << id << " with update_url "
+ << update_url;
+ ExtensionsService* extensions_service = profile->GetExtensionsService();
+ CHECK(extensions_service);
+ Extension* extension = extensions_service->GetExtensionById(id, true);
+ if (extension) {
+ if (!extension->is_theme()) {
+ LOG(INFO) << "Extension " << id << " is not a theme; aborting";
+ return;
+ }
+ ExtensionPrefs* extension_prefs = extensions_service->extension_prefs();
+ CHECK(extension_prefs);
+ // TODO(akalin): GetExtensionState() isn't very safe as it
+ // returns Extension::ENABLED by default; either change it to
+ // return something else by default or create a separate
+ // function that does so.
+ if (extension_prefs->GetExtensionState(extension->id()) !=
+ Extension::ENABLED) {
+ LOG(INFO) << "Theme " << id << " is not enabled; aborting";
+ return;
+ }
+ // Get previous theme info before we set the new theme.
+ std::string previous_theme_id;
+ {
+ const Extension* current_theme = profile->GetTheme();
+ if (current_theme) {
+ DCHECK(current_theme->is_theme());
+ previous_theme_id = current_theme->id();
+ }
+ }
+ bool previous_use_system_theme = UseSystemTheme(profile);
+ // An enabled theme extension with the given id was found, so
+ // just set the current theme to it.
+ profile->SetTheme(extension);
+ // Pretend the theme was just installed.
+ ExtensionInstallUI::ShowThemeInfoBar(
+ previous_theme_id, previous_use_system_theme,
+ extension, profile);
+ } else {
+ // No extension with this id exists -- we must install it; we do
+ // so by adding it as a pending extension and then triggering an
+ // auto-update cycle.
+ const bool kIsTheme = true;
+ // Themes don't need to install silently as they just pop up an
+ // informational dialog after installation instead of a
+ // confirmation dialog.
+ const bool kInstallSilently = false;
+ const bool kEnableOnInstall = true;
+ const bool kEnableIncognitoOnInstall = false;
+ extensions_service->AddPendingExtension(
+ id, update_url, kIsTheme, kInstallSilently,
+ kEnableOnInstall, kEnableIncognitoOnInstall);
+ ExtensionUpdater* extension_updater = extensions_service->updater();
+ // Auto-updates should now be on always (see the construction of
+ // the ExtensionsService in ProfileImpl::InitExtensions()).
+ if (!extension_updater) {
+ LOG(DFATAL) << "Extension updater unexpectedly NULL; "
+ << "auto-updates may be turned off";
+ return;
+ }
+ extension_updater->CheckNow();
+ }
+ } else if (theme_specifics.use_system_theme_by_default()) {
+ profile->SetNativeTheme();
+ } else {
+ profile->ClearTheme();
+ }
+}
+
+bool UpdateThemeSpecificsOrSetCurrentThemeIfNecessary(
+ Profile* profile, sync_pb::ThemeSpecifics* theme_specifics) {
+ if (!theme_specifics->use_custom_theme() &&
+ (profile->GetTheme() || (UseSystemTheme(profile) &&
+ IsSystemThemeDistinctFromDefaultTheme()))) {
+ GetThemeSpecificsFromCurrentTheme(profile, theme_specifics);
+ return true;
+ } else {
+ SetCurrentThemeFromThemeSpecificsIfNecessary(*theme_specifics, profile);
+ return false;
+ }
+}
+
+void GetThemeSpecificsFromCurrentTheme(
+ Profile* profile,
+ sync_pb::ThemeSpecifics* theme_specifics) {
+ DCHECK(profile);
+ const Extension* current_theme = profile->GetTheme();
+ if (current_theme) {
+ DCHECK(current_theme->is_theme());
+ }
+ GetThemeSpecificsFromCurrentThemeHelper(
+ current_theme,
+ IsSystemThemeDistinctFromDefaultTheme(),
+ UseSystemTheme(profile),
+ theme_specifics);
+}
+
+void GetThemeSpecificsFromCurrentThemeHelper(
+ const Extension* current_theme,
+ bool is_system_theme_distinct_from_default_theme,
+ bool use_system_theme_by_default,
+ sync_pb::ThemeSpecifics* theme_specifics) {
+ bool use_custom_theme = (current_theme != NULL);
+ theme_specifics->set_use_custom_theme(use_custom_theme);
+ if (is_system_theme_distinct_from_default_theme) {
+ theme_specifics->set_use_system_theme_by_default(
+ use_system_theme_by_default);
+ } else {
+ DCHECK(!use_system_theme_by_default);
+ }
+ if (use_custom_theme) {
+ DCHECK(current_theme);
+ DCHECK(current_theme->is_theme());
+ theme_specifics->set_custom_theme_name(current_theme->name());
+ theme_specifics->set_custom_theme_id(current_theme->id());
+ theme_specifics->set_custom_theme_update_url(
+ current_theme->update_url().spec());
+ } else {
+ DCHECK(!current_theme);
+ theme_specifics->clear_custom_theme_name();
+ theme_specifics->clear_custom_theme_id();
+ theme_specifics->clear_custom_theme_update_url();
+ }
+}
+
+void SetCurrentThemeFromThemeSpecificsIfNecessary(
+ const sync_pb::ThemeSpecifics& theme_specifics, Profile* profile) {
+ DCHECK(profile);
+ sync_pb::ThemeSpecifics old_theme_specifics;
+ GetThemeSpecificsFromCurrentTheme(profile, &old_theme_specifics);
+ if (!AreThemeSpecificsEqual(old_theme_specifics, theme_specifics)) {
+ SetCurrentThemeFromThemeSpecifics(theme_specifics, profile);
+ }
+}
+
+} // namespace browser_sync