Bug 882339 - Cache the blocklist state on plugin tags to avoid querying the blocklist service constantly, r=johns

This commit is contained in:
Benjamin Smedberg 2013-06-19 11:07:28 -04:00
parent 9716b68e35
commit 3b87991102
6 changed files with 77 additions and 38 deletions

View File

@ -115,8 +115,8 @@ function updateBlocklist(aCallback) {
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);
var observer = function() {
aCallback();
Services.obs.removeObserver(observer, "blocklist-updated");
SimpleTest.executeSoon(aCallback);
};
Services.obs.addObserver(observer, "blocklist-updated", false);
blocklistNotifier.notify(null);

View File

@ -58,8 +58,8 @@ function updateBlocklist(aCallback) {
var blocklistNotifier = Components.classes["@mozilla.org/extensions/blocklist;1"]
.getService(Components.interfaces.nsITimerCallback);
var observer = function() {
aCallback();
Services.obs.removeObserver(observer, "blocklist-updated");
SimpleTest.executeSoon(aCallback);
};
Services.obs.addObserver(observer, "blocklist-updated", false);
blocklistNotifier.notify(null);

View File

@ -292,6 +292,7 @@ nsPluginHost::nsPluginHost()
mozilla::services::GetObserverService();
if (obsService) {
obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
obsService->AddObserver(this, "blocklist-updated", false);
#ifdef MOZ_WIDGET_ANDROID
obsService->AddObserver(this, "application-foreground", false);
obsService->AddObserver(this, "application-background", false);
@ -1068,17 +1069,12 @@ nsPluginHost::GetBlocklistStateForType(const char *aMimeType, uint32_t *aState)
if (!plugin) {
plugin = FindPluginForType(aMimeType, false);
}
if (plugin) {
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
if (blocklist) {
// The EmptyString()s are so we use the currently running application
// and toolkit versions
return blocklist->GetPluginBlocklistState(plugin, EmptyString(),
EmptyString(), aState);
}
if (!plugin) {
return NS_ERROR_FAILURE;
}
return NS_ERROR_FAILURE;
*aState = plugin->GetBlocklistState();
return NS_OK;
}
NS_IMETHODIMP
@ -1931,25 +1927,17 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
pluginTag->mLibrary = library;
pluginTag->mLastModifiedTime = fileModTime;
uint32_t state = pluginTag->GetBlocklistState();
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
if (blocklist) {
uint32_t state;
rv = blocklist->GetPluginBlocklistState(pluginTag, EmptyString(),
EmptyString(), &state);
if (NS_SUCCEEDED(rv)) {
// If the blocklist says it is risky and we have never seen this
// plugin before, then disable it.
// If the blocklist says this is an outdated plugin, warn about
// outdated plugins.
if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
pluginTag->SetEnabledState(nsIPluginTag::STATE_DISABLED);
}
if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) {
warnOutdated = true;
}
}
// If the blocklist says it is risky and we have never seen this
// plugin before, then disable it.
// If the blocklist says this is an outdated plugin, warn about
// outdated plugins.
if (state == nsIBlocklistService::STATE_SOFTBLOCKED && !seenBefore) {
pluginTag->SetEnabledState(nsIPluginTag::STATE_DISABLED);
}
if (state == nsIBlocklistService::STATE_OUTDATED && !seenBefore) {
warnOutdated = true;
}
// Plugin unloading is tag-based. If we created a new tag and loaded
@ -3146,12 +3134,12 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *someData)
{
if (!nsCRT::strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
OnShutdown();
UnloadPlugins();
sInst->Release();
}
if (!nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
mPluginsDisabled = Preferences::GetBool("plugin.disable", false);
mPluginsClickToPlay = Preferences::GetBool("plugins.click_to_play", false);
// Unload or load plugins as needed
@ -3161,19 +3149,26 @@ NS_IMETHODIMP nsPluginHost::Observe(nsISupports *aSubject,
LoadPlugins();
}
}
if (!strcmp("blocklist-updated", aTopic)) {
nsPluginTag* plugin = mPlugins;
while (plugin) {
plugin->InvalidateBlocklistState();
plugin = plugin->mNext;
}
}
#ifdef MOZ_WIDGET_ANDROID
if (!nsCRT::strcmp("application-background", aTopic)) {
if (!strcmp("application-background", aTopic)) {
for(uint32_t i = 0; i < mInstances.Length(); i++) {
mInstances[i]->NotifyForeground(false);
}
}
if (!nsCRT::strcmp("application-foreground", aTopic)) {
if (!strcmp("application-foreground", aTopic)) {
for(uint32_t i = 0; i < mInstances.Length(); i++) {
if (mInstances[i]->IsOnScreen())
mInstances[i]->NotifyForeground(true);
}
}
if (!nsCRT::strcmp("memory-pressure", aTopic)) {
if (!strcmp("memory-pressure", aTopic)) {
for(uint32_t i = 0; i < mInstances.Length(); i++) {
mInstances[i]->MemoryPressure();
}

View File

@ -80,7 +80,9 @@ nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
mFullPath(aPluginTag->mFullPath),
mVersion(aPluginTag->mVersion),
mLastModifiedTime(0),
mNiceFileName()
mNiceFileName(),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
mCachedBlocklistStateValid(false)
{
}
@ -94,7 +96,9 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
mFullPath(aPluginInfo->fFullPath),
mVersion(aPluginInfo->fVersion),
mLastModifiedTime(0),
mNiceFileName()
mNiceFileName(),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
mCachedBlocklistStateValid(false)
{
InitMime(aPluginInfo->fMimeTypeArray,
aPluginInfo->fMimeDescriptionArray,
@ -123,7 +127,9 @@ nsPluginTag::nsPluginTag(const char* aName,
mFullPath(aFullPath),
mVersion(aVersion),
mLastModifiedTime(aLastModifiedTime),
mNiceFileName()
mNiceFileName(),
mCachedBlocklistState(nsIBlocklistService::STATE_NOT_BLOCKED),
mCachedBlocklistStateValid(false)
{
InitMime(aMimeTypes, aMimeDescriptions, aExtensions,
static_cast<uint32_t>(aVariants));
@ -538,3 +544,35 @@ void nsPluginTag::ImportFlagsToPrefs(uint32_t flags)
SetPluginState(ePluginState_Disabled);
}
}
uint32_t
nsPluginTag::GetBlocklistState()
{
if (mCachedBlocklistStateValid) {
return mCachedBlocklistState;
}
nsCOMPtr<nsIBlocklistService> blocklist = do_GetService("@mozilla.org/extensions/blocklist;1");
if (!blocklist) {
return nsIBlocklistService::STATE_NOT_BLOCKED;
}
// The EmptyString()s are so we use the currently running application
// and toolkit versions
uint32_t state;
if (NS_FAILED(blocklist->GetPluginBlocklistState(this, EmptyString(),
EmptyString(), &state))) {
return nsIBlocklistService::STATE_NOT_BLOCKED;
}
MOZ_ASSERT(state <= UINT16_MAX);
mCachedBlocklistState = (uint16_t) state;
mCachedBlocklistStateValid = true;
return state;
}
void
nsPluginTag::InvalidateBlocklistState()
{
mCachedBlocklistStateValid = false;
}

View File

@ -85,8 +85,14 @@ public:
nsCString mVersion; // UTF-8
int64_t mLastModifiedTime;
nsCOMPtr<nsITimer> mUnloadTimer;
uint32_t GetBlocklistState();
void InvalidateBlocklistState();
private:
nsCString mNiceFileName; // UTF-8
uint16_t mCachedBlocklistState;
bool mCachedBlocklistStateValid;
void InitMime(const char* const* aMimeTypes,
const char* const* aMimeDescriptions,

View File

@ -11,8 +11,8 @@ function updateBlocklist(aCallback) {
var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"]
.getService(Ci.nsITimerCallback);
var observer = function() {
aCallback();
Services.obs.removeObserver(observer, "blocklist-updated");
SimpleTest.executeSoon(aCallback);
};
Services.obs.addObserver(observer, "blocklist-updated", false);
blocklistNotifier.notify(null);