OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |