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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/extension_action/extension_actions_api.h " 5 #include "chrome/browser/extensions/api/extension_action/extension_actions_api.h "
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h"
9 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
10 #include "base/string_piece.h" 11 #include "base/string_piece.h"
11 #include "base/values.h" 12 #include "base/values.h"
12 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_ api_constants.h" 13 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_ api_constants.h"
13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/tab_helper.h" 15 #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.
16 #include "chrome/browser/extensions/extension_system.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 17 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/extensions/location_bar_controller.h" 18 #include "chrome/browser/extensions/location_bar_controller.h"
19 #include "chrome/browser/extensions/state_store.h"
17 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/tab_contents/tab_contents.h" 21 #include "chrome/browser/ui/tab_contents/tab_contents.h"
19 #include "chrome/common/chrome_notification_types.h" 22 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/extensions/extension.h" 23 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_action.h" 24 #include "chrome/common/extensions/extension_action.h"
22 #include "chrome/common/extensions/extension_error_utils.h" 25 #include "chrome/common/extensions/extension_error_utils.h"
23 #include "chrome/common/render_messages.h" 26 #include "chrome/common/render_messages.h"
24 #include "content/public/browser/navigation_entry.h" 27 #include "content/public/browser/navigation_entry.h"
25 #include "content/public/browser/notification_service.h" 28 #include "content/public/browser/notification_service.h"
26 29
27 namespace { 30 namespace {
28 31
32 const char kBrowserActionStorageKey[] = "browser_action";
33 const char kPopupUrlStorageKey[] = "poupup_url";
34 const char kTitleStorageKey[] = "title";
35 const char kIconStorageKey[] = "icon";
36 const char kBadgeTextStorageKey[] = "badge_text";
37 const char kBadgeBackgroundColorStorageKey[] = "badge_background_color";
38 const char kBadgeTextColorStorageKey[] = "badge_text_color";
39 const char kAppearanceStorageKey[] = "appearance";
40
29 // Errors. 41 // Errors.
30 const char kNoExtensionActionError[] = 42 const char kNoExtensionActionError[] =
31 "This extension has no action specified."; 43 "This extension has no action specified.";
32 const char kNoTabError[] = "No tab with id: *."; 44 const char kNoTabError[] = "No tab with id: *.";
33 const char kIconIndexOutOfBounds[] = "Page action icon index out of bounds."; 45 const char kIconIndexOutOfBounds[] = "Page action icon index out of bounds.";
34 46
35 } 47 // Conversion function for reading/writing to storage.
48 SkColor RawStringToSkColor(const std::string& str) {
49 uint64 value = 0;
50 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.
51 SkColor color = static_cast<SkColor>(value);
52 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
53 return color;
54 }
55
56 // Conversion function for reading/writing to storage.
57 std::string SkColorToRawString(SkColor color) {
58 return base::Uint64ToString(color);
59 }
60
61 // Conversion function for reading/writing to storage.
62 bool StringToSkBitmap(const std::string& str, SkBitmap* bitmap) {
63 // 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.
64 std::string raw_str;
65 if (!base::Base64Decode(str, &raw_str))
66 return false;
67 IPC::Message bitmap_pickle(raw_str.data(), raw_str.size());
68 PickleIterator iter(bitmap_pickle);
69 return IPC::ReadParam(&bitmap_pickle, &iter, bitmap);
70 }
71
72 // Conversion function for reading/writing to storage.
73 std::string ImageToString(const gfx::Image& image) {
74 IPC::Message bitmap_pickle;
75 IPC::WriteParam(&bitmap_pickle, image.AsBitmap());
76 std::string raw_str(static_cast<const char*>(bitmap_pickle.data()),
77 bitmap_pickle.size());
78 std::string base64_str;
79 if (!base::Base64Encode(raw_str, &base64_str))
80 return std::string();
81 return base64_str;
82 }
83
84 // Set |action|'s default values to those specified in |dict|.
85 void DefaultsFromValue(const base::DictionaryValue* dict,
Yoyo Zhou 2012/08/08 01:21:06 "SetDefaultsFromValue"?
Matt Perry 2012/08/08 01:40:08 Done.
86 ExtensionAction* action) {
87 const int kTabId = ExtensionAction::kDefaultTabId;
88 std::string str_value;
89 int int_value;
90 SkBitmap bitmap;
91
92 if (dict->GetString(kPopupUrlStorageKey, &str_value))
93 action->SetPopupUrl(kTabId, GURL(str_value));
94 if (dict->GetString(kTitleStorageKey, &str_value))
95 action->SetTitle(kTabId, str_value);
96 if (dict->GetString(kBadgeTextStorageKey, &str_value))
97 action->SetBadgeText(kTabId, str_value);
98 if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value))
99 action->SetBadgeBackgroundColor(kTabId, RawStringToSkColor(str_value));
100 if (dict->GetString(kBadgeTextColorStorageKey, &str_value))
101 action->SetBadgeTextColor(kTabId, RawStringToSkColor(str_value));
102 if (dict->GetInteger(kAppearanceStorageKey, &int_value))
103 action->SetAppearance(kTabId,
104 static_cast<ExtensionAction::Appearance>(int_value));
105 if (dict->GetString(kIconStorageKey, &str_value) &&
106 StringToSkBitmap(str_value, &bitmap))
107 action->SetIcon(kTabId, bitmap);
108 }
109
110 // Store |action|'s default values in a DictionaryValue for use in storing to
111 // disk.
112 scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) {
113 const int kTabId = ExtensionAction::kDefaultTabId;
114 scoped_ptr<base::DictionaryValue> dict(new DictionaryValue());
115
116 dict->SetString(kPopupUrlStorageKey, action->GetPopupUrl(kTabId).spec());
117 dict->SetString(kTitleStorageKey, action->GetTitle(kTabId));
118 dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kTabId));
119 dict->SetString(kBadgeBackgroundColorStorageKey,
120 SkColorToRawString(action->GetBadgeBackgroundColor(kTabId)));
121 dict->SetString(kBadgeTextColorStorageKey,
122 SkColorToRawString(action->GetBadgeTextColor(kTabId)));
123 dict->SetInteger(kAppearanceStorageKey,
124 action->GetIsVisible(kTabId) ?
125 ExtensionAction::ACTIVE : ExtensionAction::INVISIBLE);
126 dict->SetString(kIconStorageKey, ImageToString(action->GetIcon(kTabId)));
127
128 return dict.Pass();
129 }
130
131 }
Yoyo Zhou 2012/08/08 01:21:06 // namespace
Matt Perry 2012/08/08 01:40:08 Done.
132
133 namespace extensions {
134
135 //
136 // ExtensionActionStorageManager
137 //
138
139 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile)
140 : profile_(profile) {
141 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
142 content::Source<Profile>(profile_));
143 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
144 content::NotificationService::AllBrowserContextsAndSources());
145
146 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
147 if (storage)
148 storage->RegisterKey(kBrowserActionStorageKey);
149 }
150
151 ExtensionActionStorageManager::~ExtensionActionStorageManager() {
152 }
153
154 void ExtensionActionStorageManager::Observe(
155 int type,
156 const content::NotificationSource& source,
157 const content::NotificationDetails& details) {
158 switch (type) {
159 case chrome::NOTIFICATION_EXTENSION_LOADED: {
160 const Extension* extension =
161 content::Details<const Extension>(details).ptr();
162 if (!extension->browser_action())
163 break;
164
165 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
166 if (storage) {
167 storage->GetExtensionValue(extension->id(), kBrowserActionStorageKey,
168 base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
169 AsWeakPtr(), extension->id()));
170 }
171 break;
172 }
173 case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: {
174 ExtensionAction* extension_action =
175 content::Source<ExtensionAction>(source).ptr();
176 Profile* profile = content::Details<Profile>(details).ptr();
177 if (profile != profile_)
178 break;
179
180 extension_action->set_defaults_have_changed(true);
181 WriteToStorage(extension_action);
182 break;
183 }
184 default:
185 NOTREACHED();
186 break;
187 }
188 }
189
190 void ExtensionActionStorageManager::WriteToStorage(
191 ExtensionAction* extension_action) {
192 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
193 if (!storage)
194 return;
195
196 scoped_ptr<base::DictionaryValue> defaults =
197 DefaultsToValue(extension_action);
198 storage->SetExtensionValue(extension_action->extension_id(),
199 kBrowserActionStorageKey,
200 defaults.PassAs<base::Value>());
201 }
202
203 void ExtensionActionStorageManager::ReadFromStorage(
204 const std::string& extension_id, scoped_ptr<base::Value> value) {
205 const Extension* extension =
206 ExtensionSystem::Get(profile_)->extension_service()->
207 GetExtensionById(extension_id, true);
208 if (!extension)
209 return;
210
211 CHECK(extension->browser_action());
212
213 // Don't load values from storage if the extension has updated a value
214 // already. The extension may have only updated some of the values, but
215 // this is a good first approximation. If the extension is doing stuff
216 // to the browser action, we can assume it is ready to take over.
217 if (extension->browser_action()->defaults_have_changed())
218 return;
219
220 base::DictionaryValue* dict = NULL;
221 if (!value.get() || !value->GetAsDictionary(&dict))
222 return;
223
224 DefaultsFromValue(dict, extension->browser_action());
225 }
226
227 } // namespace extensions
228
229
230 //
231 // ExtensionActionFunction
232 //
36 233
37 ExtensionActionFunction::ExtensionActionFunction() 234 ExtensionActionFunction::ExtensionActionFunction()
38 : details_(NULL), 235 : details_(NULL),
39 tab_id_(ExtensionAction::kDefaultTabId), 236 tab_id_(ExtensionAction::kDefaultTabId),
40 contents_(NULL), 237 contents_(NULL),
41 extension_action_(NULL) { 238 extension_action_(NULL) {
42 } 239 }
43 240
44 ExtensionActionFunction::~ExtensionActionFunction() { 241 ExtensionActionFunction::~ExtensionActionFunction() {
45 } 242 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 NotifyLocationBarChange(); 327 NotifyLocationBarChange();
131 return; 328 return;
132 } 329 }
133 NOTREACHED(); 330 NOTREACHED();
134 } 331 }
135 332
136 void ExtensionActionFunction::NotifyBrowserActionChange() { 333 void ExtensionActionFunction::NotifyBrowserActionChange() {
137 content::NotificationService::current()->Notify( 334 content::NotificationService::current()->Notify(
138 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, 335 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
139 content::Source<ExtensionAction>(extension_action_), 336 content::Source<ExtensionAction>(extension_action_),
140 content::NotificationService::NoDetails()); 337 content::Details<Profile>(profile()));
141 } 338 }
142 339
143 void ExtensionActionFunction::NotifyLocationBarChange() { 340 void ExtensionActionFunction::NotifyLocationBarChange() {
144 contents_->extension_tab_helper()->location_bar_controller()->NotifyChange(); 341 contents_->extension_tab_helper()->location_bar_controller()->NotifyChange();
145 } 342 }
146 343
147 // static 344 // static
148 bool ExtensionActionFunction::ParseCSSColorString( 345 bool ExtensionActionFunction::ParseCSSColorString(
149 const std::string& color_string, 346 const std::string& color_string,
150 SkColor* result) { 347 SkColor* result) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 400
204 bool ExtensionActionSetIconFunction::RunExtensionAction() { 401 bool ExtensionActionSetIconFunction::RunExtensionAction() {
205 // setIcon can take a variant argument: either a canvas ImageData, or an 402 // setIcon can take a variant argument: either a canvas ImageData, or an
206 // icon index. 403 // icon index.
207 base::BinaryValue* binary = NULL; 404 base::BinaryValue* binary = NULL;
208 int icon_index; 405 int icon_index;
209 if (details_->GetBinary("imageData", &binary)) { 406 if (details_->GetBinary("imageData", &binary)) {
210 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize()); 407 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize());
211 PickleIterator iter(bitmap_pickle); 408 PickleIterator iter(bitmap_pickle);
212 SkBitmap bitmap; 409 SkBitmap bitmap;
213 EXTENSION_FUNCTION_VALIDATE( 410 EXTENSION_FUNCTION_VALIDATE(IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
214 IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
215 extension_action_->SetIcon(tab_id_, bitmap); 411 extension_action_->SetIcon(tab_id_, bitmap);
216 } else if (details_->GetInteger("iconIndex", &icon_index)) { 412 } else if (details_->GetInteger("iconIndex", &icon_index)) {
217 // If --enable-script-badges is on there might legitimately be an iconIndex 413 // If --enable-script-badges is on there might legitimately be an iconIndex
218 // set. Until we decide what to do with that, ignore. 414 // set. Until we decide what to do with that, ignore.
219 if (!GetExtension()->page_action()) 415 if (!GetExtension()->page_action())
220 return true; 416 return true;
221 if (icon_index < 0 || 417 if (icon_index < 0 ||
222 static_cast<size_t>(icon_index) >= 418 static_cast<size_t>(icon_index) >=
223 extension_action_->icon_paths()->size()) { 419 extension_action_->icon_paths()->size()) {
224 error_ = kIconIndexOutOfBounds; 420 error_ = kIconIndexOutOfBounds;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() { 505 bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() {
310 ListValue* list = new ListValue(); 506 ListValue* list = new ListValue();
311 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_); 507 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_);
312 list->Append(Value::CreateIntegerValue(SkColorGetR(color))); 508 list->Append(Value::CreateIntegerValue(SkColorGetR(color)));
313 list->Append(Value::CreateIntegerValue(SkColorGetG(color))); 509 list->Append(Value::CreateIntegerValue(SkColorGetG(color)));
314 list->Append(Value::CreateIntegerValue(SkColorGetB(color))); 510 list->Append(Value::CreateIntegerValue(SkColorGetB(color)));
315 list->Append(Value::CreateIntegerValue(SkColorGetA(color))); 511 list->Append(Value::CreateIntegerValue(SkColorGetA(color)));
316 SetResult(list); 512 SetResult(list);
317 return true; 513 return true;
318 } 514 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698