| 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_action_api.h" | 5 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | |
| 8 #include "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 9 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/string_util.h" | |
| 11 #include "base/values.h" | 9 #include "base/values.h" |
| 12 #include "chrome/browser/extensions/active_script_controller.h" | 10 #include "chrome/browser/extensions/active_script_controller.h" |
| 13 #include "chrome/browser/extensions/api/extension_action/extension_page_actions_
api_constants.h" | |
| 14 #include "chrome/browser/extensions/extension_action.h" | |
| 15 #include "chrome/browser/extensions/extension_action_manager.h" | 11 #include "chrome/browser/extensions/extension_action_manager.h" |
| 16 #include "chrome/browser/extensions/extension_tab_util.h" | 12 #include "chrome/browser/extensions/extension_tab_util.h" |
| 17 #include "chrome/browser/extensions/extension_toolbar_model.h" | 13 #include "chrome/browser/extensions/extension_toolbar_model.h" |
| 18 #include "chrome/browser/extensions/tab_helper.h" | 14 #include "chrome/browser/extensions/tab_helper.h" |
| 19 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/browser/sessions/session_tab_helper.h" | 16 #include "chrome/browser/sessions/session_tab_helper.h" |
| 21 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
| 22 #include "chrome/browser/ui/browser_finder.h" | 18 #include "chrome/browser/ui/browser_finder.h" |
| 23 #include "chrome/browser/ui/browser_window.h" | 19 #include "chrome/browser/ui/browser_window.h" |
| 24 #include "chrome/browser/ui/location_bar/location_bar.h" | 20 #include "chrome/browser/ui/location_bar/location_bar.h" |
| 25 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 26 #include "chrome/common/extensions/api/extension_action/action_info.h" | 22 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 27 #include "chrome/common/render_messages.h" | 23 #include "chrome/common/render_messages.h" |
| 28 #include "content/public/browser/navigation_entry.h" | |
| 29 #include "content/public/browser/notification_service.h" | 24 #include "content/public/browser/notification_service.h" |
| 30 #include "extensions/browser/event_router.h" | 25 #include "extensions/browser/event_router.h" |
| 31 #include "extensions/browser/extension_function_registry.h" | 26 #include "extensions/browser/extension_function_registry.h" |
| 32 #include "extensions/browser/extension_host.h" | 27 #include "extensions/browser/extension_host.h" |
| 33 #include "extensions/browser/extension_registry.h" | 28 #include "extensions/browser/extension_registry.h" |
| 34 #include "extensions/browser/extension_system.h" | |
| 35 #include "extensions/browser/image_util.h" | 29 #include "extensions/browser/image_util.h" |
| 36 #include "extensions/browser/notification_types.h" | 30 #include "extensions/browser/notification_types.h" |
| 37 #include "extensions/browser/state_store.h" | |
| 38 #include "extensions/common/error_utils.h" | 31 #include "extensions/common/error_utils.h" |
| 39 #include "ui/gfx/codec/png_codec.h" | |
| 40 #include "ui/gfx/image/image.h" | 32 #include "ui/gfx/image/image.h" |
| 41 #include "ui/gfx/image/image_skia.h" | 33 #include "ui/gfx/image/image_skia.h" |
| 42 | 34 |
| 43 using content::WebContents; | 35 using content::WebContents; |
| 44 | 36 |
| 45 namespace page_actions_keys = extension_page_actions_api_constants; | |
| 46 | |
| 47 namespace extensions { | 37 namespace extensions { |
| 48 | 38 |
| 49 namespace { | 39 namespace { |
| 50 | 40 |
| 51 const char kBrowserActionStorageKey[] = "browser_action"; | |
| 52 const char kPopupUrlStorageKey[] = "poupup_url"; | |
| 53 const char kTitleStorageKey[] = "title"; | |
| 54 const char kIconStorageKey[] = "icon"; | |
| 55 const char kBadgeTextStorageKey[] = "badge_text"; | |
| 56 const char kBadgeBackgroundColorStorageKey[] = "badge_background_color"; | |
| 57 const char kBadgeTextColorStorageKey[] = "badge_text_color"; | |
| 58 const char kAppearanceStorageKey[] = "appearance"; | |
| 59 | |
| 60 // Only add values to the end of this enum, since it's stored in the user's | |
| 61 // Extension State, under the kAppearanceStorageKey. It represents the | |
| 62 // ExtensionAction's default visibility. | |
| 63 enum StoredAppearance { | |
| 64 // The action icon is hidden. | |
| 65 INVISIBLE = 0, | |
| 66 // The action is trying to get the user's attention but isn't yet | |
| 67 // running on the page. Was only used for script badges. | |
| 68 OBSOLETE_WANTS_ATTENTION = 1, | |
| 69 // The action icon is visible with its normal appearance. | |
| 70 ACTIVE = 2, | |
| 71 }; | |
| 72 | |
| 73 // Whether the browser action is visible in the toolbar. | 41 // Whether the browser action is visible in the toolbar. |
| 74 const char kBrowserActionVisible[] = "browser_action_visible"; | 42 const char kBrowserActionVisible[] = "browser_action_visible"; |
| 75 | 43 |
| 76 // Errors. | 44 // Errors. |
| 77 const char kNoExtensionActionError[] = | 45 const char kNoExtensionActionError[] = |
| 78 "This extension has no action specified."; | 46 "This extension has no action specified."; |
| 79 const char kNoTabError[] = "No tab with id: *."; | 47 const char kNoTabError[] = "No tab with id: *."; |
| 80 const char kOpenPopupError[] = | 48 const char kOpenPopupError[] = |
| 81 "Failed to show popup either because there is an existing popup or another " | 49 "Failed to show popup either because there is an existing popup or another " |
| 82 "error occurred."; | 50 "error occurred."; |
| 83 const char kInternalError[] = "Internal error."; | 51 const char kInternalError[] = "Internal error."; |
| 84 | 52 |
| 85 struct IconRepresentationInfo { | |
| 86 // Size as a string that will be used to retrieve representation value from | |
| 87 // SetIcon function arguments. | |
| 88 const char* size_string; | |
| 89 // Scale factor for which the represantion should be used. | |
| 90 ui::ScaleFactor scale; | |
| 91 }; | |
| 92 | |
| 93 const IconRepresentationInfo kIconSizes[] = { | |
| 94 { "19", ui::SCALE_FACTOR_100P }, | |
| 95 { "38", ui::SCALE_FACTOR_200P } | |
| 96 }; | |
| 97 | |
| 98 // Conversion function for reading/writing to storage. | |
| 99 SkColor RawStringToSkColor(const std::string& str) { | |
| 100 uint64 value = 0; | |
| 101 base::StringToUint64(str, &value); | |
| 102 SkColor color = static_cast<SkColor>(value); | |
| 103 DCHECK(value == color); // ensure value fits into color's 32 bits | |
| 104 return color; | |
| 105 } | |
| 106 | |
| 107 // Conversion function for reading/writing to storage. | |
| 108 std::string SkColorToRawString(SkColor color) { | |
| 109 return base::Uint64ToString(color); | |
| 110 } | |
| 111 | |
| 112 // Conversion function for reading/writing to storage. | |
| 113 bool StringToSkBitmap(const std::string& str, SkBitmap* bitmap) { | |
| 114 // TODO(mpcomplete): Remove the base64 encode/decode step when | |
| 115 // http://crbug.com/140546 is fixed. | |
| 116 std::string raw_str; | |
| 117 if (!base::Base64Decode(str, &raw_str)) | |
| 118 return false; | |
| 119 | |
| 120 bool success = gfx::PNGCodec::Decode( | |
| 121 reinterpret_cast<unsigned const char*>(raw_str.data()), raw_str.size(), | |
| 122 bitmap); | |
| 123 return success; | |
| 124 } | |
| 125 | |
| 126 // Conversion function for reading/writing to storage. | |
| 127 std::string RepresentationToString(const gfx::ImageSkia& image, float scale) { | |
| 128 SkBitmap bitmap = image.GetRepresentation(scale).sk_bitmap(); | |
| 129 SkAutoLockPixels lock_image(bitmap); | |
| 130 std::vector<unsigned char> data; | |
| 131 bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data); | |
| 132 if (!success) | |
| 133 return std::string(); | |
| 134 | |
| 135 base::StringPiece raw_str( | |
| 136 reinterpret_cast<const char*>(&data[0]), data.size()); | |
| 137 std::string base64_str; | |
| 138 base::Base64Encode(raw_str, &base64_str); | |
| 139 return base64_str; | |
| 140 } | |
| 141 | |
| 142 // Set |action|'s default values to those specified in |dict|. | |
| 143 void SetDefaultsFromValue(const base::DictionaryValue* dict, | |
| 144 ExtensionAction* action) { | |
| 145 const int kDefaultTabId = ExtensionAction::kDefaultTabId; | |
| 146 std::string str_value; | |
| 147 int int_value; | |
| 148 SkBitmap bitmap; | |
| 149 gfx::ImageSkia icon; | |
| 150 | |
| 151 // For each value, don't set it if it has been modified already. | |
| 152 if (dict->GetString(kPopupUrlStorageKey, &str_value) && | |
| 153 !action->HasPopupUrl(kDefaultTabId)) { | |
| 154 action->SetPopupUrl(kDefaultTabId, GURL(str_value)); | |
| 155 } | |
| 156 if (dict->GetString(kTitleStorageKey, &str_value) && | |
| 157 !action->HasTitle(kDefaultTabId)) { | |
| 158 action->SetTitle(kDefaultTabId, str_value); | |
| 159 } | |
| 160 if (dict->GetString(kBadgeTextStorageKey, &str_value) && | |
| 161 !action->HasBadgeText(kDefaultTabId)) { | |
| 162 action->SetBadgeText(kDefaultTabId, str_value); | |
| 163 } | |
| 164 if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value) && | |
| 165 !action->HasBadgeBackgroundColor(kDefaultTabId)) { | |
| 166 action->SetBadgeBackgroundColor(kDefaultTabId, | |
| 167 RawStringToSkColor(str_value)); | |
| 168 } | |
| 169 if (dict->GetString(kBadgeTextColorStorageKey, &str_value) && | |
| 170 !action->HasBadgeTextColor(kDefaultTabId)) { | |
| 171 action->SetBadgeTextColor(kDefaultTabId, RawStringToSkColor(str_value)); | |
| 172 } | |
| 173 if (dict->GetInteger(kAppearanceStorageKey, &int_value) && | |
| 174 !action->HasIsVisible(kDefaultTabId)) { | |
| 175 switch (int_value) { | |
| 176 case INVISIBLE: | |
| 177 case OBSOLETE_WANTS_ATTENTION: | |
| 178 action->SetIsVisible(kDefaultTabId, false); | |
| 179 break; | |
| 180 case ACTIVE: | |
| 181 action->SetIsVisible(kDefaultTabId, true); | |
| 182 break; | |
| 183 } | |
| 184 } | |
| 185 | |
| 186 const base::DictionaryValue* icon_value = NULL; | |
| 187 if (dict->GetDictionary(kIconStorageKey, &icon_value) && | |
| 188 !action->HasIcon(kDefaultTabId)) { | |
| 189 for (size_t i = 0; i < arraysize(kIconSizes); i++) { | |
| 190 if (icon_value->GetString(kIconSizes[i].size_string, &str_value) && | |
| 191 StringToSkBitmap(str_value, &bitmap)) { | |
| 192 CHECK(!bitmap.isNull()); | |
| 193 float scale = ui::GetScaleForScaleFactor(kIconSizes[i].scale); | |
| 194 icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); | |
| 195 } | |
| 196 } | |
| 197 action->SetIcon(kDefaultTabId, gfx::Image(icon)); | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 // Store |action|'s default values in a DictionaryValue for use in storing to | |
| 202 // disk. | |
| 203 scoped_ptr<base::DictionaryValue> DefaultsToValue(ExtensionAction* action) { | |
| 204 const int kDefaultTabId = ExtensionAction::kDefaultTabId; | |
| 205 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 206 | |
| 207 dict->SetString(kPopupUrlStorageKey, | |
| 208 action->GetPopupUrl(kDefaultTabId).spec()); | |
| 209 dict->SetString(kTitleStorageKey, action->GetTitle(kDefaultTabId)); | |
| 210 dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kDefaultTabId)); | |
| 211 dict->SetString( | |
| 212 kBadgeBackgroundColorStorageKey, | |
| 213 SkColorToRawString(action->GetBadgeBackgroundColor(kDefaultTabId))); | |
| 214 dict->SetString(kBadgeTextColorStorageKey, | |
| 215 SkColorToRawString(action->GetBadgeTextColor(kDefaultTabId))); | |
| 216 dict->SetInteger(kAppearanceStorageKey, | |
| 217 action->GetIsVisible(kDefaultTabId) ? ACTIVE : INVISIBLE); | |
| 218 | |
| 219 gfx::ImageSkia icon = action->GetExplicitlySetIcon(kDefaultTabId); | |
| 220 if (!icon.isNull()) { | |
| 221 base::DictionaryValue* icon_value = new base::DictionaryValue(); | |
| 222 for (size_t i = 0; i < arraysize(kIconSizes); i++) { | |
| 223 float scale = ui::GetScaleForScaleFactor(kIconSizes[i].scale); | |
| 224 if (icon.HasRepresentation(scale)) { | |
| 225 icon_value->SetString( | |
| 226 kIconSizes[i].size_string, | |
| 227 RepresentationToString(icon, scale)); | |
| 228 } | |
| 229 } | |
| 230 dict->Set(kIconStorageKey, icon_value); | |
| 231 } | |
| 232 return dict.Pass(); | |
| 233 } | |
| 234 | |
| 235 } // namespace | 53 } // namespace |
| 236 | 54 |
| 237 // | 55 // |
| 238 // ExtensionActionAPI::Observer | 56 // ExtensionActionAPI::Observer |
| 239 // | 57 // |
| 240 | 58 |
| 241 void ExtensionActionAPI::Observer::OnExtensionActionUpdated( | 59 void ExtensionActionAPI::Observer::OnExtensionActionUpdated( |
| 242 ExtensionAction* extension_action, | 60 ExtensionAction* extension_action, |
| 243 content::WebContents* web_contents, | 61 content::WebContents* web_contents, |
| 244 content::BrowserContext* browser_context) { | 62 content::BrowserContext* browser_context) { |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 location_bar->UpdatePageActions(); | 297 location_bar->UpdatePageActions(); |
| 480 | 298 |
| 481 FOR_EACH_OBSERVER(Observer, observers_, OnPageActionsUpdated(web_contents)); | 299 FOR_EACH_OBSERVER(Observer, observers_, OnPageActionsUpdated(web_contents)); |
| 482 } | 300 } |
| 483 | 301 |
| 484 void ExtensionActionAPI::Shutdown() { | 302 void ExtensionActionAPI::Shutdown() { |
| 485 FOR_EACH_OBSERVER(Observer, observers_, OnExtensionActionAPIShuttingDown()); | 303 FOR_EACH_OBSERVER(Observer, observers_, OnExtensionActionAPIShuttingDown()); |
| 486 } | 304 } |
| 487 | 305 |
| 488 // | 306 // |
| 489 // ExtensionActionStorageManager | |
| 490 // | |
| 491 | |
| 492 ExtensionActionStorageManager::ExtensionActionStorageManager(Profile* profile) | |
| 493 : profile_(profile), | |
| 494 extension_action_observer_(this), | |
| 495 extension_registry_observer_(this) { | |
| 496 extension_action_observer_.Add(ExtensionActionAPI::Get(profile_)); | |
| 497 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | |
| 498 | |
| 499 StateStore* storage = ExtensionSystem::Get(profile_)->state_store(); | |
| 500 if (storage) | |
| 501 storage->RegisterKey(kBrowserActionStorageKey); | |
| 502 } | |
| 503 | |
| 504 ExtensionActionStorageManager::~ExtensionActionStorageManager() { | |
| 505 } | |
| 506 | |
| 507 void ExtensionActionStorageManager::OnExtensionLoaded( | |
| 508 content::BrowserContext* browser_context, | |
| 509 const Extension* extension) { | |
| 510 if (!ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension)) | |
| 511 return; | |
| 512 | |
| 513 StateStore* storage = ExtensionSystem::Get(profile_)->state_store(); | |
| 514 if (storage) { | |
| 515 storage->GetExtensionValue( | |
| 516 extension->id(), | |
| 517 kBrowserActionStorageKey, | |
| 518 base::Bind(&ExtensionActionStorageManager::ReadFromStorage, | |
| 519 AsWeakPtr(), | |
| 520 extension->id())); | |
| 521 } | |
| 522 } | |
| 523 | |
| 524 void ExtensionActionStorageManager::OnExtensionActionUpdated( | |
| 525 ExtensionAction* extension_action, | |
| 526 content::WebContents* web_contents, | |
| 527 content::BrowserContext* browser_context) { | |
| 528 if (profile_ == browser_context && | |
| 529 extension_action->action_type() == ActionInfo::TYPE_BROWSER) | |
| 530 WriteToStorage(extension_action); | |
| 531 } | |
| 532 | |
| 533 void ExtensionActionStorageManager::OnExtensionActionAPIShuttingDown() { | |
| 534 extension_action_observer_.RemoveAll(); | |
| 535 } | |
| 536 | |
| 537 void ExtensionActionStorageManager::WriteToStorage( | |
| 538 ExtensionAction* extension_action) { | |
| 539 StateStore* storage = ExtensionSystem::Get(profile_)->state_store(); | |
| 540 if (!storage) | |
| 541 return; | |
| 542 | |
| 543 scoped_ptr<base::DictionaryValue> defaults = | |
| 544 DefaultsToValue(extension_action); | |
| 545 storage->SetExtensionValue(extension_action->extension_id(), | |
| 546 kBrowserActionStorageKey, | |
| 547 defaults.PassAs<base::Value>()); | |
| 548 } | |
| 549 | |
| 550 void ExtensionActionStorageManager::ReadFromStorage( | |
| 551 const std::string& extension_id, scoped_ptr<base::Value> value) { | |
| 552 const Extension* extension = ExtensionRegistry::Get(profile_)-> | |
| 553 enabled_extensions().GetByID(extension_id); | |
| 554 if (!extension) | |
| 555 return; | |
| 556 | |
| 557 ExtensionAction* browser_action = | |
| 558 ExtensionActionManager::Get(profile_)->GetBrowserAction(*extension); | |
| 559 if (!browser_action) { | |
| 560 // This can happen if the extension is updated between startup and when the | |
| 561 // storage read comes back, and the update removes the browser action. | |
| 562 // http://crbug.com/349371 | |
| 563 return; | |
| 564 } | |
| 565 | |
| 566 const base::DictionaryValue* dict = NULL; | |
| 567 if (!value.get() || !value->GetAsDictionary(&dict)) | |
| 568 return; | |
| 569 | |
| 570 SetDefaultsFromValue(dict, browser_action); | |
| 571 } | |
| 572 | |
| 573 // | |
| 574 // ExtensionActionFunction | 307 // ExtensionActionFunction |
| 575 // | 308 // |
| 576 | 309 |
| 577 ExtensionActionFunction::ExtensionActionFunction() | 310 ExtensionActionFunction::ExtensionActionFunction() |
| 578 : details_(NULL), | 311 : details_(NULL), |
| 579 tab_id_(ExtensionAction::kDefaultTabId), | 312 tab_id_(ExtensionAction::kDefaultTabId), |
| 580 contents_(NULL), | 313 contents_(NULL), |
| 581 extension_action_(NULL) { | 314 extension_action_(NULL) { |
| 582 } | 315 } |
| 583 | 316 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 } | 415 } |
| 683 | 416 |
| 684 bool ExtensionActionFunction::SetVisible(bool visible) { | 417 bool ExtensionActionFunction::SetVisible(bool visible) { |
| 685 if (extension_action_->GetIsVisible(tab_id_) == visible) | 418 if (extension_action_->GetIsVisible(tab_id_) == visible) |
| 686 return true; | 419 return true; |
| 687 extension_action_->SetIsVisible(tab_id_, visible); | 420 extension_action_->SetIsVisible(tab_id_, visible); |
| 688 NotifyChange(); | 421 NotifyChange(); |
| 689 return true; | 422 return true; |
| 690 } | 423 } |
| 691 | 424 |
| 692 TabHelper& ExtensionActionFunction::tab_helper() const { | |
| 693 CHECK(contents_); | |
| 694 return *TabHelper::FromWebContents(contents_); | |
| 695 } | |
| 696 | |
| 697 bool ExtensionActionShowFunction::RunExtensionAction() { | 425 bool ExtensionActionShowFunction::RunExtensionAction() { |
| 698 return SetVisible(true); | 426 return SetVisible(true); |
| 699 } | 427 } |
| 700 | 428 |
| 701 bool ExtensionActionHideFunction::RunExtensionAction() { | 429 bool ExtensionActionHideFunction::RunExtensionAction() { |
| 702 return SetVisible(false); | 430 return SetVisible(false); |
| 703 } | 431 } |
| 704 | 432 |
| 705 bool ExtensionActionSetIconFunction::RunExtensionAction() { | 433 bool ExtensionActionSetIconFunction::RunExtensionAction() { |
| 706 EXTENSION_FUNCTION_VALIDATE(details_); | 434 EXTENSION_FUNCTION_VALIDATE(details_); |
| 707 | 435 |
| 708 // setIcon can take a variant argument: either a dictionary of canvas | 436 // setIcon can take a variant argument: either a dictionary of canvas |
| 709 // ImageData, or an icon index. | 437 // ImageData, or an icon index. |
| 710 base::DictionaryValue* canvas_set = NULL; | 438 base::DictionaryValue* canvas_set = NULL; |
| 711 int icon_index; | 439 int icon_index; |
| 712 if (details_->GetDictionary("imageData", &canvas_set)) { | 440 if (details_->GetDictionary("imageData", &canvas_set)) { |
| 713 gfx::ImageSkia icon; | 441 gfx::ImageSkia icon; |
| 714 // Extract icon representations from the ImageDataSet dictionary. | 442 // Extract icon representations from the ImageDataSet dictionary. |
| 715 for (size_t i = 0; i < arraysize(kIconSizes); i++) { | 443 for (size_t i = 0; i < extension_misc::kNumExtensionActionIconSizes; i++) { |
| 716 base::BinaryValue* binary; | 444 base::BinaryValue* binary = NULL; |
| 717 if (canvas_set->GetBinary(kIconSizes[i].size_string, &binary)) { | 445 const extension_misc::IconRepresentationInfo& icon_info = |
| 446 extension_misc::kExtensionActionIconSizes[i]; |
| 447 if (canvas_set->GetBinary(icon_info.size_string, &binary)) { |
| 718 IPC::Message pickle(binary->GetBuffer(), binary->GetSize()); | 448 IPC::Message pickle(binary->GetBuffer(), binary->GetSize()); |
| 719 PickleIterator iter(pickle); | 449 PickleIterator iter(pickle); |
| 720 SkBitmap bitmap; | 450 SkBitmap bitmap; |
| 721 EXTENSION_FUNCTION_VALIDATE(IPC::ReadParam(&pickle, &iter, &bitmap)); | 451 EXTENSION_FUNCTION_VALIDATE(IPC::ReadParam(&pickle, &iter, &bitmap)); |
| 722 CHECK(!bitmap.isNull()); | 452 CHECK(!bitmap.isNull()); |
| 723 float scale = ui::GetScaleForScaleFactor(kIconSizes[i].scale); | 453 float scale = ui::GetScaleForScaleFactor(icon_info.scale); |
| 724 icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); | 454 icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale)); |
| 725 } | 455 } |
| 726 } | 456 } |
| 727 | 457 |
| 728 extension_action_->SetIcon(tab_id_, gfx::Image(icon)); | 458 extension_action_->SetIcon(tab_id_, gfx::Image(icon)); |
| 729 } else if (details_->GetInteger("iconIndex", &icon_index)) { | 459 } else if (details_->GetInteger("iconIndex", &icon_index)) { |
| 730 // Obsolete argument: ignore it. | 460 // Obsolete argument: ignore it. |
| 731 return true; | 461 return true; |
| 732 } else { | 462 } else { |
| 733 EXTENSION_FUNCTION_VALIDATE(false); | 463 EXTENSION_FUNCTION_VALIDATE(false); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || | 611 if (host->extension_host_type() != VIEW_TYPE_EXTENSION_POPUP || |
| 882 host->extension()->id() != extension_->id()) | 612 host->extension()->id() != extension_->id()) |
| 883 return; | 613 return; |
| 884 | 614 |
| 885 SendResponse(true); | 615 SendResponse(true); |
| 886 response_sent_ = true; | 616 response_sent_ = true; |
| 887 registrar_.RemoveAll(); | 617 registrar_.RemoveAll(); |
| 888 } | 618 } |
| 889 | 619 |
| 890 } // namespace extensions | 620 } // namespace extensions |
| OLD | NEW |