Bug 653116: Sort plugins from most to least recently modified. Search them in this order for MIME/extension matches. They should also appear in this order in about:plugins. r=jst r=bent

This commit is contained in:
Josh Aas 2011-05-28 00:08:26 -04:00
Родитель b610ecccfc
Коммит de61523f19
2 изменённых файлов: 47 добавлений и 90 удалений

Просмотреть файл

@ -1616,8 +1616,7 @@ nsPluginHost::GetPluginTags(PRUint32* aPluginCount, nsIPluginTag*** aResults)
*aPluginCount = count;
plugin = mPlugins;
PRUint32 i;
for (i = 0; i < count; i++) {
for (PRUint32 i = 0; i < count; i++) {
(*aResults)[i] = plugin;
NS_ADDREF((*aResults)[i]);
plugin = plugin->mNext;
@ -2014,46 +2013,6 @@ PRBool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag)
return PR_FALSE;
}
// Structure for collecting plugin files found during directory scanning
struct pluginFileinDirectory
{
nsString mFilePath;
PRInt64 mModTime;
pluginFileinDirectory()
{
mModTime = LL_ZERO;
}
};
// QuickSort callback for comparing the modification time of two files
// if the times are the same, compare the filenames
NS_SPECIALIZE_TEMPLATE
class nsDefaultComparator<pluginFileinDirectory, pluginFileinDirectory>
{
public:
PRBool Equals(const pluginFileinDirectory& aA,
const pluginFileinDirectory& aB) const {
if (aA.mModTime == aB.mModTime &&
Compare(aA.mFilePath, aB.mFilePath,
nsCaseInsensitiveStringComparator()) == 0)
return PR_TRUE;
else
return PR_FALSE;
}
PRBool LessThan(const pluginFileinDirectory& aA,
const pluginFileinDirectory& aB) const {
if (aA.mModTime < aB.mModTime)
return PR_TRUE;
else if(aA.mModTime == aB.mModTime)
return Compare(aA.mFilePath, aB.mFilePath,
nsCaseInsensitiveStringComparator()) < 0;
else
return PR_FALSE;
}
};
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
@ -2077,8 +2036,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
if (NS_FAILED(rv))
return rv;
// Collect all the files in this directory in an array we can sort later
nsAutoTArray<pluginFileinDirectory, 8> pluginFilesArray;
nsAutoTArray<nsCOMPtr<nsILocalFile>, 6> pluginFiles;
PRBool hasMore;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
@ -2094,41 +2052,26 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
// See bug 197855.
dirEntry->Normalize();
nsAutoString filePath;
rv = dirEntry->GetPath(filePath);
if (NS_FAILED(rv))
continue;
if (nsPluginsDir::IsPluginFile(dirEntry)) {
pluginFileinDirectory * item = pluginFilesArray.AppendElement();
if (!item)
return NS_ERROR_OUT_OF_MEMORY;
// Get file mod time
PRInt64 fileModTime = LL_ZERO;
dirEntry->GetLastModifiedTime(&fileModTime);
item->mModTime = fileModTime;
item->mFilePath = filePath;
pluginFiles.AppendElement(dirEntry);
}
} // end round of up of plugin files
// now sort the array by file modification time or by filename, if equal
// put newer plugins first to weed out dups and catch upgrades, see bug 119966
pluginFilesArray.Sort();
}
PRBool warnOutdated = PR_FALSE;
// finally, go through the array, looking at each entry and continue processing it
for (PRUint32 i = 0; i < pluginFilesArray.Length(); i++) {
pluginFileinDirectory &pfd = pluginFilesArray[i];
nsCOMPtr <nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1");
nsCOMPtr <nsILocalFile> localfile = do_QueryInterface(file);
localfile->InitWithPath(pfd.mFilePath);
PRInt64 fileModTime = pfd.mModTime;
for (PRUint32 i = 0; i < pluginFiles.Length(); i++) {
nsCOMPtr<nsILocalFile>& localfile = pluginFiles[i];
nsString utf16FilePath;
rv = localfile->GetPath(utf16FilePath);
if (NS_FAILED(rv))
continue;
PRInt64 fileModTime = LL_ZERO;
localfile->GetLastModifiedTime(&fileModTime);
// Look for it in our cache
NS_ConvertUTF16toUTF8 filePath(pfd.mFilePath);
NS_ConvertUTF16toUTF8 filePath(utf16FilePath);
nsRefPtr<nsPluginTag> pluginTag;
RemoveCachedPluginsInfo(filePath.get(),
getter_AddRefs(pluginTag));
@ -2193,7 +2136,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
// if it is not found in cache info list or has been changed, create a new one
if (!pluginTag) {
nsPluginFile pluginFile(file);
nsPluginFile pluginFile(localfile);
// create a tag describing this plugin.
PRLibrary *library = nsnull;
@ -2293,16 +2236,42 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
}
pluginTag->SetHost(this);
pluginTag->mNext = mPlugins;
mPlugins = pluginTag;
if (pluginTag->IsEnabled())
// Add plugin tags such that the list is ordered by modification date,
// newest to oldest. This is ugly, it'd be easier with just about anything
// other than a single-directional linked list.
if (mPlugins) {
nsPluginTag *prev = nsnull;
nsPluginTag *next = mPlugins;
while (next) {
if (pluginTag->mLastModifiedTime >= next->mLastModifiedTime) {
pluginTag->mNext = next;
if (prev) {
prev->mNext = pluginTag;
} else {
mPlugins = pluginTag;
}
break;
}
prev = next;
next = prev->mNext;
if (!next) {
prev->mNext = pluginTag;
}
}
} else {
mPlugins = pluginTag;
}
if (pluginTag->IsEnabled()) {
pluginTag->RegisterWithCategoryManager(mOverrideInternalTypes);
}
}
}
if (warnOutdated)
if (warnOutdated) {
mPrefService->SetBoolPref("plugins.update.notifyUser", PR_TRUE);
}
return NS_OK;
}
@ -2546,17 +2515,6 @@ nsresult nsPluginHost::FindPlugins(PRBool aCreatePluginList, PRBool * aPluginsCh
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsPluginTag>, mCachedPlugins, mNext);
NS_ITERATIVE_UNREF_LIST(nsRefPtr<nsInvalidPluginTag>, mInvalidPlugins, mNext);
// reverse our list of plugins
nsRefPtr<nsPluginTag> next;
nsRefPtr<nsPluginTag> prev;
for (nsRefPtr<nsPluginTag> cur = mPlugins; cur; cur = next) {
next = cur->mNext;
cur->mNext = prev;
prev = cur;
}
mPlugins = prev;
NS_TIMELINE_STOP_TIMER("LoadPlugins");
NS_TIMELINE_MARK_TIMER("LoadPlugins");

Просмотреть файл

@ -58,7 +58,6 @@ class nsIAccessible;
class nsPluginInstanceOwner;
class nsPluginHost;
class nsIPluginInstance;
class nsPresContext;
class nsDisplayPlugin;
class nsIDOMElement;