--- /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 <e32std.h>
+#include <e32uid.h>
+#include <sysutil.h>
+#include "../../bidi.h"
+
+// System includes
+#include <ecom/ecom.h>
+
+
+// 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 (;i<end;)
+ } // end of outer for (;i<end;)
+}
+
+
+// -----------------------------------------------------------------------------
+// PluginInfo::ParseDisplayNameL(const TDesC& nameDesc)
+//
+// Parses the display_name string from resource file to populate the file name and plugin name
+// -----------------------------------------------------------------------------
+//
+void PluginInfo::parseDisplayNameL(const TDesC& nameDesc)
+{
+ __ASSERT_DEBUG(nameDesc.Ptr() != NULL, panicHandler());
+
+ _LIT16(KSeparator, ";");
+
+ TUint end(nameDesc.Length());
+ TInt offset;
+ TPtrC fileNamePtr;
+ TPtrC namePtr;
+
+ offset = nameDesc.Find(KSeparator);
+ if (offset != KErrNotFound) {
+ if (offset) {
+ fileNamePtr.Set(nameDesc.Left(offset));
+ namePtr.Set(nameDesc.Right(end - offset - 1));
+ m_filename = fileNamePtr.AllocL();
+ m_name = namePtr.AllocL();
+ }
+ }
+
+}
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// PluginHandler::PluginHandler
+//
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+PluginHandler::PluginHandler(TBool enablePlugins)
+ : m_pluginInfoArray( KPluginGranularity )
+ ,m_enablePlugins(enablePlugins)
+ ,m_asyncLoading(ETrue)
+{
+}
+
+
+// -----------------------------------------------------------------------------
+// PluginHandler::ConstructL
+//
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void PluginHandler::ConstructL()
+{
+ m_idle = CIdle::NewL(CActive::EPriorityLow);
+ m_idle->Start(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; index<pluginCount; ++index) {
+ PluginInfo* pluginInfo = new(ELeave) PluginInfo;
+ pluginInfo->m_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<HBufC> items = pluginInfo->mimeDescriptions();
+ HBufC* descBuf = HBufC::New(128);
+ if (!descBuf)
+ return descBuf;
+
+ TPtr descPtr(descBuf->Des());
+ for (TInt i=0; i<items.Count(); i++ ) {
+
+ // Make sure we can fit this mimeFileExtension
+ HBufC* desc = items[i];
+ TInt length = desc->Length();
+ // +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<PluginInfo> 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