diff options
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 42 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 31 | ||||
-rw-r--r-- | chrome/browser/views/browser_actions_container.cc | 5 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 53 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 52 |
6 files changed, 94 insertions, 97 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 0453880..09d30b7 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -238,7 +238,8 @@ void ExtensionHost::NavigateToURL(const GURL& url) { url_ = url; - if (!is_background_page() && !extension_->GetBackgroundPageReady()) { + if (!is_background_page() && + !profile_->GetExtensionsService()->IsBackgroundPageReady(extension_)) { // Make sure the background page loads before any others. registrar_.Add(this, NotificationType::EXTENSION_BACKGROUND_PAGE_READY, Source<Extension>(extension_)); @@ -253,7 +254,8 @@ void ExtensionHost::Observe(NotificationType type, const NotificationDetails& details) { switch (type.value) { case NotificationType::EXTENSION_BACKGROUND_PAGE_READY: - DCHECK(extension_->GetBackgroundPageReady()); + DCHECK(profile_->GetExtensionsService()-> + IsBackgroundPageReady(extension_)); NavigateToURL(url_); break; case NotificationType::RENDERER_PROCESS_CREATED: @@ -397,7 +399,7 @@ void ExtensionHost::DocumentAvailableInMainFrame(RenderViewHost* rvh) { document_element_available_ = true; if (is_background_page()) { - extension_->SetBackgroundPageReady(); + profile_->GetExtensionsService()->SetBackgroundPageReady(extension_); } else { switch (extension_host_type_) { case ViewType::EXTENSION_INFOBAR: diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 734bdef..ea025fb 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -150,6 +150,15 @@ PendingExtensionInfo::PendingExtensionInfo() enable_incognito_on_install(false), install_source(Extension::INVALID) {} + +ExtensionsService::ExtensionRuntimeData::ExtensionRuntimeData() + : background_page_ready(false), + being_upgraded(false) { +} + +ExtensionsService::ExtensionRuntimeData::~ExtensionRuntimeData() { +} + // ExtensionsService. const char* ExtensionsService::kInstallDirectoryName = "Extensions"; @@ -1386,6 +1395,9 @@ void ExtensionsService::UnloadExtension(const std::string& extension_id) { // Clean up if the extension is meant to be enabled after a reload. disabled_extension_paths_.erase(extension->id()); + // Clean up runtime data. + extension_runtime_data_.erase(extension_id); + ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, extension->GetChromeURLOverrides()); @@ -1413,6 +1425,7 @@ void ExtensionsService::UnloadExtension(const std::string& extension_id) { void ExtensionsService::UnloadAllExtensions() { extensions_.clear(); disabled_extensions_.clear(); + extension_runtime_data_.clear(); // TODO(erikkay) should there be a notification for this? We can't use // EXTENSION_UNLOADED since that implies that the extension has been disabled @@ -1485,8 +1498,8 @@ void ExtensionsService::OnExtensionLoaded(const Extension* extension, // Extensions get upgraded if silent upgrades are allowed, otherwise // they get disabled. if (allow_silent_upgrade) { - old->set_being_upgraded(true); - extension->set_being_upgraded(true); + SetBeingUpgraded(old, true); + SetBeingUpgraded(extension, true); } // To upgrade an extension in place, unload the old one and @@ -1524,7 +1537,7 @@ void ExtensionsService::OnExtensionLoaded(const Extension* extension, } } - extension->set_being_upgraded(false); + SetBeingUpgraded(extension, false); UpdateActiveExtensionsInCrashReporter(); @@ -1904,3 +1917,26 @@ ExtensionIdSet ExtensionsService::GetAppIds() const { return result; } + +bool ExtensionsService::IsBackgroundPageReady(const Extension* extension) { + return (extension->background_url().is_empty() || + extension_runtime_data_[extension->id()].background_page_ready); +} + +void ExtensionsService::SetBackgroundPageReady(const Extension* extension) { + DCHECK(!extension->background_url().is_empty()); + extension_runtime_data_[extension->id()].background_page_ready = true; + NotificationService::current()->Notify( + NotificationType::EXTENSION_BACKGROUND_PAGE_READY, + Source<const Extension>(extension), + NotificationService::NoDetails()); +} + +bool ExtensionsService::IsBeingUpgraded(const Extension* extension) { + return extension_runtime_data_[extension->id()].being_upgraded; +} + +void ExtensionsService::SetBeingUpgraded(const Extension* extension, + bool value) { + extension_runtime_data_[extension->id()].being_upgraded = value; +} diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 7cc2c9d..f5e541c 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -189,6 +189,17 @@ class ExtensionsService bool AllowFileAccess(const Extension* extension); void SetAllowFileAccess(const Extension* extension, bool allow); + // Whether the background page, if any, is ready. We don't load other + // components until then. If there is no background page, we consider it to + // be ready. + bool IsBackgroundPageReady(const Extension* extension); + void SetBackgroundPageReady(const Extension* extension); + + // Getter and setter for the flag that specifies whether the extension is + // being upgraded. + bool IsBeingUpgraded(const Extension* extension); + void SetBeingUpgraded(const Extension* extension, bool value); + // Initialize and start all installed extensions. void Init(); @@ -408,10 +419,25 @@ class ExtensionsService ExtensionIdSet GetAppIds() const; private: - virtual ~ExtensionsService(); friend class BrowserThread; friend class DeleteTask<ExtensionsService>; + // Contains Extension data that can change during the life of the process, + // but does not persist across restarts. + struct ExtensionRuntimeData { + // True if the background page is ready. + bool background_page_ready; + + // True while the extension is being upgraded. + bool being_upgraded; + + ExtensionRuntimeData(); + ~ExtensionRuntimeData(); + }; + typedef std::map<std::string, ExtensionRuntimeData> ExtensionRuntimeDataMap; + + virtual ~ExtensionsService(); + // Clear all persistent data that may have been stored by the extension. void ClearExtensionData(const GURL& extension_url); @@ -463,6 +489,9 @@ class ExtensionsService // The set of pending extensions. PendingExtensionMap pending_extensions_; + // The map of extension IDs to their runtime data. + ExtensionRuntimeDataMap extension_runtime_data_; + // The full path to the directory where extensions are installed. FilePath install_directory_; diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc index fb50270..b630806 100644 --- a/chrome/browser/views/browser_actions_container.cc +++ b/chrome/browser/views/browser_actions_container.cc @@ -915,7 +915,8 @@ void BrowserActionsContainer::BrowserActionAdded(const Extension* extension, // Enlarge the container if it was already at maximum size and we're not in // the middle of upgrading. - if ((model_->GetVisibleIconCount() < 0) && !extension->being_upgraded()) { + if ((model_->GetVisibleIconCount() < 0) && + !profile_->GetExtensionsService()->IsBeingUpgraded(extension)) { suppress_chevron_ = true; SaveDesiredSizeAndAnimate(Tween::LINEAR, visible_actions + 1); } else { @@ -940,7 +941,7 @@ void BrowserActionsContainer::BrowserActionRemoved(const Extension* extension) { // If the extension is being upgraded we don't want the bar to shrink // because the icon is just going to get re-added to the same location. - if (extension->being_upgraded()) + if (profile_->GetExtensionsService()->IsBeingUpgraded(extension)) return; if (browser_action_views_.size() > visible_actions) { diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 2ba995c..2bbf99b 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -249,18 +249,6 @@ const size_t Extension::kNumHostedAppPermissions = const char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage"; // -// Extension::RuntimeData -// - -Extension::RuntimeData::RuntimeData() - : background_page_ready(false), - being_upgraded(false) { -} - -Extension::RuntimeData::~RuntimeData() { -} - -// // Extension // @@ -270,7 +258,7 @@ scoped_refptr<Extension> Extension::Create(const FilePath& path, const DictionaryValue& value, bool require_key, std::string* error) { - scoped_refptr<Extension> extension(new Extension(path, location)); + scoped_refptr<Extension> extension = new Extension(path, location); if (!extension->InitFromValue(value, require_key, error)) return NULL; return extension; @@ -1000,10 +988,8 @@ Extension::Extension(const FilePath& path, Location location) DCHECK(path.IsAbsolute()); path_ = MaybeNormalizePath(path); } - Extension::~Extension() { } - ExtensionResource Extension::GetResource( const std::string& relative_path) const { #if defined(OS_POSIX) @@ -1929,20 +1915,6 @@ GURL Extension::GetFullLaunchURL() const { return GURL(launch_web_url()); } -bool Extension::GetBackgroundPageReady() const { - return (GetRuntimeData()->background_page_ready || - background_url().is_empty()); -} - -void Extension::SetBackgroundPageReady() const { - DCHECK(!background_url().is_empty()); - GetRuntimeData()->background_page_ready = true; - NotificationService::current()->Notify( - NotificationType::EXTENSION_BACKGROUND_PAGE_READY, - Source<Extension>(this), - NotificationService::NoDetails()); -} - static std::string SizeToString(const gfx::Size& max_size) { return base::IntToString(max_size.width()) + "x" + base::IntToString(max_size.height()); @@ -1968,11 +1940,9 @@ void Extension::SetCachedImage(const ExtensionResource& source, const FilePath& path = source.relative_path(); gfx::Size actual_size(image.width(), image.height()); if (actual_size == original_size) { - GetRuntimeData()->image_cache_[ - RuntimeData::ImageCacheKey(path, std::string())] = image; + image_cache_[ImageCacheKey(path, std::string())] = image; } else { - GetRuntimeData()->image_cache_[ - RuntimeData::ImageCacheKey(path, SizeToString(actual_size))] = image; + image_cache_[ImageCacheKey(path, SizeToString(actual_size))] = image; } } @@ -1996,16 +1966,15 @@ SkBitmap* Extension::GetCachedImageImpl(const ExtensionResource& source, const FilePath& path = source.relative_path(); // Look for exact size match. - RuntimeData::ImageCache::iterator i = GetRuntimeData()->image_cache_.find( - RuntimeData::ImageCacheKey(path, SizeToString(max_size))); - if (i != GetRuntimeData()->image_cache_.end()) + ImageCache::iterator i = image_cache_.find( + ImageCacheKey(path, SizeToString(max_size))); + if (i != image_cache_.end()) return &(i->second); // If we have the original size version cached, return that if it's small // enough. - i = GetRuntimeData()->image_cache_.find( - RuntimeData::ImageCacheKey(path, std::string())); - if (i != GetRuntimeData()->image_cache_.end()) { + i = image_cache_.find(ImageCacheKey(path, std::string())); + if (i != image_cache_.end()) { SkBitmap& image = i->second; if (image.width() <= max_size.width() && image.height() <= max_size.height()) @@ -2224,12 +2193,6 @@ bool Extension::CanExecuteScriptEverywhere() const { return false; } -Extension::RuntimeData* Extension::GetRuntimeData() const { - // TODO(mpcomplete): it would be nice if I could verify we were on the UI - // thread, but we're in common and don't have access to BrowserThread. - return const_cast<Extension::RuntimeData*>(&runtime_data_); -} - ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, const std::string& id, const FilePath& path, diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index b96eaec..ce7e628 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -100,28 +100,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> { bool is_public; // False if only this extension can load this plugin. }; - // Contains the subset of the extension's (private) data that can be modified - // after initialization. This class should only be accessed on the UI thread. - struct RuntimeData { - // We keep a cache of images loaded from extension resources based on their - // path and a string representation of a size that may have been used to - // scale it (or the empty string if the image is at its original size). - typedef std::pair<FilePath, std::string> ImageCacheKey; - typedef std::map<ImageCacheKey, SkBitmap> ImageCache; - - RuntimeData(); - ~RuntimeData(); - - // True if the background page is ready. - bool background_page_ready; - - // True while the extension is being upgraded. - bool being_upgraded; - - // Cached images for this extension. - ImageCache image_cache_; - }; - // A permission is defined by its |name| (what is used in the manifest), // and the |message_id| that's used by install/update UI. struct Permission { @@ -361,10 +339,8 @@ class Extension : public base::RefCountedThreadSafe<Extension> { int size, ExtensionIconSet::MatchType match_type) const; GURL GetIconURL(int size, ExtensionIconSet::MatchType match_type) const; - // Gets the fully resolved absolute launch URL. GURL GetFullLaunchURL() const; - // Image cache related methods. These are only valid on the UI thread and // not maintained by this class. See ImageLoadingTracker for usage. The // |original_size| parameter should be the size of the image at |source| @@ -440,22 +416,15 @@ class Extension : public base::RefCountedThreadSafe<Extension> { return theme_display_properties_.get(); } - // Whether the background page, if any, is ready. We don't load other - // components until then. If there is no background page, we consider it to - // be ready. - bool GetBackgroundPageReady() const; - void SetBackgroundPageReady() const; - - // Getter and setter for the flag that specifies whether the extension is - // being upgraded. - bool being_upgraded() const { return GetRuntimeData()->being_upgraded; } - void set_being_upgraded(bool value) const { - GetRuntimeData()->being_upgraded = value; - } - private: friend class base::RefCountedThreadSafe<Extension>; + // We keep a cache of images loaded from extension resources based on their + // path and a string representation of a size that may have been used to + // scale it (or the empty string if the image is at its original size). + typedef std::pair<FilePath, std::string> ImageCacheKey; + typedef std::map<ImageCacheKey, SkBitmap> ImageCache; + // Normalize the path for use by the extension. On Windows, this will make // sure the drive letter is uppercase. static FilePath MaybeNormalizePath(const FilePath& path); @@ -532,12 +501,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> { // this extension. string16 GetHostPermissionMessage() const; - // Returns a mutable pointer to our runtime data. Can only be called on - // the UI thread. - RuntimeData* GetRuntimeData() const; - - // Runtime data. - const RuntimeData runtime_data_; + // Cached images for this extension. This should only be touched on the UI + // thread. + mutable ImageCache image_cache_; // A persistent, globally unique ID. An extension's ID is used in things // like directory structures and URLs, and is expected to not change across |