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

Side by Side 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, 3 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/extensions/extension_action_storage_manager.h"
6
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/extension_action.h"
13 #include "chrome/browser/extensions/extension_action_manager.h"
14 #include "extensions/browser/extension_registry.h"
15 #include "extensions/browser/extension_system.h"
16 #include "extensions/browser/state_store.h"
17 #include "extensions/common/constants.h"
18 #include "ui/base/layout.h"
19 #include "ui/gfx/codec/png_codec.h"
20 #include "ui/gfx/image/image.h"
21 #include "ui/gfx/image/image_skia.h"
22
23 namespace extensions {
24
25 namespace {
26
27 const char kBrowserActionStorageKey[] = "browser_action";
28 const char kPopupUrlStorageKey[] = "poupup_url";
29 const char kTitleStorageKey[] = "title";
30 const char kIconStorageKey[] = "icon";
31 const char kBadgeTextStorageKey[] = "badge_text";
32 const char kBadgeBackgroundColorStorageKey[] = "badge_background_color";
33 const char kBadgeTextColorStorageKey[] = "badge_text_color";
34 const char kAppearanceStorageKey[] = "appearance";
35
36 // Only add values to the end of this enum, since it's stored in the user's
37 // Extension State, under the kAppearanceStorageKey. It represents the
38 // ExtensionAction's default visibility.
39 enum StoredAppearance {
40 // The action icon is hidden.
41 INVISIBLE = 0,
42 // The action is trying to get the user's attention but isn't yet
43 // running on the page. Was only used for script badges.
44 OBSOLETE_WANTS_ATTENTION = 1,
45 // The action icon is visible with its normal appearance.
46 ACTIVE = 2,
47 };
48
49 // Conversion function for reading/writing to storage.
50 SkColor RawStringToSkColor(const std::string& str) {
51 uint64 value = 0;
52 base::StringToUint64(str, &value);
53 SkColor color = static_cast<SkColor>(value);
54 DCHECK(value == color); // ensure value fits into color's 32 bits
55 return color;
56 }
57
58 // Conversion function for reading/writing to storage.
59 std::string SkColorToRawString(SkColor color) {
60 return base::Uint64ToString(color);
61 }
62
63 // Conversion function for reading/writing to storage.
64 bool StringToSkBitmap(const std::string& str, SkBitmap* bitmap) {
65 // TODO(mpcomplete): Remove the base64 encode/decode step when
66 // http://crbug.com/140546 is fixed.
67 std::string raw_str;
68 if (!base::Base64Decode(str, &raw_str))
69 return false;
70
71 bool success = gfx::PNGCodec::Decode(
72 reinterpret_cast<unsigned const char*>(raw_str.data()), raw_str.size(),
73 bitmap);
74 return success;
75 }
76
77 // Conversion function for reading/writing to storage.
78 std::string RepresentationToString(const gfx::ImageSkia& image, float scale) {
79 SkBitmap bitmap = image.GetRepresentation(scale).sk_bitmap();
80 SkAutoLockPixels lock_image(bitmap);
81 std::vector<unsigned char> data;
82 bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
83 if (!success)
84 return std::string();
85
86 base::StringPiece raw_str(
87 reinterpret_cast<const char*>(&data[0]), data.size());
88 std::string base64_str;
89 base::Base64Encode(raw_str, &base64_str);
90 return base64_str;
91 }
92
93 // Set |action|'s default values to those specified in |dict|.
94 void SetDefaultsFromValue(const base::DictionaryValue* dict,
95 ExtensionAction* action) {
96 const int kDefaultTabId = ExtensionAction::kDefaultTabId;
97 std::string str_value;
98 int int_value;
99 SkBitmap bitmap;
100 gfx::ImageSkia icon;
101
102 // For each value, don't set it if it has been modified already.
103 if (dict->GetString(kPopupUrlStorageKey, &str_value) &&
104 !action->HasPopupUrl(kDefaultTabId)) {
105 action->SetPopupUrl(kDefaultTabId, GURL(str_value));
106 }
107 if (dict->GetString(kTitleStorageKey, &str_value) &&
108 !action->HasTitle(kDefaultTabId)) {
109 action->SetTitle(kDefaultTabId, str_value);
110 }
111 if (dict->GetString(kBadgeTextStorageKey, &str_value) &&
112 !action->HasBadgeText(kDefaultTabId)) {
113 action->SetBadgeText(kDefaultTabId, str_value);
114 }
115 if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value) &&
116 !action->HasBadgeBackgroundColor(kDefaultTabId)) {
117 action->SetBadgeBackgroundColor(kDefaultTabId,
118 RawStringToSkColor(str_value));
119 }
120 if (dict->GetString(kBadgeTextColorStorageKey, &str_value) &&
121 !action->HasBadgeTextColor(kDefaultTabId)) {
122 action->SetBadgeTextColor(kDefaultTabId, RawStringToSkColor(str_value));
123 }
124 if (dict->GetInteger(kAppearanceStorageKey, &int_value) &&
125 !action->HasIsVisible(kDefaultTabId)) {
126 switch (int_value) {
127 case INVISIBLE:
128 case OBSOLETE_WANTS_ATTENTION:
129 action->SetIsVisible(kDefaultTabId, false);
130 break;
131 case ACTIVE:
132 action->SetIsVisible(kDefaultTabId, true);
133 break;
134 }
135 }
136
137 const base::DictionaryValue* icon_value = NULL;
138 if (dict->GetDictionary(kIconStorageKey, &icon_value) &&
139 !action->HasIcon(kDefaultTabId)) {
140 for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) {
141 const extension_misc::IconRepresentationInfo& icon_info =
142 extension_misc::kExtensionActionIconSizes[i];
143 if (icon_value->GetString(icon_info.size_string, &str_value) &&
144 StringToSkBitmap(str_value, &bitmap)) {
145 CHECK(!bitmap.isNull());
146 float scale = ui::GetScaleForScaleFactor(icon_info.scale);
147 icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale));
148 }
149 }
150 action->SetIcon(kDefaultTabId, gfx::Image(icon));
151 }
152 }
153
154 // Store |action|'s default values in a DictionaryValue for use in storing to
155 // disk.
156 scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) {
157 const int kDefaultTabId = ExtensionAction::kDefaultTabId;
158 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
159
160 dict->SetString(kPopupUrlStorageKey,
161 action->GetPopupUrl(kDefaultTabId).spec());
162 dict->SetString(kTitleStorageKey, action->GetTitle(kDefaultTabId));
163 dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kDefaultTabId));
164 dict->SetString(
165 kBadgeBackgroundColorStorageKey,
166 SkColorToRawString(action->GetBadgeBackgroundColor(kDefaultTabId)));
167 dict->SetString(kBadgeTextColorStorageKey,
168 SkColorToRawString(action->GetBadgeTextColor(kDefaultTabId)));
169 dict->SetInteger(kAppearanceStorageKey,
170 action->GetIsVisible(kDefaultTabId) ? ACTIVE : INVISIBLE);
171
172 gfx::ImageSkia icon = action->GetExplicitlySetIcon(kDefaultTabId);
173 if (!icon.isNull()) {
174 scoped_ptr<base::DictionaryValue> icon_value(new base::DictionaryValue());
175 for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) {
176 const extension_misc::IconRepresentationInfo& icon_info =
177 extension_misc::kExtensionActionIconSizes[i];
178 float scale = ui::GetScaleForScaleFactor(icon_info.scale);
179 if (icon.HasRepresentation(scale)) {
180 icon_value->SetString(icon_info.size_string,
181 RepresentationToString(icon, scale));
182 }
183 }
184 dict->Set(kIconStorageKey, icon_value.release());
185 }
186 return dict.Pass();
187 }
188
189 } // namespace
190
191 ExtensionActionStorageManager::ExtensionActionStorageManager(
192 content::BrowserContext* context)
193 : browser_context_(context),
194 extension_action_observer_(this),
195 extension_registry_observer_(this),
196 weak_factory_(this) {
197 extension_action_observer_.Add(ExtensionActionAPI::Get(browser_context_));
198 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));
199
200 StateStore* store = GetStateStore();
201 if (store)
202 store->RegisterKey(kBrowserActionStorageKey);
203 }
204
205 ExtensionActionStorageManager::~ExtensionActionStorageManager() {
206 }
207
208 void ExtensionActionStorageManager::OnExtensionLoaded(
209 content::BrowserContext* browser_context,
210 const Extension* extension) {
211 if (!ExtensionActionManager::Get(browser_context_)->GetBrowserAction(
212 *extension))
213 return;
214
215 StateStore* store = GetStateStore();
216 if (store) {
217 store->GetExtensionValue(
218 extension->id(),
219 kBrowserActionStorageKey,
220 base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
221 weak_factory_.GetWeakPtr(),
222 extension->id()));
223 }
224 }
225
226 void ExtensionActionStorageManager::OnExtensionActionUpdated(
227 ExtensionAction* extension_action,
228 content::WebContents* web_contents,
229 content::BrowserContext* browser_context) {
230 if (browser_context_ == browser_context &&
231 extension_action->action_type() == ActionInfo::TYPE_BROWSER)
232 WriteToStorage(extension_action);
233 }
234
235 void ExtensionActionStorageManager::OnExtensionActionAPIShuttingDown() {
236 extension_action_observer_.RemoveAll();
237 }
238
239 void ExtensionActionStorageManager::WriteToStorage(
240 ExtensionAction* extension_action) {
241 StateStore* store = GetStateStore();
242 if (store) {
243 scoped_ptr<base::DictionaryValue> defaults =
244 DefaultsToValue(extension_action);
245 store->SetExtensionValue(extension_action->extension_id(),
246 kBrowserActionStorageKey,
247 defaults.PassAs<base::Value>());
248 }
249 }
250
251 void ExtensionActionStorageManager::ReadFromStorage(
252 const std::string& extension_id, scoped_ptr<base::Value> value) {
253 const Extension* extension = ExtensionRegistry::Get(browser_context_)->
254 enabled_extensions().GetByID(extension_id);
255 if (!extension)
256 return;
257
258 ExtensionAction* browser_action =
259 ExtensionActionManager::Get(browser_context_)->GetBrowserAction(
260 *extension);
261 if (!browser_action) {
262 // This can happen if the extension is updated between startup and when the
263 // storage read comes back, and the update removes the browser action.
264 // http://crbug.com/349371
265 return;
266 }
267
268 const base::DictionaryValue* dict = NULL;
269 if (!value.get() || !value->GetAsDictionary(&dict))
270 return;
271
272 SetDefaultsFromValue(dict, browser_action);
273 }
274
275 StateStore* ExtensionActionStorageManager::GetStateStore() {
276 return ExtensionSystem::Get(browser_context_)->state_store();
277 }
278
279 } // namespace extensions
OLDNEW
« 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