Chromium Code Reviews| 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/string_number_conversions.h" | |
| 9 #include "base/values.h" | 10 #include "base/values.h" |
| 10 #include "base/string_number_conversions.h" | 11 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_ api_constants.h" |
|
Aaron Boodman
2012/04/26 05:30:54
There's no reason for these separate constants fil
not at google - send to devlin
2012/04/26 06:01:57
Merge which files?
Aaron Boodman
2012/04/26 06:25:36
Nevermind, I didn't read this carefully.
| |
| 12 #include "chrome/browser/extensions/extension_service.h" | |
| 13 #include "chrome/browser/extensions/extension_tab_helper.h" | |
| 14 #include "chrome/browser/extensions/extension_tab_util.h" | |
| 15 #include "chrome/browser/profiles/profile.h" | |
| 16 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
| 17 #include "chrome/common/chrome_notification_types.h" | |
| 11 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
| 19 #include "chrome/common/extensions/extension_action.h" | |
| 20 #include "chrome/common/extensions/extension_error_utils.h" | |
| 12 #include "chrome/common/render_messages.h" | 21 #include "chrome/common/render_messages.h" |
| 22 #include "content/public/browser/navigation_entry.h" | |
| 23 #include "content/public/browser/notification_service.h" | |
| 24 | |
| 25 namespace { | |
| 26 | |
| 27 // Errors. | |
| 28 const char kNoExtensionActionError[] = | |
| 29 "This extension has no action specified."; | |
| 30 const char kNoTabError[] = "No tab with id: *."; | |
| 31 const char kIconIndexOutOfBounds[] = "Page action icon index out of bounds."; | |
| 32 | |
| 33 } | |
| 13 | 34 |
| 14 ExtensionActionFunction::ExtensionActionFunction() | 35 ExtensionActionFunction::ExtensionActionFunction() |
| 15 : details_(NULL), | 36 : details_(NULL), |
| 16 tab_id_(ExtensionAction::kDefaultTabId), | 37 tab_id_(ExtensionAction::kDefaultTabId), |
| 38 contents_(NULL), | |
| 17 extension_action_(NULL) { | 39 extension_action_(NULL) { |
| 18 } | 40 } |
| 19 | 41 |
| 20 ExtensionActionFunction::~ExtensionActionFunction() { | 42 ExtensionActionFunction::~ExtensionActionFunction() { |
| 21 } | 43 } |
| 22 | 44 |
| 23 bool ExtensionActionFunction::RunImpl() { | 45 bool ExtensionActionFunction::RunImpl() { |
| 24 base::Value* arg; | 46 extension_action_ = GetExtension()->browser_action(); |
| 25 args_->Get(0, &arg); | 47 if (!extension_action_) |
| 26 if (arg->IsType(base::Value::TYPE_DICTIONARY)) { | 48 extension_action_ = GetExtension()->page_action(); |
| 27 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details_)); | 49 EXTENSION_FUNCTION_VALIDATE(extension_action_); |
| 28 EXTENSION_FUNCTION_VALIDATE(details_ != NULL); | 50 |
| 29 if (details_->HasKey("tabId")) | 51 // There may or may not be details (depends on the function). |
| 30 EXTENSION_FUNCTION_VALIDATE(details_->GetInteger("tabId", &tab_id_)); | 52 // The tabId might appear in details (if it exists) or as the first |
| 53 // argument besides the action type (depends on the function). | |
| 54 { | |
| 55 base::Value* arg = NULL; | |
| 56 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &arg)); | |
| 57 if (arg->GetType() == Value::TYPE_INTEGER) { | |
|
Aaron Boodman
2012/04/26 05:30:54
Nit: There's IsType().
not at google - send to devlin
2012/04/26 06:01:57
I'm innocent!
I'm going to switch. I like switchi
| |
| 58 CHECK(arg->GetAsInteger(&tab_id_)); | |
| 59 } else if (arg->GetType() == Value::TYPE_DICTIONARY) { | |
| 60 details_ = static_cast<base::DictionaryValue*>(arg); | |
| 61 if (details_->HasKey("tabId")) | |
| 62 EXTENSION_FUNCTION_VALIDATE(details_->GetInteger("tabId", &tab_id_)); | |
| 63 } else { | |
| 64 EXTENSION_FUNCTION_VALIDATE(false); | |
|
Aaron Boodman
2012/04/26 05:30:54
You could simplify this slightly by making the pre
not at google - send to devlin
2012/04/26 06:01:57
Oh, I made it a switch. I think it looks nice now.
| |
| 65 } | |
| 31 } | 66 } |
| 32 return true; | 67 |
| 68 // Find the TabContentsWrapper that contains this tab id if one is required. | |
| 69 if (tab_id_ == ExtensionAction::kDefaultTabId) { | |
| 70 EXTENSION_FUNCTION_VALIDATE(GetExtension()->browser_action()); | |
| 71 } else { | |
| 72 ExtensionTabUtil::GetTabById( | |
| 73 tab_id_, profile(), include_incognito(), NULL, NULL, &contents_, NULL); | |
| 74 if (!contents_) { | |
| 75 error_ = ExtensionErrorUtils::FormatErrorMessage( | |
| 76 kNoTabError, base::IntToString(tab_id_)); | |
| 77 return false; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 return RunExtensionAction(); | |
| 33 } | 82 } |
| 34 | 83 |
| 35 bool ExtensionActionFunction::SetIcon() { | 84 void ExtensionActionFunction::NotifyChange() { |
|
Aaron Boodman
2012/04/26 05:30:54
Nit: I would make this abstract and have the subcl
not at google - send to devlin
2012/04/26 06:01:57
Yeah that's the thing, it's what I'm trying to avo
Aaron Boodman
2012/04/26 06:25:36
I see! OK.
| |
| 36 base::BinaryValue* binary = NULL; | 85 if (GetExtension()->browser_action()) |
| 37 EXTENSION_FUNCTION_VALIDATE(details_->GetBinary("imageData", &binary)); | 86 NotifyBrowserActionChange(); |
| 38 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize()); | 87 else if (GetExtension()->page_action()) |
| 39 PickleIterator iter(bitmap_pickle); | 88 NotifyPageActionChange(); |
| 40 SkBitmap bitmap; | 89 else |
| 41 EXTENSION_FUNCTION_VALIDATE( | 90 NOTREACHED(); |
| 42 IPC::ReadParam(&bitmap_pickle, &iter, &bitmap)); | |
| 43 extension_action_->SetIcon(tab_id_, bitmap); | |
| 44 return true; | |
| 45 } | 91 } |
| 46 | 92 |
| 47 bool ExtensionActionFunction::SetTitle() { | 93 void ExtensionActionFunction::NotifyBrowserActionChange() { |
| 48 std::string title; | 94 content::NotificationService::current()->Notify( |
| 49 EXTENSION_FUNCTION_VALIDATE(details_->GetString("title", &title)); | 95 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_UPDATED, |
| 50 extension_action_->SetTitle(tab_id_, title); | 96 content::Source<ExtensionAction>(extension_action_), |
| 51 return true; | 97 content::NotificationService::NoDetails()); |
| 52 } | 98 } |
| 53 | 99 |
| 54 bool ExtensionActionFunction::SetPopup() { | 100 void ExtensionActionFunction::NotifyPageActionChange() { |
| 55 std::string popup_string; | 101 contents_->extension_tab_helper()->PageActionStateChanged(); |
| 56 EXTENSION_FUNCTION_VALIDATE(details_->GetString("popup", &popup_string)); | |
| 57 | |
| 58 GURL popup_url; | |
| 59 if (!popup_string.empty()) | |
| 60 popup_url = GetExtension()->GetResourceURL(popup_string); | |
| 61 | |
| 62 extension_action_->SetPopupUrl(tab_id_, popup_url); | |
| 63 return true; | |
| 64 } | 102 } |
| 65 | 103 |
| 66 bool ExtensionActionFunction::SetBadgeText() { | 104 // static |
| 67 std::string badge_text; | |
| 68 EXTENSION_FUNCTION_VALIDATE(details_->GetString("text", &badge_text)); | |
| 69 extension_action_->SetBadgeText(tab_id_, badge_text); | |
| 70 return true; | |
| 71 } | |
| 72 | |
| 73 bool ExtensionActionFunction::ParseCSSColorString( | 105 bool ExtensionActionFunction::ParseCSSColorString( |
| 74 const std::string& color_string, | 106 const std::string& color_string, |
| 75 SkColor* result) { | 107 SkColor* result) { |
| 76 std::string formatted_color = "#"; | 108 std::string formatted_color = "#"; |
| 77 // Check the string for incorrect formatting. | 109 // Check the string for incorrect formatting. |
| 78 if (color_string[0] != '#') | 110 if (color_string[0] != '#') |
| 79 return false; | 111 return false; |
| 80 | 112 |
| 81 // Convert the string from #FFF format to #FFFFFF format. | 113 // Convert the string from #FFF format to #FFFFFF format. |
| 82 if (color_string.length() == 4) { | 114 if (color_string.length() == 4) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 99 color_ints + i)) | 131 color_ints + i)) |
| 100 return false; | 132 return false; |
| 101 if (color_ints[i] > 255 || color_ints[i] < 0) | 133 if (color_ints[i] > 255 || color_ints[i] < 0) |
| 102 return false; | 134 return false; |
| 103 } | 135 } |
| 104 | 136 |
| 105 *result = SkColorSetARGB(255, color_ints[0], color_ints[1], color_ints[2]); | 137 *result = SkColorSetARGB(255, color_ints[0], color_ints[1], color_ints[2]); |
| 106 return true; | 138 return true; |
| 107 } | 139 } |
| 108 | 140 |
| 109 bool ExtensionActionFunction::SetBadgeBackgroundColor() { | 141 bool ExtensionActionFunction::SetVisible(bool visible) { |
| 142 EXTENSION_FUNCTION_VALIDATE(GetExtension()->page_action()); | |
|
Aaron Boodman
2012/04/26 05:30:54
If this has to always be page_action, why put it h
not at google - send to devlin
2012/04/26 06:01:57
Yeah, good point. I was trying to make this API wo
Aaron Boodman
2012/04/26 06:25:36
It's fine, after seeing the other patch, it makes
| |
| 143 extension_action_->SetIsVisible(tab_id_, visible); | |
| 144 NotifyChange(); | |
| 145 return true; | |
| 146 } | |
| 147 | |
| 148 bool ExtensionActionShowFunction::RunExtensionAction() { | |
| 149 return SetVisible(true); | |
| 150 } | |
| 151 | |
| 152 bool ExtensionActionHideFunction::RunExtensionAction() { | |
| 153 return SetVisible(false); | |
| 154 } | |
| 155 | |
| 156 bool ExtensionActionSetIconFunction::RunExtensionAction() { | |
| 157 // setIcon can take a variant argument: either a canvas ImageData, or an | |
| 158 // icon index. | |
| 159 base::BinaryValue* binary = NULL; | |
| 160 int icon_index; | |
| 161 if (details_->GetBinary("imageData", &binary)) { | |
| 162 IPC::Message bitmap_pickle(binary->GetBuffer(), binary->GetSize()); | |
| 163 PickleIterator iter(bitmap_pickle); | |
| 164 SkBitmap bitmap; | |
| 165 EXTENSION_FUNCTION_VALIDATE( | |
| 166 IPC::ReadParam(&bitmap_pickle, &iter, &bitmap)); | |
| 167 extension_action_->SetIcon(tab_id_, bitmap); | |
| 168 } else if (details_->GetInteger("iconIndex", &icon_index)) { | |
| 169 EXTENSION_FUNCTION_VALIDATE(GetExtension()->page_action()); | |
| 170 if (icon_index < 0 || | |
| 171 static_cast<size_t>(icon_index) >= | |
| 172 extension_action_->icon_paths()->size()) { | |
| 173 error_ = kIconIndexOutOfBounds; | |
| 174 return false; | |
| 175 } | |
| 176 extension_action_->SetIcon(tab_id_, SkBitmap()); | |
| 177 extension_action_->SetIconIndex(tab_id_, icon_index); | |
| 178 } else { | |
| 179 EXTENSION_FUNCTION_VALIDATE(false); | |
| 180 } | |
| 181 NotifyChange(); | |
| 182 return true; | |
| 183 } | |
| 184 | |
| 185 bool ExtensionActionSetTitleFunction::RunExtensionAction() { | |
| 186 std::string title; | |
| 187 EXTENSION_FUNCTION_VALIDATE(details_->GetString("title", &title)); | |
| 188 extension_action_->SetTitle(tab_id_, title); | |
| 189 NotifyChange(); | |
| 190 return true; | |
| 191 } | |
| 192 | |
| 193 bool ExtensionActionSetPopupFunction::RunExtensionAction() { | |
| 194 std::string popup_string; | |
| 195 EXTENSION_FUNCTION_VALIDATE(details_->GetString("popup", &popup_string)); | |
| 196 | |
| 197 GURL popup_url; | |
| 198 if (!popup_string.empty()) | |
| 199 popup_url = GetExtension()->GetResourceURL(popup_string); | |
| 200 | |
| 201 extension_action_->SetPopupUrl(tab_id_, popup_url); | |
| 202 NotifyChange(); | |
| 203 return true; | |
| 204 } | |
| 205 | |
| 206 bool ExtensionActionSetBadgeTextFunction::RunExtensionAction() { | |
| 207 EXTENSION_FUNCTION_VALIDATE(GetExtension()->browser_action()); | |
| 208 std::string badge_text; | |
| 209 EXTENSION_FUNCTION_VALIDATE(details_->GetString("text", &badge_text)); | |
| 210 extension_action_->SetBadgeText(tab_id_, badge_text); | |
| 211 NotifyChange(); | |
| 212 return true; | |
| 213 } | |
| 214 | |
| 215 bool ExtensionActionSetBadgeBackgroundColorFunction::RunExtensionAction() { | |
| 216 EXTENSION_FUNCTION_VALIDATE(GetExtension()->browser_action()); | |
| 217 | |
| 110 Value* color_value = NULL; | 218 Value* color_value = NULL; |
| 111 details_->Get("color", &color_value); | 219 details_->Get("color", &color_value); |
| 112 SkColor color = 0; | 220 SkColor color = 0; |
| 113 if (color_value->IsType(Value::TYPE_LIST)) { | 221 if (color_value->IsType(Value::TYPE_LIST)) { |
| 114 ListValue* list = NULL; | 222 ListValue* list = NULL; |
| 115 EXTENSION_FUNCTION_VALIDATE(details_->GetList("color", &list)); | 223 EXTENSION_FUNCTION_VALIDATE(details_->GetList("color", &list)); |
| 116 EXTENSION_FUNCTION_VALIDATE(list->GetSize() == 4); | 224 EXTENSION_FUNCTION_VALIDATE(list->GetSize() == 4); |
| 117 | 225 |
| 118 int color_array[4] = {0}; | 226 int color_array[4] = {0}; |
| 119 for (size_t i = 0; i < arraysize(color_array); ++i) { | 227 for (size_t i = 0; i < arraysize(color_array); ++i) { |
| 120 EXTENSION_FUNCTION_VALIDATE(list->GetInteger(i, &color_array[i])); | 228 EXTENSION_FUNCTION_VALIDATE(list->GetInteger(i, &color_array[i])); |
| 121 } | 229 } |
| 122 | 230 |
| 123 color = SkColorSetARGB(color_array[3], color_array[0], | 231 color = SkColorSetARGB(color_array[3], color_array[0], |
| 124 color_array[1], color_array[2]); | 232 color_array[1], color_array[2]); |
| 125 | |
| 126 } else if (color_value->IsType(Value::TYPE_STRING)) { | 233 } else if (color_value->IsType(Value::TYPE_STRING)) { |
| 127 std::string color_string; | 234 std::string color_string; |
| 128 EXTENSION_FUNCTION_VALIDATE(details_->GetString("color", &color_string)); | 235 EXTENSION_FUNCTION_VALIDATE(details_->GetString("color", &color_string)); |
| 129 if (!ParseCSSColorString(color_string, &color)) | 236 if (!ParseCSSColorString(color_string, &color)) |
| 130 return false; | 237 return false; |
| 131 } | 238 } |
| 132 | 239 |
| 133 extension_action_->SetBadgeBackgroundColor(tab_id_, color); | 240 extension_action_->SetBadgeBackgroundColor(tab_id_, color); |
| 134 | 241 NotifyChange(); |
| 135 return true; | 242 return true; |
| 136 } | 243 } |
| 137 | 244 |
| 138 bool ExtensionActionFunction::GetTitle() { | 245 bool ExtensionActionGetTitleFunction::RunExtensionAction() { |
| 139 result_.reset(Value::CreateStringValue(extension_action_->GetTitle(tab_id_))); | 246 result_.reset(Value::CreateStringValue(extension_action_->GetTitle(tab_id_))); |
| 140 return true; | 247 return true; |
| 141 } | 248 } |
| 142 | 249 |
| 143 bool ExtensionActionFunction::GetPopup() { | 250 bool ExtensionActionGetPopupFunction::RunExtensionAction() { |
| 144 result_.reset(Value::CreateStringValue( | 251 result_.reset(Value::CreateStringValue( |
| 145 extension_action_->GetPopupUrl(tab_id_).spec())); | 252 extension_action_->GetPopupUrl(tab_id_).spec())); |
| 146 return true; | 253 return true; |
| 147 } | 254 } |
| 148 | 255 |
| 149 bool ExtensionActionFunction::GetBadgeText() { | 256 bool ExtensionActionGetBadgeTextFunction::RunExtensionAction() { |
| 257 EXTENSION_FUNCTION_VALIDATE(GetExtension()->browser_action()); | |
| 150 result_.reset(Value::CreateStringValue( | 258 result_.reset(Value::CreateStringValue( |
| 151 extension_action_->GetBadgeText(tab_id_))); | 259 extension_action_->GetBadgeText(tab_id_))); |
| 152 return true; | 260 return true; |
| 153 } | 261 } |
| 154 | 262 |
| 155 bool ExtensionActionFunction::GetBadgeBackgroundColor() { | 263 bool ExtensionActionGetBadgeBackgroundColorFunction::RunExtensionAction() { |
| 264 EXTENSION_FUNCTION_VALIDATE(GetExtension()->browser_action()); | |
| 156 ListValue* list = new ListValue(); | 265 ListValue* list = new ListValue(); |
| 157 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_); | 266 SkColor color = extension_action_->GetBadgeBackgroundColor(tab_id_); |
| 158 list->Append(Value::CreateIntegerValue(SkColorGetR(color))); | 267 list->Append(Value::CreateIntegerValue(SkColorGetR(color))); |
| 159 list->Append(Value::CreateIntegerValue(SkColorGetG(color))); | 268 list->Append(Value::CreateIntegerValue(SkColorGetG(color))); |
| 160 list->Append(Value::CreateIntegerValue(SkColorGetB(color))); | 269 list->Append(Value::CreateIntegerValue(SkColorGetB(color))); |
| 161 list->Append(Value::CreateIntegerValue(SkColorGetA(color))); | 270 list->Append(Value::CreateIntegerValue(SkColorGetA(color))); |
| 162 result_.reset(list); | 271 result_.reset(list); |
| 163 return true; | 272 return true; |
| 164 } | 273 } |
| OLD | NEW |