webengine/osswebengine/WebKit/s60/plugins/PluginHandler.cpp
changeset 0 dd21522fd290
child 8 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Plugin handling, manages the loading and unloading of the
       
    15 *                plugin. Initializes the CInfoArray that contains the plugin
       
    16 *                MIME-types supported.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include <e32std.h>
       
    23 #include <e32uid.h>
       
    24 #include <sysutil.h>
       
    25 #include "../../bidi.h"
       
    26 
       
    27 // System includes
       
    28 #include <ecom/ecom.h>
       
    29 
       
    30 
       
    31 //  INCLUDES
       
    32 #include "WebCorePluginHandler.h"
       
    33 #include "NPNImplementation.h"
       
    34 #include "PluginHandler.h"
       
    35 
       
    36 // CONSTANTS
       
    37 
       
    38 const TInt KPluginGranularity = 3;
       
    39 const TInt KMimeTypeLength = 7;
       
    40 
       
    41 _LIT( KMimeTypeAudio, "audio/" );
       
    42 _LIT( KMimeTypeVideo, "video/" );
       
    43 
       
    44 // LOCAL FUNCTION PROTOTYPES
       
    45 typedef NPError (*NPP_InitializeFunc)(NPNetscapeFuncs *netscapeFuncs,
       
    46                                       NPPluginFuncs *pluginFuncs);
       
    47 typedef void (*NPP_ShutdownFunc)(void);
       
    48 
       
    49 #define LOAD_PLUGINS  if(!m_pluginsLoaded) { TRAP_IGNORE(loadPluginsL()); m_pluginsLoaded = ETrue; }
       
    50 
       
    51 
       
    52 // ============================ MEMBER FUNCTIONS ===============================
       
    53 
       
    54 void panicHandler(TInt error = KErrNone)
       
    55 {
       
    56     User::Panic(_L("Object Handling Panic"), error);
       
    57 }
       
    58 
       
    59 
       
    60 // ============================ MEMBER FUNCTIONS ===============================
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // PluginInfo::PluginInfo
       
    64 // C++ default constructor can NOT contain any code, that might leave.
       
    65 // -----------------------------------------------------------------------------
       
    66 //
       
    67 PluginInfo::PluginInfo()
       
    68     : m_mimeTypes(KPluginGranularity),
       
    69       m_mimeFileExtensions(KPluginGranularity),
       
    70       m_mimeExtensionToTypeMap(KPluginGranularity),
       
    71       m_mimeDescriptions(KPluginGranularity),
       
    72       m_handle(-1)
       
    73 {
       
    74 }
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // PluginInfo::~PluginInfo
       
    78 //
       
    79 // Deconstructor.
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 PluginInfo::~PluginInfo()
       
    83 {
       
    84     m_mimeDescriptions.ResetAndDestroy();
       
    85     m_mimeDescriptions.Close();
       
    86 
       
    87     // Don't ResetAndDestroy() the m_mimeExtensionToTypeMap array, this array
       
    88     // contains pointers (memory) that is cleaned up in the m_mimeTypes array
       
    89     m_mimeExtensionToTypeMap.Close();
       
    90 
       
    91     m_mimeFileExtensions.ResetAndDestroy();
       
    92     m_mimeFileExtensions.Close();
       
    93 
       
    94     m_mimeTypes.ResetAndDestroy();
       
    95     m_mimeTypes.Close();
       
    96 
       
    97     delete m_name;
       
    98     delete m_description;
       
    99     delete m_nppFuncs;
       
   100     delete m_filename;
       
   101 
       
   102 }
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // PluginInfo::ShouldLoad
       
   106 //
       
   107 // Returns ETrue if the plugin should be loaded.
       
   108 // -----------------------------------------------------------------------------
       
   109 //
       
   110 TBool PluginInfo::shouldLoad()
       
   111 {
       
   112     return m_ref < 1;
       
   113 }
       
   114 
       
   115 // -----------------------------------------------------------------------------
       
   116 // PluginInfo::ShouldUnload
       
   117 //
       
   118 // Returns ETrue if the plugin should be unloaded.
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 TBool PluginInfo::shouldUnload()
       
   122 {
       
   123     return m_ref == 1;
       
   124 }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // PluginInfo::LoadInstance
       
   128 //
       
   129 // Increments the PluginInfo's reference count
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 void PluginInfo::loadInstance()
       
   133 {
       
   134     m_ref++;
       
   135 }
       
   136 
       
   137 // -----------------------------------------------------------------------------
       
   138 // PluginInfo::UnloadInstance
       
   139 //
       
   140 // Decrements the PluginInfo's reference count.
       
   141 // -----------------------------------------------------------------------------
       
   142 //
       
   143 void PluginInfo::unloadInstance()
       
   144 {
       
   145     m_ref--;
       
   146 }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // PluginInfo::CopyMimeDescription
       
   150 //
       
   151 // Copy the mimetypes and file extention from one plugin info struct to another,
       
   152 // Called after a rescan of the file system
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void PluginInfo::copyMimeDescription(PluginInfo& pluginInfo)
       
   156 {
       
   157     TUint   i;
       
   158     TUint   count;
       
   159     HBufC*  entry;
       
   160     
       
   161     m_mimeTypes.ResetAndDestroy();
       
   162     m_mimeExtensionToTypeMap.Reset();
       
   163     count = pluginInfo.m_mimeTypes.Count();
       
   164     for (i = 0; i < count; i++) {
       
   165         entry = pluginInfo.m_mimeTypes[0]->Des().Alloc();
       
   166         pluginInfo.m_mimeTypes.Remove(0);
       
   167         m_mimeTypes.Append(entry);
       
   168     }
       
   169 
       
   170     HBufC8*  extEntry;
       
   171     m_mimeFileExtensions.ResetAndDestroy();
       
   172     count = pluginInfo.m_mimeFileExtensions.Count();
       
   173     for (i = 0; i < count; i++) {
       
   174         extEntry = pluginInfo.m_mimeFileExtensions[0]->Des().Alloc();
       
   175         pluginInfo.m_mimeFileExtensions.Remove(0);
       
   176         m_mimeFileExtensions.Append(extEntry);
       
   177         m_mimeExtensionToTypeMap.Append(entry);
       
   178     }
       
   179 }
       
   180 
       
   181 // -----------------------------------------------------------------------------
       
   182 // PluginInfo::GetMimeExtensionsL
       
   183 //
       
   184 // Gets the supported mimeExtensions for the mimeType presented. Returns a HBufC*
       
   185 // that has allocated memory, which is the responsibility of the caller to
       
   186 // clean up. The HBufC* will be NULL if no supported mimeExtensions are supported.
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 HBufC8* PluginInfo::getMimeExtensionsL(const TDesC& mimeType)
       
   190 {    
       
   191     HBufC8* mimeTypeBuf = HBufC8::NewLC(128);
       
   192     TPtr8  mimeTypePtr(mimeTypeBuf->Des());
       
   193     //
       
   194     for (TInt i = 0; i < m_mimeExtensionToTypeMap.Count(); i++) {
       
   195 
       
   196         if (*(m_mimeExtensionToTypeMap[i]) == mimeType) {
       
   197             // We found a mimeType match, save the mimeExtension
       
   198             HBufC8* mimeExtensionBuf = m_mimeFileExtensions[i];
       
   199             // Make sure we can fit this mimeFileExtension
       
   200             TInt length = mimeExtensionBuf->Length();
       
   201             // +1 is for ','
       
   202             if (mimeTypePtr.Length() + length + 1 > mimeTypePtr.MaxLength()) {                    
       
   203                 HBufC8* tmp = HBufC8::NewL(mimeTypePtr.Length() + 2 * length);    
       
   204                 mimeTypePtr.Set(tmp->Des());
       
   205                 mimeTypePtr.Copy(*mimeTypeBuf);                
       
   206                 CleanupStack::PopAndDestroy(); // mimeTypeBuf
       
   207                 mimeTypeBuf = tmp;
       
   208                 CleanupStack::PushL(mimeTypeBuf);
       
   209             }                
       
   210             // append ',' unless this is the first item in the list
       
   211             if (mimeTypePtr.Length())
       
   212                 mimeTypePtr.Append(',');
       
   213     
       
   214             mimeTypePtr.Append(*mimeExtensionBuf);
       
   215         }
       
   216     }
       
   217 
       
   218     CleanupStack::Pop(); //mimeTypeBuf 
       
   219     return mimeTypeBuf;
       
   220 }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // PluginInfo::ParseDefaultDataL(const TDesC8& mimeDesc)
       
   224 //
       
   225 // Parses the default_data string from resource file to populate the mimeTypes, mimeExtensions,
       
   226 // and mimeDescriptions arrays.
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 void PluginInfo::parseDefaultDataL(const TDesC8& mimeDesc)
       
   230 {
       
   231     __ASSERT_DEBUG(mimeDesc.Ptr() != NULL, panicHandler());
       
   232 
       
   233     _LIT(KPattern1Ptr, ",;|");
       
   234     _LIT(KPattern2Ptr, ";|");
       
   235 
       
   236     TUint    end(mimeDesc.Length());
       
   237     TUint    i(0);
       
   238     TUint    marker(0);
       
   239     TUint16  mimeSeparator('|');
       
   240     TUint    fieldSeparator(';');
       
   241     HBufC*   newMimeTypeEntry = NULL;
       
   242     HBufC8*  newMimeFileExtEntry = NULL;
       
   243     HBufC*   newMimeDescriptionEntry = NULL;
       
   244 
       
   245     // Parse the mimeDesc string to populate the mimeTypes, mimeExtensions,
       
   246     // and mimeDescriptions arrays.
       
   247     
       
   248     for (; i < end;)  { // outer for loop
       
   249         // Search until end of buffer or match one of the delimiters ';' or '|'.
       
   250         // We are looking for the mimeType, ie "text/html", "application/pdf", etc.
       
   251         for (; (i < end) && (KPattern2Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) {
       
   252             // Walking the mimeDesc string
       
   253         }
       
   254 
       
   255         if (i > marker) {
       
   256             // Create new mimeType entry, the first entry is mimeType
       
   257             TPtrC8 mimeType8(mimeDesc.Mid(marker,i-marker));
       
   258             newMimeTypeEntry = HBufC::NewLC(i-marker);
       
   259             newMimeTypeEntry->Des().Copy(mimeType8);
       
   260             User::LeaveIfError(m_mimeTypes.Append(newMimeTypeEntry));
       
   261             CleanupStack::Pop(); //pop newMimeTypeEntry
       
   262         }
       
   263 
       
   264         // Are we at the end of the supported mime string
       
   265         if (i == end) {
       
   266             // This break with i=end means we leave outer for loop
       
   267             break;
       
   268         }
       
   269 
       
   270         marker = ++i;
       
   271         if ((mimeDesc)[i - 1] == mimeSeparator) {
       
   272             // Found a mime separator '|', get next supported mime
       
   273             continue;
       
   274         }
       
   275 
       
   276         // We are looking for the mimeFileExtensions, ie "html", "htm", "pdf", "txt", etc.
       
   277         // There can be multiple mimeFileExtentions per mimeType
       
   278         for (; (i < end);) { // inner for loop
       
   279             
       
   280             // Search until end of buffer or match one of the delimiters ';' or ',' or '|'.
       
   281             for (; (i < end) && (KPattern1Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) {
       
   282                 // Walking the mimeDesc string
       
   283             }
       
   284 
       
   285             if (i > marker) {
       
   286                 TPtrC8 mimeFileExt8(mimeDesc.Mid(marker,i-marker));
       
   287                 newMimeFileExtEntry = HBufC8::NewLC(i-marker);
       
   288                 newMimeFileExtEntry->Des().Copy(mimeFileExt8);
       
   289                 User::LeaveIfError(m_mimeFileExtensions.Append(newMimeFileExtEntry));
       
   290                 CleanupStack::Pop(); //pop newMimeFileExtEntry
       
   291 
       
   292                 // Add the mimeType to the mapping array. Every mimeFileExtension entry
       
   293                 // in m_mimeFileExtensions, has a corresponding mimeType entry in
       
   294                 // m_mimeExtensionToTypeMap.  This allows us to provide a list of
       
   295                 // extensions for each supported mimeType.
       
   296                 User::LeaveIfError(m_mimeExtensionToTypeMap.Append(newMimeTypeEntry));
       
   297             }
       
   298 
       
   299             // Are we at the end of the supported mime string
       
   300             if (i == end) {
       
   301                 // This break means we leave the inner loop, and with i=end means
       
   302                 // we leave the outer loop
       
   303                 break;
       
   304             }
       
   305 
       
   306             marker = ++i;
       
   307             if ((mimeDesc)[i - 1] == mimeSeparator) {
       
   308                 // Found a mime separator '|', get next supported mime
       
   309                 break;
       
   310             }
       
   311 
       
   312             if ((mimeDesc)[i - 1] == fieldSeparator) {
       
   313             
       
   314                 // Found a field separator ';', get the mimeDescription.
       
   315                 // Search until end of buffer or match one of the delimiters ';' or '|'.
       
   316                 for (; (i < end) && (KPattern2Ptr().Locate((mimeDesc)[i]) == KErrNotFound); i++) {
       
   317                     // Walking the mimeDesc string
       
   318                 }
       
   319 
       
   320                 if (i > marker) {
       
   321                     // Create new mimeDescription entry
       
   322                     TPtrC8 mimeDesc8(mimeDesc.Mid(marker,i-marker));
       
   323                     newMimeDescriptionEntry = HBufC::NewLC(i-marker);
       
   324                     newMimeDescriptionEntry->Des().Copy(mimeDesc8);
       
   325 
       
   326                     User::LeaveIfError(m_mimeDescriptions.Append(newMimeDescriptionEntry));
       
   327                     CleanupStack::Pop();  //pop newMimeDescriptionEntry
       
   328                 }
       
   329 
       
   330                 // Are we at the end of the supported mime string
       
   331                 if (i == end) {
       
   332                     // This break means we leave the inner loop, and with i=end means
       
   333                     // we leave the outer loop
       
   334                     break;
       
   335                 }
       
   336 
       
   337                 marker = ++i;
       
   338                 // Make sure we start at the next mime, after we found the mimeDescription.
       
   339                 // We are handling a mime string with an extra semi-colon(s),
       
   340                 // ie "...mimeDescription1;|mimeType2
       
   341                 for (; (i < end) && ((mimeDesc)[i-1] != mimeSeparator); i++) {
       
   342                     // Walking the mimeDesc string
       
   343                 }
       
   344 
       
   345                 // Leave the inner loop and look for the next mime
       
   346                 break;
       
   347             
       
   348             }   // end of if fieldSeparator aka get mimeDescription
       
   349 
       
   350             // If we get here, we have another mimeFileExtension.  Continue on the
       
   351             // inner loop to find additional mimeFileExtensions.
       
   352 
       
   353         }   // end of inner for (;i<end;)
       
   354     }   // end of outer for (;i<end;)
       
   355 }
       
   356 
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // PluginInfo::ParseDisplayNameL(const TDesC& nameDesc)
       
   360 //
       
   361 // Parses the display_name string from resource file to populate the file name and plugin name
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 void PluginInfo::parseDisplayNameL(const TDesC& nameDesc)
       
   365 {
       
   366     __ASSERT_DEBUG(nameDesc.Ptr() != NULL, panicHandler());
       
   367 
       
   368     _LIT16(KSeparator, ";");
       
   369 
       
   370     TUint    end(nameDesc.Length());
       
   371     TInt     offset;
       
   372     TPtrC fileNamePtr;
       
   373     TPtrC namePtr;
       
   374 
       
   375     offset = nameDesc.Find(KSeparator);
       
   376     if (offset != KErrNotFound) {
       
   377         if (offset) {
       
   378             fileNamePtr.Set(nameDesc.Left(offset));
       
   379             namePtr.Set(nameDesc.Right(end - offset - 1));
       
   380             m_filename = fileNamePtr.AllocL();
       
   381             m_name = namePtr.AllocL();
       
   382         }
       
   383     }
       
   384 
       
   385 }
       
   386 
       
   387 // ============================ MEMBER FUNCTIONS ===============================
       
   388 
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // PluginHandler::PluginHandler
       
   392 //
       
   393 // C++ default constructor can NOT contain any code, that
       
   394 // might leave.
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 PluginHandler::PluginHandler(TBool enablePlugins)
       
   398     : m_pluginInfoArray( KPluginGranularity )
       
   399       ,m_enablePlugins(enablePlugins)
       
   400       ,m_asyncLoading(ETrue)
       
   401 {
       
   402 }
       
   403 
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // PluginHandler::ConstructL
       
   407 //
       
   408 // Symbian 2nd phase constructor can leave.
       
   409 // -----------------------------------------------------------------------------
       
   410 //
       
   411 void PluginHandler::ConstructL()
       
   412 {
       
   413     m_idle = CIdle::NewL(CActive::EPriorityLow);
       
   414     m_idle->Start(TCallBack(initialize, this));
       
   415 }
       
   416 
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // PluginHandler::NewL
       
   420 //
       
   421 // Two-phased constructor.
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 PluginHandler* PluginHandler::NewL(TBool enablePlugins)
       
   425 {
       
   426     PluginHandler* self = new(ELeave) PluginHandler(enablePlugins);
       
   427     CleanupStack::PushL(self);
       
   428     self->ConstructL();
       
   429     CleanupStack::Pop();
       
   430     return self;
       
   431 }
       
   432 
       
   433 // -----------------------------------------------------------------------------
       
   434 // PluginHandler::~PluginHandler
       
   435 //
       
   436 // Deconstructor.
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 PluginHandler::~PluginHandler()
       
   440 {
       
   441     m_pluginInfoArray.ResetAndDestroy();
       
   442     m_pluginInfoArray.Close();
       
   443     if (m_idle) {
       
   444        m_idle->Cancel();
       
   445     }
       
   446     delete m_idle;
       
   447 }
       
   448 
       
   449 // -----------------------------------------------------------------------------
       
   450 // PluginHandler::Initialize
       
   451 //
       
   452 // Initializes the PluginHandler, possibly asynchronously
       
   453 // -----------------------------------------------------------------------------
       
   454 //
       
   455 TBool PluginHandler::initialize(TAny* pluginHandler)
       
   456 {
       
   457     TBool doneInit(EFalse);
       
   458 
       
   459     PluginHandler* handler = (PluginHandler*)pluginHandler;
       
   460 
       
   461     TRAPD(err, doneInit = handler->loadPluginsL());
       
   462     if (err) {
       
   463         // If we leave from LoadPluginsL, stop CIdle
       
   464         doneInit = EFalse;
       
   465     }
       
   466 
       
   467     return doneInit;
       
   468 }
       
   469 
       
   470 //------------------------------------------------------------------------------
       
   471 // PluginHandler::loadPluginsL
       
   472 //
       
   473 // Loads all the plugins and query them for details.
       
   474 // -----------------------------------------------------------------------------
       
   475 //
       
   476 TBool PluginHandler::loadPluginsL()
       
   477 {
       
   478     
       
   479     if(m_pluginsLoaded) {
       
   480         return EFalse;
       
   481     }
       
   482         
       
   483     // 1) fetch CImplementationInformation instances from the ECOM infrastructure
       
   484     // 2) create plugin info for each plugin
       
   485 
       
   486     // Create the ECom info array, contains the plugin information
       
   487     RImplInfoPtrArray ecomPluginInfoArray;
       
   488 
       
   489     // Get list of ECOM plugins that match the KNBrowserPluginInterfaceUid
       
   490     REComSession::ListImplementationsL(KBrowserPluginInterfaceUid, ecomPluginInfoArray);
       
   491 
       
   492     // Loop through all the Netscape plugins found by ECom and populate the
       
   493     // m_pluginInfoArray
       
   494     m_nextHandle = 0;
       
   495     const TInt pluginCount = ecomPluginInfoArray.Count();
       
   496     for (TInt index=0; index<pluginCount; ++index) {
       
   497         PluginInfo* pluginInfo = new(ELeave) PluginInfo;
       
   498         pluginInfo->m_handle = m_nextHandle++;
       
   499         CleanupStack::PushL(pluginInfo);
       
   500 
       
   501         // Set the plugin properties
       
   502         pluginInfo->m_pluginInfo = ecomPluginInfoArray[index];
       
   503         // Read the plugin's name and plugin FileName (display_name) from the IMPLEMENTATION_INFO
       
   504         pluginInfo->parseDisplayNameL(pluginInfo->m_pluginInfo->DisplayName());
       
   505         pluginInfo->m_description = HBufC::NewL(pluginInfo->m_pluginInfo->OpaqueData().Length());
       
   506         pluginInfo->m_description->Des().Copy(pluginInfo->m_pluginInfo->OpaqueData());
       
   507         pluginInfo->m_uid = pluginInfo->m_pluginInfo->ImplementationUid();
       
   508         // Parses the mimeDesc string to populate the mimeTypes, mimeExtensions,
       
   509         // and mimeDescriptions arrays.
       
   510         pluginInfo->parseDefaultDataL(pluginInfo->m_pluginInfo->DataType());
       
   511 
       
   512         // Add the filter information to the list
       
   513         User::LeaveIfError(m_pluginInfoArray.Append(pluginInfo));
       
   514         CleanupStack::Pop();    // pluginInfo
       
   515     }
       
   516 
       
   517     // Clean up the ECom info array
       
   518     ecomPluginInfoArray.ResetAndDestroy();
       
   519     ecomPluginInfoArray.Close();
       
   520     
       
   521     m_pluginsLoaded = ETrue;
       
   522     return EFalse;
       
   523 }
       
   524 
       
   525 // -----------------------------------------------------------------------------
       
   526 // PluginHandler::findPlugin
       
   527 //
       
   528 // Find a plugin by MIME type.
       
   529 // -----------------------------------------------------------------------------
       
   530 //
       
   531 TInt PluginHandler::findPlugin(const TDesC& mimeType) 
       
   532 {    
       
   533     LOAD_PLUGINS
       
   534     
       
   535 	HBufC*   newMimeType = NULL;
       
   536 	_LIT(KSeparator, "*");
       
   537 	TInt  pluginIndex;
       
   538     TInt  mimeIndex;
       
   539 
       
   540 	if (mimeType.FindF(KMimeTypeAudio) != KErrNotFound){
       
   541 		newMimeType = HBufC::NewLC(KMimeTypeLength);
       
   542         newMimeType->Des().Copy(KMimeTypeAudio);
       
   543 		newMimeType->Des().Append(KSeparator);
       
   544 	}
       
   545 	else if (mimeType.FindF(KMimeTypeVideo) != KErrNotFound){
       
   546 		newMimeType = HBufC::NewLC(KMimeTypeLength);
       
   547         newMimeType->Des().Copy(KMimeTypeVideo);
       
   548 		newMimeType->Des().Append(KSeparator);
       
   549 	}
       
   550 	else{
       
   551 		newMimeType = HBufC::NewLC(mimeType.Length());
       
   552         newMimeType = mimeType.AllocL();
       
   553 	}
       
   554 	CleanupStack::Pop(); //pop newMimeType
       
   555 	
       
   556     for (pluginIndex = 0; pluginIndex < m_pluginInfoArray.Count(); pluginIndex++) {
       
   557         for (mimeIndex = 0;
       
   558              mimeIndex < m_pluginInfoArray[pluginIndex]->m_mimeTypes.Count();
       
   559              mimeIndex++) {
       
   560             if (!m_pluginInfoArray[pluginIndex]->m_mimeTypes[mimeIndex]->CompareF(*newMimeType)) {
       
   561                 delete newMimeType;
       
   562 				return m_pluginInfoArray[pluginIndex]->m_handle;
       
   563             }
       
   564         }
       
   565     }
       
   566 	delete newMimeType;
       
   567     return KErrNotFound;
       
   568 }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // PluginHandler::findPluginByExtension
       
   572 //
       
   573 // Find a plugin by file extension.
       
   574 // -----------------------------------------------------------------------------
       
   575 //
       
   576 TInt PluginHandler::findPluginByExtension(const TDesC8& url)
       
   577 {
       
   578     LOAD_PLUGINS
       
   579     
       
   580     TInt  pluginIndex;
       
   581     TInt  extIndex;
       
   582 
       
   583     TPtrC8 extPtr(url.Mid(url.LocateReverse('.') + 1));
       
   584     for (pluginIndex = 0; pluginIndex < m_pluginInfoArray.Count(); pluginIndex++) {
       
   585         
       
   586         for (extIndex = 0; 
       
   587             extIndex < m_pluginInfoArray[pluginIndex]->
       
   588             m_mimeFileExtensions.Count(); extIndex++) {
       
   589             
       
   590             if (!m_pluginInfoArray[pluginIndex]->m_mimeFileExtensions[extIndex]->CompareF(extPtr)) {
       
   591                 return m_pluginInfoArray[pluginIndex]->m_handle;
       
   592             }                
       
   593         }
       
   594     }
       
   595 
       
   596     return KErrNotFound;
       
   597 }
       
   598 
       
   599 
       
   600 // -----------------------------------------------------------------------------
       
   601 // PluginHandler::loadPluginL
       
   602 //
       
   603 // Load a plugin if not yet loaded and return its function table. The handle was
       
   604 // gotten from the methods FindPlugin and FindPluginFromExtension, so the
       
   605 // handle should be valid.
       
   606 // -----------------------------------------------------------------------------
       
   607 //
       
   608 void PluginHandler::loadPluginL(TInt handle, NPPluginFuncs** retPluginFuncs)
       
   609 {
       
   610     LOAD_PLUGINS
       
   611     
       
   612     TUint index(getIndexFromHandle(handle));
       
   613     __ASSERT_DEBUG(index < (TUint)m_pluginInfoArray.Count(), panicHandler());
       
   614 
       
   615     PluginInfo* plugin = m_pluginInfoArray[index];
       
   616 
       
   617     if (plugin->shouldLoad()) {
       
   618     
       
   619         NPPluginFuncs* pluginFuncs = (NPPluginFuncs*) User::AllocLC(sizeof (NPPluginFuncs));
       
   620         Mem::FillZ((void*) pluginFuncs, sizeof (NPPluginFuncs));
       
   621         // create CEcomBrowserPluginInterface, given the UID from the PLuginInfo, when ref count == 0
       
   622         plugin->m_pluginInterface = CEcomBrowserPluginInterface::CreatePluginL(plugin->m_uid,
       
   623           (NPNetscapeFuncs *) (&NpnImplementationFuncs), pluginFuncs);
       
   624 
       
   625         CleanupStack::Pop(pluginFuncs);
       
   626         plugin->m_nppFuncs = pluginFuncs;
       
   627         pluginFuncs = NULL;
       
   628     }
       
   629     
       
   630     plugin->loadInstance();
       
   631     __ASSERT_DEBUG(plugin->m_nppFuncs != NULL, panicHandler());
       
   632     *retPluginFuncs = plugin->m_nppFuncs;
       
   633 
       
   634 }
       
   635 
       
   636 
       
   637 // -----------------------------------------------------------------------------
       
   638 // PluginHandler::UnloadPlugin
       
   639 //
       
   640 // Unload a plugin. If this is the last instance, the library is unloaded.
       
   641 // The handle was gotten from the methods FindPlugin and FindPluginFromExtension,
       
   642 // so the handle should be valid.
       
   643 // -----------------------------------------------------------------------------
       
   644 //
       
   645 void PluginHandler::unloadPlugin(TInt handle)
       
   646 {
       
   647     TUint index(getIndexFromHandle(handle));
       
   648     __ASSERT_DEBUG(index < (TUint) m_pluginInfoArray.Count(), panicHandler());
       
   649 
       
   650     PluginInfo* plugin = m_pluginInfoArray[index];
       
   651 
       
   652     if (plugin->shouldUnload()) {
       
   653         User::Free(plugin->m_nppFuncs);
       
   654         plugin->m_nppFuncs = NULL;
       
   655         // delete the CEcomBrowserPluginInterface instance when ref count  == 0
       
   656         delete plugin->m_pluginInterface;
       
   657     }
       
   658 
       
   659     plugin->unloadInstance();
       
   660 }
       
   661 
       
   662 // -----------------------------------------------------------------------------
       
   663 // PluginHandler::GetIndexFromHandle
       
   664 //
       
   665 // Get the index of plugin info from its handle. This method should always
       
   666 // return a valid handle, since the calling program got the handle from the
       
   667 // methods FindPlugin and FindPluginFromExtension.
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 TUint PluginHandler::getIndexFromHandle(TInt handle)
       
   671 {
       
   672     LOAD_PLUGINS
       
   673     TUint  index;
       
   674     TUint  count(m_pluginInfoArray.Count());
       
   675 
       
   676     __ASSERT_DEBUG(handle >= 0, panicHandler());
       
   677 
       
   678     for (index = 0; index < count; index++) {
       
   679         if (m_pluginInfoArray[index]->m_handle == handle) {
       
   680             return index;
       
   681         }
       
   682     }
       
   683 
       
   684     // We should never get here. We should always return a valid handle. Return
       
   685     // the count (handle + 1), this should assert debug in calling methods, as
       
   686     // well as the forced assert debug .
       
   687     __ASSERT_DEBUG(EFalse, panicHandler());
       
   688     return count;
       
   689 }
       
   690 
       
   691 // -----------------------------------------------------------------------------
       
   692 // PluginHandler::GetPluginCount
       
   693 //
       
   694 // Returns the number of plugins supported by the platform
       
   695 // -----------------------------------------------------------------------------
       
   696 TInt PluginHandler::getPluginCount()
       
   697 {
       
   698     LOAD_PLUGINS
       
   699     return m_pluginInfoArray.Count();
       
   700 }
       
   701     
       
   702 TBool PluginHandler::pluginSupportsMIMEType(const TDesC& mimeType)
       
   703 {
       
   704     return findPlugin(mimeType) != KErrNotFound;
       
   705 }
       
   706 
       
   707 TBool PluginHandler::objectAtIndex(TInt index, TWebCorePluginInfo& pluginInfo )
       
   708 {
       
   709     if (index<0 || index>m_pluginInfoArray.Count()-1)
       
   710         return EFalse;
       
   711 
       
   712     PluginInfo* pinfo = m_pluginInfoArray[index];
       
   713     if (!pinfo)
       
   714         return EFalse;
       
   715 
       
   716     pluginInfo.iName.Set(KNullDesC());
       
   717     pluginInfo.iFilename.Set(KNullDesC());
       
   718     pluginInfo.iPluginDescription.Set(KNullDesC());
       
   719     //
       
   720     if (pinfo->name())        
       
   721         pluginInfo.iName.Set(*(pinfo->name()));
       
   722     if (pinfo->fileName())
       
   723         pluginInfo.iFilename.Set(*(pinfo->fileName()));
       
   724     if (pinfo->description())
       
   725         pluginInfo.iPluginDescription.Set(*(pinfo->description()));
       
   726 
       
   727     pluginInfo.iMimeTypeArray = pinfo->mimeTypes();
       
   728 
       
   729     return ETrue;        
       
   730 }
       
   731 
       
   732 void PluginHandler::refreshPlugins(TBool reload)
       
   733 {
       
   734     TRAP_IGNORE(reloadPluginsL(reload));
       
   735 }
       
   736 
       
   737 HBufC8* PluginHandler::extensionsForMIMEType(TInt index, TDesC& mimeType )
       
   738 {
       
   739     PluginInfo *pluginInfo = m_pluginInfoArray[index];
       
   740     HBufC8 *extn = NULL;
       
   741     TRAP_IGNORE(extn = pluginInfo->getMimeExtensionsL(mimeType));
       
   742     return extn;
       
   743 }
       
   744 
       
   745 HBufC* PluginHandler::descriptionForMIMEType(TInt index, TDesC& mimeType )
       
   746 {
       
   747     // there is no way to tell mimeType-description pairs. return the whole string    
       
   748     PluginInfo *pluginInfo = m_pluginInfoArray[index];
       
   749     RPointerArray<HBufC> items = pluginInfo->mimeDescriptions();
       
   750     HBufC* descBuf = HBufC::New(128);
       
   751     if (!descBuf)
       
   752         return descBuf;
       
   753         
       
   754     TPtr descPtr(descBuf->Des());
       
   755     for (TInt i=0; i<items.Count(); i++ ) {
       
   756         
       
   757         // Make sure we can fit this mimeFileExtension
       
   758         HBufC* desc = items[i];
       
   759         TInt length = desc->Length();
       
   760 		// +1 is for ','
       
   761         if (descPtr.Length() + length + 1 > descPtr.MaxLength()) {                    
       
   762             HBufC* tmp = HBufC::New(descPtr.Length() + 2 * length);    
       
   763             if (!tmp) {
       
   764                 // return whatever we have    
       
   765                 return descBuf;
       
   766             }
       
   767             descPtr.Set(tmp->Des());
       
   768             descPtr.Copy(*descBuf);                
       
   769             descBuf = tmp;
       
   770         }                
       
   771         // append ',' unless this is the first item in the list
       
   772         if (descPtr.Length())
       
   773             descPtr.Append(',');
       
   774         descPtr.Append(*desc);
       
   775     }
       
   776     
       
   777     return descBuf;
       
   778 }
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // PluginHandler::ReloadPluginsL
       
   782 //
       
   783 // Rescan for new plugins.
       
   784 // -----------------------------------------------------------------------------
       
   785 //
       
   786 void PluginHandler::reloadPluginsL(TBool reload)
       
   787 {
       
   788     // This function stores the plugins that are currently loaded in a temp array
       
   789     // Then it rescans the drives for all plugins
       
   790     // Currently loaded plugins must exist in the new list because the dll is loaded
       
   791     // and the plugin could not be deleted from the file system while the dll is loaded.
       
   792     // After rescanning, each plugin from the temp array is matched with a plugin
       
   793     // in the new array. The matching is done by file name.
       
   794     // Each new entry is replaced with the existing entry from the temp array.
       
   795     // This is done because the CPluginInst object keeps the handle and
       
   796     // the function table of the existing plugin.
       
   797 
       
   798     RPointerArray<PluginInfo>  tmpPluginInfoArray;
       
   799     PluginInfo*                 pluginInfo = NULL;
       
   800     TInt                        count(m_pluginInfoArray.Count());
       
   801     TInt                        index;
       
   802 
       
   803     // Copy all the loaded plugins to a temp array
       
   804     for (index = 0; index < count; index++) {
       
   805         pluginInfo = m_pluginInfoArray[0];
       
   806         if (pluginInfo->shouldLoad()) { // Is it currently loaded?
       
   807             m_pluginInfoArray.Remove(0);
       
   808             delete pluginInfo;
       
   809             pluginInfo = NULL;
       
   810         }
       
   811         else {
       
   812             m_pluginInfoArray.Remove(0);
       
   813             tmpPluginInfoArray.Append(pluginInfo);
       
   814         }
       
   815     }
       
   816         
       
   817     // reload the plugins by scanning the drives
       
   818     if (m_idle) {
       
   819         m_idle->Cancel();
       
   820     }
       
   821 
       
   822     //Load the plugins synchronously
       
   823     m_asyncLoading = EFalse;
       
   824     m_pluginsLoaded =EFalse;
       
   825     loadPluginsL();
       
   826     count = m_pluginInfoArray.Count();
       
   827 
       
   828     TInt tmpCount(tmpPluginInfoArray.Count());
       
   829     TInt i;
       
   830     PluginInfo* delPluginInfo = NULL;
       
   831     for (index = 0; index < tmpCount; index++) {
       
   832         pluginInfo = tmpPluginInfoArray[0];
       
   833         tmpPluginInfoArray.Remove(0);
       
   834         // Search through the array for a filename match
       
   835         // use ECOM Uid rather then file names
       
   836         for (i = 0; i < count && (pluginInfo->m_uid != m_pluginInfoArray[i]->m_uid); i++) {
       
   837         }
       
   838 
       
   839         if (i == count) {
       
   840             i = -1;
       
   841         }
       
   842         
       
   843         if (i >= 0) {
       
   844             // i < 0 only if rescanning failed
       
   845             delPluginInfo = m_pluginInfoArray[i];
       
   846             m_pluginInfoArray.Remove(i);
       
   847             // Save the new Mimetype and extensions. They might be different than before
       
   848             pluginInfo->copyMimeDescription(*delPluginInfo);
       
   849 
       
   850             delete (delPluginInfo);
       
   851             delPluginInfo = NULL;
       
   852         }
       
   853     
       
   854         m_pluginInfoArray.Append(pluginInfo);    
       
   855     }
       
   856 
       
   857     tmpPluginInfoArray.Close();
       
   858     if (reload) {
       
   859         //m_view.mainFrame().WebKitBridge().reload();
       
   860     }
       
   861 
       
   862 }
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // PluginHandler::IsSupported
       
   866 //
       
   867 // Determines whether a given content-type of dot-extension has a cooresponding
       
   868 // plugin or external application.  aContentType and aUrl can be NULL, but at least
       
   869 // one must be non-NULL (otherwise it will always return EFalse).  If handlerType
       
   870 // is EPlugin then it returns ETrue only if their is a supported plugin.  If handlerType
       
   871 // is EExternalApp then it returns ETrue only if their is a supported external
       
   872 // application.  If handlerType is EBoth then it returns ETrue only if their is a
       
   873 // supported plugin or external application.
       
   874 // -----------------------------------------------------------------------------
       
   875 TBool PluginHandler::isSupported(const TDesC& contentType, const TDesC8& url)
       
   876 {
       
   877     TBool isSupported(EFalse);
       
   878 
       
   879     // Do we have a plugin that supports this content type
       
   880 	if (contentType.FindF(KMimeTypeAudio) != KErrNotFound || contentType.FindF(KMimeTypeVideo) != KErrNotFound 
       
   881 			|| findPlugin(contentType) != KErrNotFound || findPluginByExtension(url) != KErrNotFound) {
       
   882 		isSupported = ETrue;
       
   883 	}
       
   884     // We don't have a plugin to support this content
       
   885     return isSupported;
       
   886 }
       
   887 
       
   888 //  End of File