diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,888 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Plugin handling, manages the loading and unloading of the +* plugin. Initializes the CInfoArray that contains the plugin +* MIME-types supported. +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include "../../bidi.h" + +// System includes +#include + + +// INCLUDES +#include "WebCorePluginHandler.h" +#include "NPNImplementation.h" +#include "PluginHandler.h" + +// CONSTANTS + +const TInt KPluginGranularity = 3; +const TInt KMimeTypeLength = 7; + +_LIT( KMimeTypeAudio, "audio/" ); +_LIT( KMimeTypeVideo, "video/" ); + +// LOCAL FUNCTION PROTOTYPES +typedef NPError (*NPP_InitializeFunc)(NPNetscapeFuncs *netscapeFuncs, + NPPluginFuncs *pluginFuncs); +typedef void (*NPP_ShutdownFunc)(void); + +#define LOAD_PLUGINS if(!m_pluginsLoaded) { TRAP_IGNORE(loadPluginsL()); m_pluginsLoaded = ETrue; } + + +// ============================ MEMBER FUNCTIONS =============================== + +void panicHandler(TInt error = KErrNone) +{ + User::Panic(_L("Object Handling Panic"), error); +} + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// PluginInfo::PluginInfo +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +// +PluginInfo::PluginInfo() + : m_mimeTypes(KPluginGranularity), + m_mimeFileExtensions(KPluginGranularity), + m_mimeExtensionToTypeMap(KPluginGranularity), + m_mimeDescriptions(KPluginGranularity), + m_handle(-1) +{ +} + +// ----------------------------------------------------------------------------- +// PluginInfo::~PluginInfo +// +// Deconstructor. +// ----------------------------------------------------------------------------- +// +PluginInfo::~PluginInfo() +{ + m_mimeDescriptions.ResetAndDestroy(); + m_mimeDescriptions.Close(); + + // Don't ResetAndDestroy() the m_mimeExtensionToTypeMap array, this array + // contains pointers (memory) that is cleaned up in the m_mimeTypes array + m_mimeExtensionToTypeMap.Close(); + + m_mimeFileExtensions.ResetAndDestroy(); + m_mimeFileExtensions.Close(); + + m_mimeTypes.ResetAndDestroy(); + m_mimeTypes.Close(); + + delete m_name; + delete m_description; + delete m_nppFuncs; + delete m_filename; + +} + +// ----------------------------------------------------------------------------- +// PluginInfo::ShouldLoad +// +// Returns ETrue if the plugin should be loaded. +// ----------------------------------------------------------------------------- +// +TBool PluginInfo::shouldLoad() +{ + return m_ref < 1; +} + +// ----------------------------------------------------------------------------- +// PluginInfo::ShouldUnload +// +// Returns ETrue if the plugin should be unloaded. +// ----------------------------------------------------------------------------- +// +TBool PluginInfo::shouldUnload() +{ + return m_ref == 1; +} + +// ----------------------------------------------------------------------------- +// PluginInfo::LoadInstance +// +// Increments the PluginInfo's reference count +// ----------------------------------------------------------------------------- +// +void PluginInfo::loadInstance() +{ + m_ref++; +} + +// ----------------------------------------------------------------------------- +// PluginInfo::UnloadInstance +// +// Decrements the PluginInfo's reference count. +// ----------------------------------------------------------------------------- +// +void PluginInfo::unloadInstance() +{ + m_ref--; +} + +// ----------------------------------------------------------------------------- +// PluginInfo::CopyMimeDescription +// +// Copy the mimetypes and file extention from one plugin info struct to another, +// Called after a rescan of the file system +// ----------------------------------------------------------------------------- +// +void PluginInfo::copyMimeDescription(PluginInfo& pluginInfo) +{ + TUint i; + TUint count; + HBufC* entry; + + m_mimeTypes.ResetAndDestroy(); + m_mimeExtensionToTypeMap.Reset(); + count = pluginInfo.m_mimeTypes.Count(); + for (i = 0; i < count; i++) { + entry = pluginInfo.m_mimeTypes[0]->Des().Alloc(); + pluginInfo.m_mimeTypes.Remove(0); + m_mimeTypes.Append(entry); + } + + HBufC8* extEntry; + m_mimeFileExtensions.ResetAndDestroy(); + count = pluginInfo.m_mimeFileExtensions.Count(); + for (i = 0; i < count; i++) { + extEntry = pluginInfo.m_mimeFileExtensions[0]->Des().Alloc(); + pluginInfo.m_mimeFileExtensions.Remove(0); + m_mimeFileExtensions.Append(extEntry); + m_mimeExtensionToTypeMap.Append(entry); + } +} + +// ----------------------------------------------------------------------------- +// PluginInfo::GetMimeExtensionsL +// +// Gets the supported mimeExtensions for the mimeType presented. Returns a HBufC* +// that has allocated memory, which is the responsibility of the caller to +// clean up. The HBufC* will be NULL if no supported mimeExtensions are supported. +// ----------------------------------------------------------------------------- +// +HBufC8* PluginInfo::getMimeExtensionsL(const TDesC& mimeType) +{ + HBufC8* mimeTypeBuf = HBufC8::NewLC(128); + TPtr8 mimeTypePtr(mimeTypeBuf->Des()); + // + for (TInt i = 0; i < m_mimeExtensionToTypeMap.Count(); i++) { + + if (*(m_mimeExtensionToTypeMap[i]) == mimeType) { + // We found a mimeType match, save the mimeExtension + HBufC8* mimeExtensionBuf = m_mimeFileExtensions[i]; + // Make sure we can fit this mimeFileExtension + TInt length = mimeExtensionBuf->Length(); + // +1 is for ',' + if (mimeTypePtr.Length() + length + 1 > mimeTypePtr.MaxLength()) { + HBufC8* tmp = HBufC8::NewL(mimeTypePtr.Length() + 2 * length); + mimeTypePtr.Set(tmp->Des()); + mimeTypePtr.Copy(*mimeTypeBuf); + CleanupStack::PopAndDestroy(); // mimeTypeBuf + mimeTypeBuf = tmp; + CleanupStack::PushL(mimeTypeBuf); + } + // append ',' unless this is the first item in the list + if (mimeTypePtr.Length()) + mimeTypePtr.Append(','); + + mimeTypePtr.Append(*mimeExtensionBuf); + } + } + + CleanupStack::Pop(); //mimeTypeBuf + return mimeTypeBuf; +} + +// ----------------------------------------------------------------------------- +// PluginInfo::ParseDefaultDataL(const TDesC8& mimeDesc) +// +// Parses the default_data string from resource file to populate the mimeTypes, mimeExtensions, +// and mimeDescriptions arrays. +// ----------------------------------------------------------------------------- +// +void PluginInfo::parseDefaultDataL(const TDesC8& mimeDesc) +{ + __ASSERT_DEBUG(mimeDesc.Ptr() != NULL, panicHandler()); + + _LIT(KPattern1Ptr, ",;|"); + _LIT(KPattern2Ptr, ";|"); + + TUint end(mimeDesc.Length()); + TUint i(0); + TUint marker(0); + TUint16 mimeSeparator('|'); + TUint fieldSeparator(';'); + HBufC* newMimeTypeEntry = NULL; + HBufC8* newMimeFileExtEntry = NULL; + HBufC* newMimeDescriptionEntry = NULL; + + // Parse the mimeDesc string to populate the mimeTypes, mimeExtensions, + // and mimeDescriptions arrays. + + for (; i < end;) { // outer for loop + // Search until end of buffer or match one of the delimiters ';' or '|'. + // We are looking for the mimeType, ie "text/html", "application/pdf", etc. + for (; (i < end) && (KPattern2Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) { + // Walking the mimeDesc string + } + + if (i > marker) { + // Create new mimeType entry, the first entry is mimeType + TPtrC8 mimeType8(mimeDesc.Mid(marker,i-marker)); + newMimeTypeEntry = HBufC::NewLC(i-marker); + newMimeTypeEntry->Des().Copy(mimeType8); + User::LeaveIfError(m_mimeTypes.Append(newMimeTypeEntry)); + CleanupStack::Pop(); //pop newMimeTypeEntry + } + + // Are we at the end of the supported mime string + if (i == end) { + // This break with i=end means we leave outer for loop + break; + } + + marker = ++i; + if ((mimeDesc)[i - 1] == mimeSeparator) { + // Found a mime separator '|', get next supported mime + continue; + } + + // We are looking for the mimeFileExtensions, ie "html", "htm", "pdf", "txt", etc. + // There can be multiple mimeFileExtentions per mimeType + for (; (i < end);) { // inner for loop + + // Search until end of buffer or match one of the delimiters ';' or ',' or '|'. + for (; (i < end) && (KPattern1Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) { + // Walking the mimeDesc string + } + + if (i > marker) { + TPtrC8 mimeFileExt8(mimeDesc.Mid(marker,i-marker)); + newMimeFileExtEntry = HBufC8::NewLC(i-marker); + newMimeFileExtEntry->Des().Copy(mimeFileExt8); + User::LeaveIfError(m_mimeFileExtensions.Append(newMimeFileExtEntry)); + CleanupStack::Pop(); //pop newMimeFileExtEntry + + // Add the mimeType to the mapping array. Every mimeFileExtension entry + // in m_mimeFileExtensions, has a corresponding mimeType entry in + // m_mimeExtensionToTypeMap. This allows us to provide a list of + // extensions for each supported mimeType. + User::LeaveIfError(m_mimeExtensionToTypeMap.Append(newMimeTypeEntry)); + } + + // Are we at the end of the supported mime string + if (i == end) { + // This break means we leave the inner loop, and with i=end means + // we leave the outer loop + break; + } + + marker = ++i; + if ((mimeDesc)[i - 1] == mimeSeparator) { + // Found a mime separator '|', get next supported mime + break; + } + + if ((mimeDesc)[i - 1] == fieldSeparator) { + + // Found a field separator ';', get the mimeDescription. + // Search until end of buffer or match one of the delimiters ';' or '|'. + for (; (i < end) && (KPattern2Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) { + // Walking the mimeDesc string + } + + if (i > marker) { + // Create new mimeDescription entry + TPtrC8 mimeDesc8(mimeDesc.Mid(marker,i-marker)); + newMimeDescriptionEntry = HBufC::NewLC(i-marker); + newMimeDescriptionEntry->Des().Copy(mimeDesc8); + + User::LeaveIfError(m_mimeDescriptions.Append(newMimeDescriptionEntry)); + CleanupStack::Pop(); //pop newMimeDescriptionEntry + } + + // Are we at the end of the supported mime string + if (i == end) { + // This break means we leave the inner loop, and with i=end means + // we leave the outer loop + break; + } + + marker = ++i; + // Make sure we start at the next mime, after we found the mimeDescription. + // We are handling a mime string with an extra semi-colon(s), + // ie "...mimeDescription1;|mimeType2 + for (; (i < end) && ((mimeDesc)[i-1] != mimeSeparator); i++) { + // Walking the mimeDesc string + } + + // Leave the inner loop and look for the next mime + break; + + } // end of if fieldSeparator aka get mimeDescription + + // If we get here, we have another mimeFileExtension. Continue on the + // inner loop to find additional mimeFileExtensions. + + } // end of inner for (;iStart(TCallBack(initialize, this)); +} + + +// ----------------------------------------------------------------------------- +// PluginHandler::NewL +// +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +PluginHandler* PluginHandler::NewL(TBool enablePlugins) +{ + PluginHandler* self = new(ELeave) PluginHandler(enablePlugins); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::~PluginHandler +// +// Deconstructor. +// ----------------------------------------------------------------------------- +// +PluginHandler::~PluginHandler() +{ + m_pluginInfoArray.ResetAndDestroy(); + m_pluginInfoArray.Close(); + if (m_idle) { + m_idle->Cancel(); + } + delete m_idle; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::Initialize +// +// Initializes the PluginHandler, possibly asynchronously +// ----------------------------------------------------------------------------- +// +TBool PluginHandler::initialize(TAny* pluginHandler) +{ + TBool doneInit(EFalse); + + PluginHandler* handler = (PluginHandler*)pluginHandler; + + TRAPD(err, doneInit = handler->loadPluginsL()); + if (err) { + // If we leave from LoadPluginsL, stop CIdle + doneInit = EFalse; + } + + return doneInit; +} + +//------------------------------------------------------------------------------ +// PluginHandler::loadPluginsL +// +// Loads all the plugins and query them for details. +// ----------------------------------------------------------------------------- +// +TBool PluginHandler::loadPluginsL() +{ + + if(m_pluginsLoaded) { + return EFalse; + } + + // 1) fetch CImplementationInformation instances from the ECOM infrastructure + // 2) create plugin info for each plugin + + // Create the ECom info array, contains the plugin information + RImplInfoPtrArray ecomPluginInfoArray; + + // Get list of ECOM plugins that match the KNBrowserPluginInterfaceUid + REComSession::ListImplementationsL(KBrowserPluginInterfaceUid, ecomPluginInfoArray); + + // Loop through all the Netscape plugins found by ECom and populate the + // m_pluginInfoArray + m_nextHandle = 0; + const TInt pluginCount = ecomPluginInfoArray.Count(); + for (TInt index=0; indexm_handle = m_nextHandle++; + CleanupStack::PushL(pluginInfo); + + // Set the plugin properties + pluginInfo->m_pluginInfo = ecomPluginInfoArray[index]; + // Read the plugin's name and plugin FileName (display_name) from the IMPLEMENTATION_INFO + pluginInfo->parseDisplayNameL(pluginInfo->m_pluginInfo->DisplayName()); + pluginInfo->m_description = HBufC::NewL(pluginInfo->m_pluginInfo->OpaqueData().Length()); + pluginInfo->m_description->Des().Copy(pluginInfo->m_pluginInfo->OpaqueData()); + pluginInfo->m_uid = pluginInfo->m_pluginInfo->ImplementationUid(); + // Parses the mimeDesc string to populate the mimeTypes, mimeExtensions, + // and mimeDescriptions arrays. + pluginInfo->parseDefaultDataL(pluginInfo->m_pluginInfo->DataType()); + + // Add the filter information to the list + User::LeaveIfError(m_pluginInfoArray.Append(pluginInfo)); + CleanupStack::Pop(); // pluginInfo + } + + // Clean up the ECom info array + ecomPluginInfoArray.ResetAndDestroy(); + ecomPluginInfoArray.Close(); + + m_pluginsLoaded = ETrue; + return EFalse; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::findPlugin +// +// Find a plugin by MIME type. +// ----------------------------------------------------------------------------- +// +TInt PluginHandler::findPlugin(const TDesC& mimeType) +{ + LOAD_PLUGINS + + HBufC* newMimeType = NULL; + _LIT(KSeparator, "*"); + TInt pluginIndex; + TInt mimeIndex; + + if (mimeType.FindF(KMimeTypeAudio) != KErrNotFound){ + newMimeType = HBufC::NewLC(KMimeTypeLength); + newMimeType->Des().Copy(KMimeTypeAudio); + newMimeType->Des().Append(KSeparator); + } + else if (mimeType.FindF(KMimeTypeVideo) != KErrNotFound){ + newMimeType = HBufC::NewLC(KMimeTypeLength); + newMimeType->Des().Copy(KMimeTypeVideo); + newMimeType->Des().Append(KSeparator); + } + else{ + newMimeType = HBufC::NewLC(mimeType.Length()); + newMimeType = mimeType.AllocL(); + } + CleanupStack::Pop(); //pop newMimeType + + for (pluginIndex = 0; pluginIndex < m_pluginInfoArray.Count(); pluginIndex++) { + for (mimeIndex = 0; + mimeIndex < m_pluginInfoArray[pluginIndex]->m_mimeTypes.Count(); + mimeIndex++) { + if (!m_pluginInfoArray[pluginIndex]->m_mimeTypes[mimeIndex]->CompareF(*newMimeType)) { + delete newMimeType; + return m_pluginInfoArray[pluginIndex]->m_handle; + } + } + } + delete newMimeType; + return KErrNotFound; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::findPluginByExtension +// +// Find a plugin by file extension. +// ----------------------------------------------------------------------------- +// +TInt PluginHandler::findPluginByExtension(const TDesC8& url) +{ + LOAD_PLUGINS + + TInt pluginIndex; + TInt extIndex; + + TPtrC8 extPtr(url.Mid(url.LocateReverse('.') + 1)); + for (pluginIndex = 0; pluginIndex < m_pluginInfoArray.Count(); pluginIndex++) { + + for (extIndex = 0; + extIndex < m_pluginInfoArray[pluginIndex]-> + m_mimeFileExtensions.Count(); extIndex++) { + + if (!m_pluginInfoArray[pluginIndex]->m_mimeFileExtensions[extIndex]->CompareF(extPtr)) { + return m_pluginInfoArray[pluginIndex]->m_handle; + } + } + } + + return KErrNotFound; +} + + +// ----------------------------------------------------------------------------- +// PluginHandler::loadPluginL +// +// Load a plugin if not yet loaded and return its function table. The handle was +// gotten from the methods FindPlugin and FindPluginFromExtension, so the +// handle should be valid. +// ----------------------------------------------------------------------------- +// +void PluginHandler::loadPluginL(TInt handle, NPPluginFuncs** retPluginFuncs) +{ + LOAD_PLUGINS + + TUint index(getIndexFromHandle(handle)); + __ASSERT_DEBUG(index < (TUint)m_pluginInfoArray.Count(), panicHandler()); + + PluginInfo* plugin = m_pluginInfoArray[index]; + + if (plugin->shouldLoad()) { + + NPPluginFuncs* pluginFuncs = (NPPluginFuncs*) User::AllocLC(sizeof (NPPluginFuncs)); + Mem::FillZ((void*) pluginFuncs, sizeof (NPPluginFuncs)); + // create CEcomBrowserPluginInterface, given the UID from the PLuginInfo, when ref count == 0 + plugin->m_pluginInterface = CEcomBrowserPluginInterface::CreatePluginL(plugin->m_uid, + (NPNetscapeFuncs *) (&NpnImplementationFuncs), pluginFuncs); + + CleanupStack::Pop(pluginFuncs); + plugin->m_nppFuncs = pluginFuncs; + pluginFuncs = NULL; + } + + plugin->loadInstance(); + __ASSERT_DEBUG(plugin->m_nppFuncs != NULL, panicHandler()); + *retPluginFuncs = plugin->m_nppFuncs; + +} + + +// ----------------------------------------------------------------------------- +// PluginHandler::UnloadPlugin +// +// Unload a plugin. If this is the last instance, the library is unloaded. +// The handle was gotten from the methods FindPlugin and FindPluginFromExtension, +// so the handle should be valid. +// ----------------------------------------------------------------------------- +// +void PluginHandler::unloadPlugin(TInt handle) +{ + TUint index(getIndexFromHandle(handle)); + __ASSERT_DEBUG(index < (TUint) m_pluginInfoArray.Count(), panicHandler()); + + PluginInfo* plugin = m_pluginInfoArray[index]; + + if (plugin->shouldUnload()) { + User::Free(plugin->m_nppFuncs); + plugin->m_nppFuncs = NULL; + // delete the CEcomBrowserPluginInterface instance when ref count == 0 + delete plugin->m_pluginInterface; + } + + plugin->unloadInstance(); +} + +// ----------------------------------------------------------------------------- +// PluginHandler::GetIndexFromHandle +// +// Get the index of plugin info from its handle. This method should always +// return a valid handle, since the calling program got the handle from the +// methods FindPlugin and FindPluginFromExtension. +// ----------------------------------------------------------------------------- +// +TUint PluginHandler::getIndexFromHandle(TInt handle) +{ + LOAD_PLUGINS + TUint index; + TUint count(m_pluginInfoArray.Count()); + + __ASSERT_DEBUG(handle >= 0, panicHandler()); + + for (index = 0; index < count; index++) { + if (m_pluginInfoArray[index]->m_handle == handle) { + return index; + } + } + + // We should never get here. We should always return a valid handle. Return + // the count (handle + 1), this should assert debug in calling methods, as + // well as the forced assert debug . + __ASSERT_DEBUG(EFalse, panicHandler()); + return count; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::GetPluginCount +// +// Returns the number of plugins supported by the platform +// ----------------------------------------------------------------------------- +TInt PluginHandler::getPluginCount() +{ + LOAD_PLUGINS + return m_pluginInfoArray.Count(); +} + +TBool PluginHandler::pluginSupportsMIMEType(const TDesC& mimeType) +{ + return findPlugin(mimeType) != KErrNotFound; +} + +TBool PluginHandler::objectAtIndex(TInt index, TWebCorePluginInfo& pluginInfo ) +{ + if (index<0 || index>m_pluginInfoArray.Count()-1) + return EFalse; + + PluginInfo* pinfo = m_pluginInfoArray[index]; + if (!pinfo) + return EFalse; + + pluginInfo.iName.Set(KNullDesC()); + pluginInfo.iFilename.Set(KNullDesC()); + pluginInfo.iPluginDescription.Set(KNullDesC()); + // + if (pinfo->name()) + pluginInfo.iName.Set(*(pinfo->name())); + if (pinfo->fileName()) + pluginInfo.iFilename.Set(*(pinfo->fileName())); + if (pinfo->description()) + pluginInfo.iPluginDescription.Set(*(pinfo->description())); + + pluginInfo.iMimeTypeArray = pinfo->mimeTypes(); + + return ETrue; +} + +void PluginHandler::refreshPlugins(TBool reload) +{ + TRAP_IGNORE(reloadPluginsL(reload)); +} + +HBufC8* PluginHandler::extensionsForMIMEType(TInt index, TDesC& mimeType ) +{ + PluginInfo *pluginInfo = m_pluginInfoArray[index]; + HBufC8 *extn = NULL; + TRAP_IGNORE(extn = pluginInfo->getMimeExtensionsL(mimeType)); + return extn; +} + +HBufC* PluginHandler::descriptionForMIMEType(TInt index, TDesC& mimeType ) +{ + // there is no way to tell mimeType-description pairs. return the whole string + PluginInfo *pluginInfo = m_pluginInfoArray[index]; + RPointerArray items = pluginInfo->mimeDescriptions(); + HBufC* descBuf = HBufC::New(128); + if (!descBuf) + return descBuf; + + TPtr descPtr(descBuf->Des()); + for (TInt i=0; iLength(); + // +1 is for ',' + if (descPtr.Length() + length + 1 > descPtr.MaxLength()) { + HBufC* tmp = HBufC::New(descPtr.Length() + 2 * length); + if (!tmp) { + // return whatever we have + return descBuf; + } + descPtr.Set(tmp->Des()); + descPtr.Copy(*descBuf); + descBuf = tmp; + } + // append ',' unless this is the first item in the list + if (descPtr.Length()) + descPtr.Append(','); + descPtr.Append(*desc); + } + + return descBuf; +} + +// ----------------------------------------------------------------------------- +// PluginHandler::ReloadPluginsL +// +// Rescan for new plugins. +// ----------------------------------------------------------------------------- +// +void PluginHandler::reloadPluginsL(TBool reload) +{ + // This function stores the plugins that are currently loaded in a temp array + // Then it rescans the drives for all plugins + // Currently loaded plugins must exist in the new list because the dll is loaded + // and the plugin could not be deleted from the file system while the dll is loaded. + // After rescanning, each plugin from the temp array is matched with a plugin + // in the new array. The matching is done by file name. + // Each new entry is replaced with the existing entry from the temp array. + // This is done because the CPluginInst object keeps the handle and + // the function table of the existing plugin. + + RPointerArray tmpPluginInfoArray; + PluginInfo* pluginInfo = NULL; + TInt count(m_pluginInfoArray.Count()); + TInt index; + + // Copy all the loaded plugins to a temp array + for (index = 0; index < count; index++) { + pluginInfo = m_pluginInfoArray[0]; + if (pluginInfo->shouldLoad()) { // Is it currently loaded? + m_pluginInfoArray.Remove(0); + delete pluginInfo; + pluginInfo = NULL; + } + else { + m_pluginInfoArray.Remove(0); + tmpPluginInfoArray.Append(pluginInfo); + } + } + + // reload the plugins by scanning the drives + if (m_idle) { + m_idle->Cancel(); + } + + //Load the plugins synchronously + m_asyncLoading = EFalse; + m_pluginsLoaded =EFalse; + loadPluginsL(); + count = m_pluginInfoArray.Count(); + + TInt tmpCount(tmpPluginInfoArray.Count()); + TInt i; + PluginInfo* delPluginInfo = NULL; + for (index = 0; index < tmpCount; index++) { + pluginInfo = tmpPluginInfoArray[0]; + tmpPluginInfoArray.Remove(0); + // Search through the array for a filename match + // use ECOM Uid rather then file names + for (i = 0; i < count && (pluginInfo->m_uid != m_pluginInfoArray[i]->m_uid); i++) { + } + + if (i == count) { + i = -1; + } + + if (i >= 0) { + // i < 0 only if rescanning failed + delPluginInfo = m_pluginInfoArray[i]; + m_pluginInfoArray.Remove(i); + // Save the new Mimetype and extensions. They might be different than before + pluginInfo->copyMimeDescription(*delPluginInfo); + + delete (delPluginInfo); + delPluginInfo = NULL; + } + + m_pluginInfoArray.Append(pluginInfo); + } + + tmpPluginInfoArray.Close(); + if (reload) { + //m_view.mainFrame().WebKitBridge().reload(); + } + +} + +// ----------------------------------------------------------------------------- +// PluginHandler::IsSupported +// +// Determines whether a given content-type of dot-extension has a cooresponding +// plugin or external application. aContentType and aUrl can be NULL, but at least +// one must be non-NULL (otherwise it will always return EFalse). If handlerType +// is EPlugin then it returns ETrue only if their is a supported plugin. If handlerType +// is EExternalApp then it returns ETrue only if their is a supported external +// application. If handlerType is EBoth then it returns ETrue only if their is a +// supported plugin or external application. +// ----------------------------------------------------------------------------- +TBool PluginHandler::isSupported(const TDesC& contentType, const TDesC8& url) +{ + TBool isSupported(EFalse); + + // Do we have a plugin that supports this content type + if (contentType.FindF(KMimeTypeAudio) != KErrNotFound || contentType.FindF(KMimeTypeVideo) != KErrNotFound + || findPlugin(contentType) != KErrNotFound || findPluginByExtension(url) != KErrNotFound) { + isSupported = ETrue; + } + // We don't have a plugin to support this content + return isSupported; +} + +// End of File