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

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: yoyo 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/extension_system.h"
15 #include "chrome/browser/extensions/extension_tab_util.h" 16 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/extensions/location_bar_controller.h" 17 #include "chrome/browser/extensions/location_bar_controller.h"
18 #include "chrome/browser/extensions/state_store.h"
19 #include "chrome/browser/extensions/tab_helper.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);
51 SkColor color = static_cast<SkColor>(value);
52 DCHECK(value == color); // ensure value fits into color's 32 bits
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): Remove the base64 encode/decode step when
64 // http://crbug.com/140546 is fixed.
65 std::string raw_str;
66 if (!base::Base64Decode(str, &raw_str))
67 return false;
68 IPC::Message bitmap_pickle(raw_str.data(), raw_str.size());
69 PickleIterator iter(bitmap_pickle);
70 return IPC::ReadParam(&bitmap_pickle, &iter, bitmap);
71 }
72
73 // Conversion function for reading/writing to storage.
74 std::string ImageToString(const gfx::Image& image) {
75 IPC::Message bitmap_pickle;
76 IPC::WriteParam(&bitmap_pickle, image.AsBitmap());
77 std::string raw_str(static_cast<const char*>(bitmap_pickle.data()),
78 bitmap_pickle.size());
79 std::string base64_str;
80 if (!base::Base64Encode(raw_str, &base64_str))
81 return std::string();
82 return base64_str;
83 }
84
85 // Set |action|'s default values to those specified in |dict|.
86 void SetDefaultsFromValue(const base::DictionaryValue* dict,
87 ExtensionAction* action) {
88 const int kTabId = ExtensionAction::kDefaultTabId;
89 std::string str_value;
90 int int_value;
91 SkBitmap bitmap;
92
93 if (dict->GetString(kPopupUrlStorageKey, &str_value))
94 action->SetPopupUrl(kTabId, GURL(str_value));
95 if (dict->GetString(kTitleStorageKey, &str_value))
96 action->SetTitle(kTabId, str_value);
97 if (dict->GetString(kBadgeTextStorageKey, &str_value))
98 action->SetBadgeText(kTabId, str_value);
99 if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value))
100 action->SetBadgeBackgroundColor(kTabId, RawStringToSkColor(str_value));
101 if (dict->GetString(kBadgeTextColorStorageKey, &str_value))
102 action->SetBadgeTextColor(kTabId, RawStringToSkColor(str_value));
103 if (dict->GetInteger(kAppearanceStorageKey, &int_value))
104 action->SetAppearance(kTabId,
105 static_cast<ExtensionAction::Appearance>(int_value));
106 if (dict->GetString(kIconStorageKey, &str_value) &&
107 StringToSkBitmap(str_value, &bitmap))
108 action->SetIcon(kTabId, bitmap);
109 }
110
111 // Store |action|'s default values in a DictionaryValue for use in storing to
112 // disk.
113 scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) {
114 const int kTabId = ExtensionAction::kDefaultTabId;
115 scoped_ptr<base::DictionaryValue> dict(new DictionaryValue());
116
117 dict->SetString(kPopupUrlStorageKey, action->GetPopupUrl(kTabId).spec());
118 dict->SetString(kTitleStorageKey, action->GetTitle(kTabId));
119 dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kTabId));
120 dict->SetString(kBadgeBackgroundColorStorageKey,
121 SkColorToRawString(action->GetBadgeBackgroundColor(kTabId)));
122 dict->SetString(kBadgeTextColorStorageKey,
123 SkColorToRawString(action->GetBadgeTextColor(kTabId)));
124 dict->SetInteger(kAppearanceStorageKey,
125 action->GetIsVisible(kTabId) ?
126 ExtensionAction::ACTIVE : ExtensionAction::INVISIBLE);
127 dict->SetString(kIconStorageKey, ImageToString(action->GetIcon(kTabId)));
128
129 return dict.Pass();
130 }
131
132 } // namespace
133
134 namespace extensions {
135
136 //
137 // ExtensionActionStorageManager
138 //
139
140 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile)
141 : profile_(profile) {
142 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
143 content::Source<Profile>(profile_));
144 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
145 content::NotificationService::AllBrowserContextsAndSources());
146
147 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
148 if (storage)
149 storage->RegisterKey(kBrowserActionStorageKey);
150 }
151
152 ExtensionActionStorageManager::~ExtensionActionStorageManager() {
153 }
154
155 void ExtensionActionStorageManager::Observe(
156 int type,
157 const content::NotificationSource& source,
158 const content::NotificationDetails& details) {
159 switch (type) {
160 case chrome::NOTIFICATION_EXTENSION_LOADED: {
161 const Extension* extension =
162 content::Details<const Extension>(details).ptr();
163 if (!extension->browser_action())
164 break;
165
166 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
167 if (storage) {
168 storage->GetExtensionValue(extension->id(), kBrowserActionStorageKey,
169 base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
170 AsWeakPtr(), extension->id()));
171 }
172 break;
173 }
174 case chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED: {
175 ExtensionAction* extension_action =
176 content::Source<ExtensionAction>(source).ptr();
177 Profile* profile = content::Details<Profile>(details).ptr();
178 if (profile != profile_)
179 break;
180
181 extension_action->set_has_changed(true);
182 WriteToStorage(extension_action);
183 break;
184 }
185 default:
186 NOTREACHED();
187 break;
188 }
189 }
190
191 void ExtensionActionStorageManager::WriteToStorage(
192 ExtensionAction* extension_action) {
193 StateStore* storage = ExtensionSystem::Get(profile_)->state_store();
194 if (!storage)
195 return;
196
197 scoped_ptr<base::DictionaryValue> defaults =
198 DefaultsToValue(extension_action);
199 storage->SetExtensionValue(extension_action->extension_id(),
200 kBrowserActionStorageKey,
201 defaults.PassAs<base::Value>());
202 }
203
204 void ExtensionActionStorageManager::ReadFromStorage(
205 const std::string& extension_id, scoped_ptr<base::Value> value) {
206 const Extension* extension =
207 ExtensionSystem::Get(profile_)->extension_service()->
208 GetExtensionById(extension_id, true);
209 if (!extension)
210 return;
211
212 CHECK(extension->browser_action());
213
214 // Don't load values from storage if the extension has updated a value
215 // already. The extension may have only updated some of the values, but
216 // this is a good first approximation. If the extension is doing stuff
217 // to the browser action, we can assume it is ready to take over.
218 if (extension->browser_action()->has_changed())
219 return;
220
221 base::DictionaryValue* dict = NULL;
222 if (!value.get() || !value->GetAsDictionary(&dict))
223 return;
224
225 SetDefaultsFromValue(dict, extension->browser_action());
226 }
227
228 } // namespace extensions
229
230
231 //
232 // ExtensionActionFunction
233 //
36 234
37 ExtensionActionFunction::ExtensionActionFunction() 235 ExtensionActionFunction::ExtensionActionFunction()
38 : details_(NULL), 236 : details_(NULL),
39 tab_id_(ExtensionAction::kDefaultTabId), 237 tab_id_(ExtensionAction::kDefaultTabId),
40 contents_(NULL), 238 contents_(NULL),
41 extension_action_(NULL) { 239 extension_action_(NULL) {
42 } 240 }
43 241
44 ExtensionActionFunction::~ExtensionActionFunction() { 242 ExtensionActionFunction::~ExtensionActionFunction() {
45 } 243 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 NotifyLocationBarChange(); 328 NotifyLocationBarChange();
131 return; 329 return;
132 } 330 }
133 NOTREACHED(); 331 NOTREACHED();
134 } 332 }
135 333
136 void ExtensionActionFunction::NotifyBrowserActionChange() { 334 void ExtensionActionFunction::NotifyBrowserActionChange() {
137 content::NotificationService::current()->Notify( 335 content::NotificationService::current()->Notify(
138 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, 336 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED,
139 content::Source<ExtensionAction>(extension_action_), 337 content::Source<ExtensionAction>(extension_action_),
140 content::NotificationService::NoDetails()); 338 content::Details<Profile>(profile()));
141 } 339 }
142 340
143 void ExtensionActionFunction::NotifyLocationBarChange() { 341 void ExtensionActionFunction::NotifyLocationBarChange() {
144 contents_->extension_tab_helper()->location_bar_controller()->NotifyChange(); 342 contents_->extension_tab_helper()->location_bar_controller()->NotifyChange();
145 } 343 }
146 344
147 // static 345 // static
148 bool ExtensionActionFunction::ParseCSSColorString( 346 bool ExtensionActionFunction::ParseCSSColorString(
149 const std::string& color_string, 347 const std::string& color_string,
150 SkColor* result) { 348 SkColor* result) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 401
204 bool ExtensionActionSetIconFunction::RunExtensionAction() { 402 bool ExtensionActionSetIconFunction::RunExtensionAction() {
205 // setIcon can take a variant argument: either a canvas ImageData, or an 403 // setIcon can take a variant argument: either a canvas ImageData, or an
206 // icon index. 404 // icon index.
207 base::BinaryValue* binary = NULL; 405 base::BinaryValue* binary = NULL;
208 int icon_index; 406 int icon_index;
209 if (details_->GetBinary("imageData", &binary)) { 407 if (details_->GetBinary("imageData", &binary)) {
210 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize()); 408 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize());
211 PickleIterator iter(bitmap_pickle); 409 PickleIterator iter(bitmap_pickle);
212 SkBitmap bitmap; 410 SkBitmap bitmap;
213 EXTENSION_FUNCTION_VALIDATE( 411 EXTENSION_FUNCTION_VALIDATE(IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
214 IPC::ReadParam(&bitmap_pickle, &iter, &bitmap));
215 extension_action_->SetIcon(tab_id_, bitmap); 412 extension_action_->SetIcon(tab_id_, bitmap);
216 } else if (details_->GetInteger("iconIndex", &icon_index)) { 413 } else if (details_->GetInteger("iconIndex", &icon_index)) {
217 // If --enable-script-badges is on there might legitimately be an iconIndex 414 // If --enable-script-badges is on there might legitimately be an iconIndex
218 // set. Until we decide what to do with that, ignore. 415 // set. Until we decide what to do with that, ignore.
219 if (!GetExtension()->page_action()) 416 if (!GetExtension()->page_action())
220 return true; 417 return true;
221 if (icon_index < 0 || 418 if (icon_index < 0 ||
222 static_cast<size_t>(icon_index) >= 419 static_cast<size_t>(icon_index) >=
223 extension_action_->icon_paths()->size()) { 420 extension_action_->icon_paths()->size()) {
224 error_ = kIconIndexOutOfBounds; 421 error_ = kIconIndexOutOfBounds;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() { 506 bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() {
310 ListValue* list = new ListValue(); 507 ListValue* list = new ListValue();
311 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_); 508 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_);
312 list->Append(Value::CreateIntegerValue(SkColorGetR(color))); 509 list->Append(Value::CreateIntegerValue(SkColorGetR(color)));
313 list->Append(Value::CreateIntegerValue(SkColorGetG(color))); 510 list->Append(Value::CreateIntegerValue(SkColorGetG(color)));
314 list->Append(Value::CreateIntegerValue(SkColorGetB(color))); 511 list->Append(Value::CreateIntegerValue(SkColorGetB(color)));
315 list->Append(Value::CreateIntegerValue(SkColorGetA(color))); 512 list->Append(Value::CreateIntegerValue(SkColorGetA(color)));
316 SetResult(list); 513 SetResult(list);
317 return true; 514 return true;
318 } 515 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/extension_action/extension_actions_api.h ('k') | chrome/browser/extensions/extension_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698