Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Unified Diff: chrome/browser/extensions/extension_action_storage_manager.cc

Issue 502033003: Move ExtensionActionStorageManager out of extension_action_api.* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Latest master for CQ Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/extension_action_storage_manager.cc
diff --git a/chrome/browser/extensions/extension_action_storage_manager.cc b/chrome/browser/extensions/extension_action_storage_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..56ff5c4983678e09346a7b7870edc7ef07afc785
--- /dev/null
+++ b/chrome/browser/extensions/extension_action_storage_manager.cc
@@ -0,0 +1,279 @@
+// Copyright 2014 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_action_storage_manager.h"
+
+#include "base/base64.h"
+#include "base/bind.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/extension_action.h"
+#include "chrome/browser/extensions/extension_action_manager.h"
+#include "extensions/browser/extension_registry.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/state_store.h"
+#include "extensions/common/constants.h"
+#include "ui/base/layout.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace extensions {
+
+namespace {
+
+const char kBrowserActionStorageKey[] = "browser_action";
+const char kPopupUrlStorageKey[] = "poupup_url";
+const char kTitleStorageKey[] = "title";
+const char kIconStorageKey[] = "icon";
+const char kBadgeTextStorageKey[] = "badge_text";
+const char kBadgeBackgroundColorStorageKey[] = "badge_background_color";
+const char kBadgeTextColorStorageKey[] = "badge_text_color";
+const char kAppearanceStorageKey[] = "appearance";
+
+// Only add values to the end of this enum, since it's stored in the user's
+// Extension State, under the kAppearanceStorageKey. It represents the
+// ExtensionAction's default visibility.
+enum StoredAppearance {
+ // The action icon is hidden.
+ INVISIBLE = 0,
+ // The action is trying to get the user's attention but isn't yet
+ // running on the page. Was only used for script badges.
+ OBSOLETE_WANTS_ATTENTION = 1,
+ // The action icon is visible with its normal appearance.
+ ACTIVE = 2,
+};
+
+// Conversion function for reading/writing to storage.
+SkColor RawStringToSkColor(const std::string& str) {
+ uint64 value = 0;
+ base::StringToUint64(str, &value);
+ SkColor color = static_cast<SkColor>(value);
+ DCHECK(value == color); // ensure value fits into color's 32 bits
+ return color;
+}
+
+// Conversion function for reading/writing to storage.
+std::string SkColorToRawString(SkColor color) {
+ return base::Uint64ToString(color);
+}
+
+// Conversion function for reading/writing to storage.
+bool StringToSkBitmap(const std::string& str, SkBitmap* bitmap) {
+ // TODO(mpcomplete): Remove the base64 encode/decode step when
+ // http://crbug.com/140546 is fixed.
+ std::string raw_str;
+ if (!base::Base64Decode(str, &raw_str))
+ return false;
+
+ bool success = gfx::PNGCodec::Decode(
+ reinterpret_cast<unsigned const char*>(raw_str.data()), raw_str.size(),
+ bitmap);
+ return success;
+}
+
+// Conversion function for reading/writing to storage.
+std::string RepresentationToString(const gfx::ImageSkia& image, float scale) {
+ SkBitmap bitmap = image.GetRepresentation(scale).sk_bitmap();
+ SkAutoLockPixels lock_image(bitmap);
+ std::vector<unsigned char> data;
+ bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
+ if (!success)
+ return std::string();
+
+ base::StringPiece raw_str(
+ reinterpret_cast<const char*>(&data[0]), data.size());
+ std::string base64_str;
+ base::Base64Encode(raw_str, &base64_str);
+ return base64_str;
+}
+
+// Set |action|'s default values to those specified in |dict|.
+void SetDefaultsFromValue(const base::DictionaryValue* dict,
+ ExtensionAction* action) {
+ const int kDefaultTabId = ExtensionAction::kDefaultTabId;
+ std::string str_value;
+ int int_value;
+ SkBitmap bitmap;
+ gfx::ImageSkia icon;
+
+ // For each value, don't set it if it has been modified already.
+ if (dict->GetString(kPopupUrlStorageKey, &str_value) &&
+ !action->HasPopupUrl(kDefaultTabId)) {
+ action->SetPopupUrl(kDefaultTabId, GURL(str_value));
+ }
+ if (dict->GetString(kTitleStorageKey, &str_value) &&
+ !action->HasTitle(kDefaultTabId)) {
+ action->SetTitle(kDefaultTabId, str_value);
+ }
+ if (dict->GetString(kBadgeTextStorageKey, &str_value) &&
+ !action->HasBadgeText(kDefaultTabId)) {
+ action->SetBadgeText(kDefaultTabId, str_value);
+ }
+ if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value) &&
+ !action->HasBadgeBackgroundColor(kDefaultTabId)) {
+ action->SetBadgeBackgroundColor(kDefaultTabId,
+ RawStringToSkColor(str_value));
+ }
+ if (dict->GetString(kBadgeTextColorStorageKey, &str_value) &&
+ !action->HasBadgeTextColor(kDefaultTabId)) {
+ action->SetBadgeTextColor(kDefaultTabId, RawStringToSkColor(str_value));
+ }
+ if (dict->GetInteger(kAppearanceStorageKey, &int_value) &&
+ !action->HasIsVisible(kDefaultTabId)) {
+ switch (int_value) {
+ case INVISIBLE:
+ case OBSOLETE_WANTS_ATTENTION:
+ action->SetIsVisible(kDefaultTabId, false);
+ break;
+ case ACTIVE:
+ action->SetIsVisible(kDefaultTabId, true);
+ break;
+ }
+ }
+
+ const base::DictionaryValue* icon_value = NULL;
+ if (dict->GetDictionary(kIconStorageKey, &icon_value) &&
+ !action->HasIcon(kDefaultTabId)) {
+ for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) {
+ const extension_misc::IconRepresentationInfo& icon_info =
+ extension_misc::kExtensionActionIconSizes[i];
+ if (icon_value->GetString(icon_info.size_string, &str_value) &&
+ StringToSkBitmap(str_value, &bitmap)) {
+ CHECK(!bitmap.isNull());
+ float scale = ui::GetScaleForScaleFactor(icon_info.scale);
+ icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale));
+ }
+ }
+ action->SetIcon(kDefaultTabId, gfx::Image(icon));
+ }
+}
+
+// Store |action|'s default values in a DictionaryValue for use in storing to
+// disk.
+scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) {
+ const int kDefaultTabId = ExtensionAction::kDefaultTabId;
+ scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+
+ dict->SetString(kPopupUrlStorageKey,
+ action->GetPopupUrl(kDefaultTabId).spec());
+ dict->SetString(kTitleStorageKey, action->GetTitle(kDefaultTabId));
+ dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kDefaultTabId));
+ dict->SetString(
+ kBadgeBackgroundColorStorageKey,
+ SkColorToRawString(action->GetBadgeBackgroundColor(kDefaultTabId)));
+ dict->SetString(kBadgeTextColorStorageKey,
+ SkColorToRawString(action->GetBadgeTextColor(kDefaultTabId)));
+ dict->SetInteger(kAppearanceStorageKey,
+ action->GetIsVisible(kDefaultTabId) ? ACTIVE : INVISIBLE);
+
+ gfx::ImageSkia icon = action->GetExplicitlySetIcon(kDefaultTabId);
+ if (!icon.isNull()) {
+ scoped_ptr<base::DictionaryValue> icon_value(new base::DictionaryValue());
+ for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) {
+ const extension_misc::IconRepresentationInfo& icon_info =
+ extension_misc::kExtensionActionIconSizes[i];
+ float scale = ui::GetScaleForScaleFactor(icon_info.scale);
+ if (icon.HasRepresentation(scale)) {
+ icon_value->SetString(icon_info.size_string,
+ RepresentationToString(icon, scale));
+ }
+ }
+ dict->Set(kIconStorageKey, icon_value.release());
+ }
+ return dict.Pass();
+}
+
+} // namespace
+
+ExtensionActionStorageManager::ExtensionActionStorageManager(
+ content::BrowserContext* context)
+ : browser_context_(context),
+ extension_action_observer_(this),
+ extension_registry_observer_(this),
+ weak_factory_(this) {
+ extension_action_observer_.Add(ExtensionActionAPI::Get(browser_context_));
+ extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
+
+ StateStore* store = GetStateStore();
+ if (store)
+ store->RegisterKey(kBrowserActionStorageKey);
+}
+
+ExtensionActionStorageManager::~ExtensionActionStorageManager() {
+}
+
+void ExtensionActionStorageManager::OnExtensionLoaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension) {
+ if (!ExtensionActionManager::Get(browser_context_)->GetBrowserAction(
+ *extension))
+ return;
+
+ StateStore* store = GetStateStore();
+ if (store) {
+ store->GetExtensionValue(
+ extension->id(),
+ kBrowserActionStorageKey,
+ base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
+ weak_factory_.GetWeakPtr(),
+ extension->id()));
+ }
+}
+
+void ExtensionActionStorageManager::OnExtensionActionUpdated(
+ ExtensionAction* extension_action,
+ content::WebContents* web_contents,
+ content::BrowserContext* browser_context) {
+ if (browser_context_ == browser_context &&
+ extension_action->action_type() == ActionInfo::TYPE_BROWSER)
+ WriteToStorage(extension_action);
+}
+
+void ExtensionActionStorageManager::OnExtensionActionAPIShuttingDown() {
+ extension_action_observer_.RemoveAll();
+}
+
+void ExtensionActionStorageManager::WriteToStorage(
+ ExtensionAction* extension_action) {
+ StateStore* store = GetStateStore();
+ if (store) {
+ scoped_ptr<base::DictionaryValue> defaults =
+ DefaultsToValue(extension_action);
+ store->SetExtensionValue(extension_action->extension_id(),
+ kBrowserActionStorageKey,
+ defaults.PassAs<base::Value>());
+ }
+}
+
+void ExtensionActionStorageManager::ReadFromStorage(
+ const std::string& extension_id, scoped_ptr<base::Value> value) {
+ const Extension* extension = ExtensionRegistry::Get(browser_context_)->
+ enabled_extensions().GetByID(extension_id);
+ if (!extension)
+ return;
+
+ ExtensionAction* browser_action =
+ ExtensionActionManager::Get(browser_context_)->GetBrowserAction(
+ *extension);
+ if (!browser_action) {
+ // This can happen if the extension is updated between startup and when the
+ // storage read comes back, and the update removes the browser action.
+ // http://crbug.com/349371
+ return;
+ }
+
+ const base::DictionaryValue* dict = NULL;
+ if (!value.get() || !value->GetAsDictionary(&dict))
+ return;
+
+ SetDefaultsFromValue(dict, browser_action);
+}
+
+StateStore* ExtensionActionStorageManager::GetStateStore() {
+ return ExtensionSystem::Get(browser_context_)->state_store();
+}
+
+} // namespace extensions
« no previous file with comments | « chrome/browser/extensions/extension_action_storage_manager.h ('k') | chrome/browser/extensions/extension_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698