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

Unified Diff: chrome/browser/extensions/api/extension_action/extension_actions_api.cc

Issue 10837155: Persist browserAction settings to the extension StateStore. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 8 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/api/extension_action/extension_actions_api.cc
diff --git a/chrome/browser/extensions/api/extension_action/extension_actions_api.cc b/chrome/browser/extensions/api/extension_action/extension_actions_api.cc
index 975fc6f72d8163ba9f0be37807f90050705dd97b..e2eab675f7918a778b4e17fe873ea30931f56be8 100644
--- a/chrome/browser/extensions/api/extension_action/extension_actions_api.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_actions_api.cc
@@ -6,14 +6,17 @@
#include <string>
+#include "base/base64.h"
#include "base/string_number_conversions.h"
#include "base/string_piece.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/extension_action/extension_page_actions_api_constants.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/tab_helper.h"
Yoyo Zhou 2012/08/08 01:21:06 nit: not in sorted order
Matt Perry 2012/08/08 01:40:08 Done.
+#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/location_bar_controller.h"
+#include "chrome/browser/extensions/state_store.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/common/chrome_notification_types.h"
@@ -26,14 +29,208 @@
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";
+
// Errors.
const char kNoExtensionActionError[] =
"This extension has no action specified.";
const char kNoTabError[] = "No tab with id: *.";
const char kIconIndexOutOfBounds[] = "Page action icon index out of bounds.";
+// Conversion function for reading/writing to storage.
+SkColor RawStringToSkColor(const std::string& str) {
+ uint64 value = 0;
+ base::StringToUint64(str, &value);
Yoyo Zhou 2012/08/08 01:21:06 Why not check that this returns true?
Matt Perry 2012/08/08 01:40:08 We'll return 0 either way.
+ SkColor color = static_cast<SkColor>(value);
+ DCHECK(value == color);
Yoyo Zhou 2012/08/08 01:21:06 This seems like overkill.
Matt Perry 2012/08/08 01:40:08 SkColor is 32-bit. I want to make sure the int con
+ 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): Our state store can't hold binary data.
Yoyo Zhou 2012/08/08 01:21:06 nit: rephrase this as an action you could do.
Matt Perry 2012/08/08 01:40:08 Done.
+ std::string raw_str;
+ if (!base::Base64Decode(str, &raw_str))
+ return false;
+ IPC::Message bitmap_pickle(raw_str.data(), raw_str.size());
+ PickleIterator iter(bitmap_pickle);
+ return IPC::ReadParam(&bitmap_pickle, &iter, bitmap);
+}
+
+// Conversion function for reading/writing to storage.
+std::string ImageToString(const gfx::Image& image) {
+ IPC::Message bitmap_pickle;
+ IPC::WriteParam(&bitmap_pickle, image.AsBitmap());
+ std::string raw_str(static_cast<const char*>(bitmap_pickle.data()),
+ bitmap_pickle.size());
+ std::string base64_str;
+ if (!base::Base64Encode(raw_str, &base64_str))
+ return std::string();
+ return base64_str;
+}
+
+// Set |action|'s default values to those specified in |dict|.
+void DefaultsFromValue(const base::DictionaryValue* dict,
Yoyo Zhou 2012/08/08 01:21:06 "SetDefaultsFromValue"?
Matt Perry 2012/08/08 01:40:08 Done.
+ ExtensionAction* action) {
+ const int kTabId = ExtensionAction::kDefaultTabId;
+ std::string str_value;
+ int int_value;
+ SkBitmap bitmap;
+
+ if (dict->GetString(kPopupUrlStorageKey, &str_value))
+ action->SetPopupUrl(kTabId, GURL(str_value));
+ if (dict->GetString(kTitleStorageKey, &str_value))
+ action->SetTitle(kTabId, str_value);
+ if (dict->GetString(kBadgeTextStorageKey, &str_value))
+ action->SetBadgeText(kTabId, str_value);
+ if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value))
+ action->SetBadgeBackgroundColor(kTabId, RawStringToSkColor(str_value));
+ if (dict->GetString(kBadgeTextColorStorageKey, &str_value))
+ action->SetBadgeTextColor(kTabId, RawStringToSkColor(str_value));
+ if (dict->GetInteger(kAppearanceStorageKey, &int_value))
+ action->SetAppearance(kTabId,
+ static_cast<ExtensionAction::Appearance>(int_value));
+ if (dict->GetString(kIconStorageKey, &str_value) &&
+ StringToSkBitmap(str_value, &bitmap))
+ action->SetIcon(kTabId, bitmap);
+}
+
+// Store |action|'s default values in a DictionaryValue for use in storing to
+// disk.
+scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) {
+ const int kTabId = ExtensionAction::kDefaultTabId;
+ scoped_ptr<base::DictionaryValue> dict(new DictionaryValue());
+
+ dict->SetString(kPopupUrlStorageKey, action->GetPopupUrl(kTabId).spec());
+ dict->SetString(kTitleStorageKey, action->GetTitle(kTabId));
+ dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kTabId));
+ dict->SetString(kBadgeBackgroundColorStorageKey,
+ SkColorToRawString(action->GetBadgeBackgroundColor(kTabId)));
+ dict->SetString(kBadgeTextColorStorageKey,
+ SkColorToRawString(action->GetBadgeTextColor(kTabId)));
+ dict->SetInteger(kAppearanceStorageKey,
+ action->GetIsVisible(kTabId) ?
+ ExtensionAction::ACTIVE : ExtensionAction::INVISIBLE);
+ dict->SetString(kIconStorageKey, ImageToString(action->GetIcon(kTabId)));
+
+ return dict.Pass();
+}
+
+}
Yoyo Zhou 2012/08/08 01:21:06 // namespace
Matt Perry 2012/08/08 01:40:08 Done.
+
+namespace extensions {
+
+//
+// ExtensionActionStorageManager
+//
+
+ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile)
+ : profile_(profile) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
+ content::Source<Profile>(profile_));
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
+ content::NotificationService::AllBrowserContextsAndSources());
+
+ StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+ if (storage)
+ storage->RegisterKey(kBrowserActionStorageKey);
+}
+
+ExtensionActionStorageManager::~ExtensionActionStorageManager() {
}
+void ExtensionActionStorageManager::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_EXTENSION_LOADED: {
+ const Extension* extension =
+ content::Details<const Extension>(details).ptr();
+ if (!extension->browser_action())
+ break;
+
+ StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+ if (storage) {
+ storage->GetExtensionValue(extension->id(), kBrowserActionStorageKey,
+ base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
+ AsWeakPtr(), extension->id()));
+ }
+ break;
+ }
+ case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: {
+ ExtensionAction* extension_action =
+ content::Source<ExtensionAction>(source).ptr();
+ Profile* profile = content::Details<Profile>(details).ptr();
+ if (profile != profile_)
+ break;
+
+ extension_action->set_defaults_have_changed(true);
+ WriteToStorage(extension_action);
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+void ExtensionActionStorageManager::WriteToStorage(
+ ExtensionAction* extension_action) {
+ StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
+ if (!storage)
+ return;
+
+ scoped_ptr<base::DictionaryValue> defaults =
+ DefaultsToValue(extension_action);
+ storage->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 =
+ ExtensionSystem::Get(profile_)->extension_service()->
+ GetExtensionById(extension_id, true);
+ if (!extension)
+ return;
+
+ CHECK(extension->browser_action());
+
+ // Don't load values from storage if the extension has updated a value
+ // already. The extension may have only updated some of the values, but
+ // this is a good first approximation. If the extension is doing stuff
+ // to the browser action, we can assume it is ready to take over.
+ if (extension->browser_action()->defaults_have_changed())
+ return;
+
+ base::DictionaryValue* dict = NULL;
+ if (!value.get() || !value->GetAsDictionary(&dict))
+ return;
+
+ DefaultsFromValue(dict, extension->browser_action());
+}
+
+} // namespace extensions
+
+
+//
+// ExtensionActionFunction
+//
+
ExtensionActionFunction::ExtensionActionFunction()
: details_(NULL),
tab_id_(ExtensionAction::kDefaultTabId),
@@ -137,7 +334,7 @@ void ExtensionActionFunction::NotifyBrowserActionChange() {
content::NotificationService::current()->Notify(
chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
content::Source<ExtensionAction>(extension_action_),
- content::NotificationService::NoDetails());
+ content::Details<Profile>(profile()));
}
void ExtensionActionFunction::NotifyLocationBarChange() {
@@ -210,8 +407,7 @@ bool ExtensionActionSetIconFunction::RunExtensionAction() {
IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize());
PickleIterator iter(bitmap_pickle);
SkBitmap bitmap;
- EXTENSION_FUNCTION_VALIDATE(
- IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
+ EXTENSION_FUNCTION_VALIDATE(IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
extension_action_->SetIcon(tab_id_, bitmap);
} else if (details_->GetInteger("iconIndex", &icon_index)) {
// If --enable-script-badges is on there might legitimately be an iconIndex

Powered by Google App Engine
This is Rietveld 408576698