OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/common/extensions/api/themes/theme_handler.h" | 5 #include "chrome/common/extensions/manifest_handlers/theme_handler.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/common/extensions/extension_manifest_constants.h" | 11 #include "chrome/common/extensions/extension_manifest_constants.h" |
12 #include "chrome/common/extensions/manifest.h" | 12 #include "chrome/common/extensions/manifest.h" |
13 #include "grit/generated_resources.h" | 13 #include "grit/generated_resources.h" |
14 #include "ui/base/l10n/l10n_util.h" | 14 #include "ui/base/l10n/l10n_util.h" |
15 | 15 |
| 16 using base::DictionaryValue; |
| 17 |
16 namespace extensions { | 18 namespace extensions { |
17 | 19 |
18 namespace keys = extension_manifest_keys; | 20 namespace keys = extension_manifest_keys; |
19 namespace errors = extension_manifest_errors; | 21 namespace errors = extension_manifest_errors; |
20 | 22 |
21 namespace { | 23 namespace { |
22 | 24 |
23 bool LoadThemeImages(const DictionaryValue* theme_value, | 25 bool LoadImages(const DictionaryValue* theme_value, |
24 string16* error, | 26 string16* error, |
25 ThemeInfo* theme_info) { | 27 ThemeInfo* theme_info) { |
26 const DictionaryValue* images_value = NULL; | 28 const DictionaryValue* images_value = NULL; |
27 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { | 29 if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) { |
28 // Validate that the images are all strings. | 30 // Validate that the images are all strings. |
29 for (DictionaryValue::Iterator iter(*images_value); !iter.IsAtEnd(); | 31 for (DictionaryValue::Iterator iter(*images_value); !iter.IsAtEnd(); |
30 iter.Advance()) { | 32 iter.Advance()) { |
31 if (!iter.value().IsType(Value::TYPE_STRING)) { | 33 if (!iter.value().IsType(Value::TYPE_STRING)) { |
32 *error = ASCIIToUTF16(errors::kInvalidThemeImages); | 34 *error = ASCIIToUTF16(errors::kInvalidThemeImages); |
33 return false; | 35 return false; |
34 } | 36 } |
35 } | 37 } |
36 theme_info->theme_images_.reset(images_value->DeepCopy()); | 38 theme_info->theme_images_.reset(images_value->DeepCopy()); |
37 } | 39 } |
38 return true; | 40 return true; |
39 } | 41 } |
40 | 42 |
41 bool LoadThemeColors(const DictionaryValue* theme_value, | 43 bool LoadColors(const DictionaryValue* theme_value, |
42 string16* error, | 44 string16* error, |
43 ThemeInfo* theme_info) { | 45 ThemeInfo* theme_info) { |
44 const DictionaryValue* colors_value = NULL; | 46 const DictionaryValue* colors_value = NULL; |
45 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { | 47 if (theme_value->GetDictionary(keys::kThemeColors, &colors_value)) { |
46 // Validate that the colors are RGB or RGBA lists. | 48 // Validate that the colors are RGB or RGBA lists. |
47 for (DictionaryValue::Iterator iter(*colors_value); !iter.IsAtEnd(); | 49 for (DictionaryValue::Iterator iter(*colors_value); !iter.IsAtEnd(); |
48 iter.Advance()) { | 50 iter.Advance()) { |
49 const ListValue* color_list = NULL; | 51 const ListValue* color_list = NULL; |
50 double alpha = 0.0; | 52 double alpha = 0.0; |
51 int color = 0; | 53 int color = 0; |
52 // The color must be a list... | 54 // The color must be a list... |
53 if (!iter.value().GetAsList(&color_list) || | 55 if (!iter.value().GetAsList(&color_list) || |
54 // ... and either 3 items (RGB) or 4 (RGBA). | 56 // ... and either 3 items (RGB) or 4 (RGBA). |
55 ((color_list->GetSize() != 3) && | 57 ((color_list->GetSize() != 3) && |
56 ((color_list->GetSize() != 4) || | 58 ((color_list->GetSize() != 4) || |
57 // For RGBA, the fourth item must be a real or int alpha value. | 59 // For RGBA, the fourth item must be a real or int alpha value. |
58 // Note that GetDouble() can get an integer value. | 60 // Note that GetDouble() can get an integer value. |
59 !color_list->GetDouble(3, &alpha))) || | 61 !color_list->GetDouble(3, &alpha))) || |
60 // For both RGB and RGBA, the first three items must be ints (R,G,B). | 62 // For both RGB and RGBA, the first three items must be ints (R,G,B). |
61 !color_list->GetInteger(0, &color) || | 63 !color_list->GetInteger(0, &color) || |
62 !color_list->GetInteger(1, &color) || | 64 !color_list->GetInteger(1, &color) || |
63 !color_list->GetInteger(2, &color)) { | 65 !color_list->GetInteger(2, &color)) { |
64 *error = ASCIIToUTF16(errors::kInvalidThemeColors); | 66 *error = ASCIIToUTF16(errors::kInvalidThemeColors); |
65 return false; | 67 return false; |
66 } | 68 } |
67 } | 69 } |
68 theme_info->theme_colors_.reset(colors_value->DeepCopy()); | 70 theme_info->theme_colors_.reset(colors_value->DeepCopy()); |
69 } | 71 } |
70 return true; | 72 return true; |
71 } | 73 } |
72 | 74 |
73 bool LoadThemeTints(const DictionaryValue* theme_value, | 75 bool LoadTints(const DictionaryValue* theme_value, |
74 string16* error, | 76 string16* error, |
75 ThemeInfo* theme_info) { | 77 ThemeInfo* theme_info) { |
76 const DictionaryValue* tints_value = NULL; | 78 const DictionaryValue* tints_value = NULL; |
77 if (!theme_value->GetDictionary(keys::kThemeTints, &tints_value)) | 79 if (!theme_value->GetDictionary(keys::kThemeTints, &tints_value)) |
78 return true; | 80 return true; |
79 | 81 |
80 // Validate that the tints are all reals. | 82 // Validate that the tints are all reals. |
81 for (DictionaryValue::Iterator iter(*tints_value); !iter.IsAtEnd(); | 83 for (DictionaryValue::Iterator iter(*tints_value); !iter.IsAtEnd(); |
82 iter.Advance()) { | 84 iter.Advance()) { |
83 const ListValue* tint_list = NULL; | 85 const ListValue* tint_list = NULL; |
84 double v = 0.0; | 86 double v = 0.0; |
85 if (!iter.value().GetAsList(&tint_list) || | 87 if (!iter.value().GetAsList(&tint_list) || |
86 tint_list->GetSize() != 3 || | 88 tint_list->GetSize() != 3 || |
87 !tint_list->GetDouble(0, &v) || | 89 !tint_list->GetDouble(0, &v) || |
88 !tint_list->GetDouble(1, &v) || | 90 !tint_list->GetDouble(1, &v) || |
89 !tint_list->GetDouble(2, &v)) { | 91 !tint_list->GetDouble(2, &v)) { |
90 *error = ASCIIToUTF16(errors::kInvalidThemeTints); | 92 *error = ASCIIToUTF16(errors::kInvalidThemeTints); |
91 return false; | 93 return false; |
92 } | 94 } |
93 } | 95 } |
94 theme_info->theme_tints_.reset(tints_value->DeepCopy()); | 96 theme_info->theme_tints_.reset(tints_value->DeepCopy()); |
95 return true; | 97 return true; |
96 } | 98 } |
97 | 99 |
98 bool LoadThemeDisplayProperties(const DictionaryValue* theme_value, | 100 bool LoadDisplayProperties(const DictionaryValue* theme_value, |
99 string16* error, | 101 string16* error, |
100 ThemeInfo* theme_info) { | 102 ThemeInfo* theme_info) { |
101 const DictionaryValue* display_properties_value = NULL; | 103 const DictionaryValue* display_properties_value = NULL; |
102 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, | 104 if (theme_value->GetDictionary(keys::kThemeDisplayProperties, |
103 &display_properties_value)) { | 105 &display_properties_value)) { |
104 theme_info->theme_display_properties_.reset( | 106 theme_info->theme_display_properties_.reset( |
105 display_properties_value->DeepCopy()); | 107 display_properties_value->DeepCopy()); |
106 } | 108 } |
107 return true; | 109 return true; |
108 } | 110 } |
109 | 111 |
110 const ThemeInfo* GetThemeInfo(const Extension* extension) { | 112 const ThemeInfo* GetInfo(const Extension* extension) { |
111 return static_cast<ThemeInfo*>(extension->GetManifestData(keys::kTheme)); | 113 return static_cast<ThemeInfo*>(extension->GetManifestData(keys::kTheme)); |
112 } | 114 } |
113 | 115 |
114 } // namespace | 116 } // namespace |
115 | 117 |
116 ThemeInfo::ThemeInfo() { | 118 ThemeInfo::ThemeInfo() { |
117 } | 119 } |
118 | 120 |
119 ThemeInfo::~ThemeInfo() { | 121 ThemeInfo::~ThemeInfo() { |
120 } | 122 } |
121 | 123 |
122 // static | 124 // static |
123 DictionaryValue* ThemeInfo::GetThemeImages(const Extension* extension) { | 125 const DictionaryValue* ThemeInfo::GetImages(const Extension* extension) { |
124 const ThemeInfo* theme_info = GetThemeInfo(extension); | 126 const ThemeInfo* theme_info = GetInfo(extension); |
125 return theme_info ? theme_info->theme_images_.get() : NULL; | 127 return theme_info ? theme_info->theme_images_.get() : NULL; |
126 } | 128 } |
127 | 129 |
128 // static | 130 // static |
129 DictionaryValue* ThemeInfo::GetThemeColors(const Extension* extension) { | 131 const DictionaryValue* ThemeInfo::GetColors(const Extension* extension) { |
130 const ThemeInfo* theme_info = GetThemeInfo(extension); | 132 const ThemeInfo* theme_info = GetInfo(extension); |
131 return theme_info ? theme_info->theme_colors_.get() : NULL; | 133 return theme_info ? theme_info->theme_colors_.get() : NULL; |
132 } | 134 } |
133 | 135 |
134 // static | 136 // static |
135 DictionaryValue* ThemeInfo::GetThemeTints(const Extension* extension) { | 137 const DictionaryValue* ThemeInfo::GetTints(const Extension* extension) { |
136 const ThemeInfo* theme_info = GetThemeInfo(extension); | 138 const ThemeInfo* theme_info = GetInfo(extension); |
137 return theme_info ? theme_info->theme_tints_.get() : NULL; | 139 return theme_info ? theme_info->theme_tints_.get() : NULL; |
138 } | 140 } |
139 | 141 |
140 // static | 142 // static |
141 DictionaryValue* ThemeInfo::GetThemeDisplayProperties( | 143 const DictionaryValue* ThemeInfo::GetDisplayProperties( |
142 const Extension* extension) { | 144 const Extension* extension) { |
143 const ThemeInfo* theme_info = GetThemeInfo(extension); | 145 const ThemeInfo* theme_info = GetInfo(extension); |
144 return theme_info ? theme_info->theme_display_properties_.get() : NULL; | 146 return theme_info ? theme_info->theme_display_properties_.get() : NULL; |
145 } | 147 } |
146 | 148 |
147 ThemeHandler::ThemeHandler() { | 149 ThemeHandler::ThemeHandler() { |
148 } | 150 } |
149 | 151 |
150 ThemeHandler::~ThemeHandler() { | 152 ThemeHandler::~ThemeHandler() { |
151 } | 153 } |
152 | 154 |
153 bool ThemeHandler::Parse(Extension* extension, string16* error) { | 155 bool ThemeHandler::Parse(Extension* extension, string16* error) { |
154 const DictionaryValue* theme_value = NULL; | 156 const DictionaryValue* theme_value = NULL; |
155 if (!extension->manifest()->GetDictionary(keys::kTheme, &theme_value)) { | 157 if (!extension->manifest()->GetDictionary(keys::kTheme, &theme_value)) { |
156 *error = ASCIIToUTF16(errors::kInvalidTheme); | 158 *error = ASCIIToUTF16(errors::kInvalidTheme); |
157 return false; | 159 return false; |
158 } | 160 } |
159 | 161 |
160 scoped_ptr<ThemeInfo> theme_info(new ThemeInfo); | 162 scoped_ptr<ThemeInfo> theme_info(new ThemeInfo); |
161 if (!LoadThemeImages(theme_value, error, theme_info.get())) | 163 if (!LoadImages(theme_value, error, theme_info.get())) |
162 return false; | 164 return false; |
163 if (!LoadThemeColors(theme_value, error, theme_info.get())) | 165 if (!LoadColors(theme_value, error, theme_info.get())) |
164 return false; | 166 return false; |
165 if (!LoadThemeTints(theme_value, error, theme_info.get())) | 167 if (!LoadTints(theme_value, error, theme_info.get())) |
166 return false; | 168 return false; |
167 if (!LoadThemeDisplayProperties(theme_value, error, theme_info.get())) | 169 if (!LoadDisplayProperties(theme_value, error, theme_info.get())) |
168 return false; | 170 return false; |
169 | 171 |
170 extension->SetManifestData(keys::kTheme, theme_info.release()); | 172 extension->SetManifestData(keys::kTheme, theme_info.release()); |
171 return true; | 173 return true; |
172 } | 174 } |
173 | 175 |
174 bool ThemeHandler::Validate(const Extension* extension, | 176 bool ThemeHandler::Validate(const Extension* extension, |
175 std::string* error, | 177 std::string* error, |
176 std::vector<InstallWarning>* warnings) const { | 178 std::vector<InstallWarning>* warnings) const { |
177 // Validate that theme images exist. | 179 // Validate that theme images exist. |
178 if (extension->is_theme()) { | 180 if (extension->is_theme()) { |
179 DictionaryValue* images_value = | 181 const DictionaryValue* images_value = |
180 extensions::ThemeInfo::GetThemeImages(extension); | 182 extensions::ThemeInfo::GetImages(extension); |
181 if (images_value) { | 183 if (images_value) { |
182 for (DictionaryValue::Iterator iter(*images_value); !iter.IsAtEnd(); | 184 for (DictionaryValue::Iterator iter(*images_value); !iter.IsAtEnd(); |
183 iter.Advance()) { | 185 iter.Advance()) { |
184 std::string val; | 186 std::string val; |
185 if (iter.value().GetAsString(&val)) { | 187 if (iter.value().GetAsString(&val)) { |
186 base::FilePath image_path = extension->path().Append( | 188 base::FilePath image_path = extension->path().Append( |
187 base::FilePath::FromUTF8Unsafe(val)); | 189 base::FilePath::FromUTF8Unsafe(val)); |
188 if (!file_util::PathExists(image_path)) { | 190 if (!file_util::PathExists(image_path)) { |
189 *error = | 191 *error = |
190 l10n_util::GetStringFUTF8(IDS_EXTENSION_INVALID_IMAGE_PATH, | 192 l10n_util::GetStringFUTF8(IDS_EXTENSION_INVALID_IMAGE_PATH, |
191 image_path.LossyDisplayName()); | 193 image_path.LossyDisplayName()); |
192 return false; | 194 return false; |
193 } | 195 } |
194 } | 196 } |
195 } | 197 } |
196 } | 198 } |
197 } | 199 } |
198 return true; | 200 return true; |
199 } | 201 } |
200 | 202 |
201 const std::vector<std::string> ThemeHandler::Keys() const { | 203 const std::vector<std::string> ThemeHandler::Keys() const { |
202 return SingleKey(keys::kTheme); | 204 return SingleKey(keys::kTheme); |
203 } | 205 } |
204 | 206 |
205 } // namespace extensions | 207 } // namespace extensions |
OLD | NEW |