installationservices/swi/source/sislauncher/server/sislaunchersession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:21:33 +0300
branchRCL_3
changeset 25 7333d7932ef7
parent 0 ba25891c3a9e
child 26 8b7f4e561641
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2004-2010 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: 
* SisLauncher - session implementation
*
*/


/**
 @file 
 @released
 @internalComponent
*/

#include <s32mem.h>

#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
#include <ct/rcpointerarray.h>
#include "swtypereginfoparser.h"
#ifndef SWI_TEXTSHELL_ROM
#include <apgcli.h>
#endif
#endif

#include "sislauncherserver.h"
#include "sislaunchersession.h"
#include "sislauncherclientserver.h"
#include "threadmonitor.h"
#include "securitypolicy.h"
#include "sisregistryfiledescription.h"
#include "sislauncherdefs.h"
#include "arrayutils.h"  // from source/sisregistry/common/ 
#include "log.h"
#include "queueprocessor.h"
#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
#include "apprscparser.h"
#include "ipcutil.h"
#include <usif/scr/appregentries.h>
#include <usif/scr/screntries_platform.h>
#include "sislauncherclient.h" 
#endif

namespace Swi 
{

template <class T>
void DestroyRPointerArray(TAny* aPtr)
    {
    RPointerArray<T>* self = static_cast<RPointerArray<T>*> (aPtr);
    self->ResetAndDestroy();
    delete self;
    }

template <>
class TTraits<TDesC>
    {
public:
    static TDesC* CopyLC(const TDesC& aOther) { return aOther.AllocLC(); }
    static TDesC* ReadFromStreamLC(RReadStream& aStream) { return HBufC::NewLC(aStream, KMaxTInt); }
    static void WriteToStreamL(const TDesC& aItem, RWriteStream& aStream) { aStream << aItem; }
    };

CSisLauncherSession::CSisLauncherSession()
    {
    }

void CSisLauncherSession::CreateL()
    {
    Server().AddSession();
    }

CSisLauncherSession::~CSisLauncherSession()
    {
    #ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
    delete iCurrentAppRegData;
    #endif
    Server().DropSession();
    }
void CSisLauncherSession::DoRunExecutableL(const RMessage2& aMessage) 
    {
    TFileName filename;
    aMessage.ReadL(0, filename);

    TBool wait;
    TPckg <TBool> waitPckg(wait);

    aMessage.ReadL(1, waitPckg);
    Server().RunExecutableL(filename, wait);

    aMessage.Complete(KErrNone);
    }

void CSisLauncherSession::DoStartDocumentL(const RMessage2& aMessage)
    {
    TFileName filename;
    aMessage.ReadL(0, filename);
    
    TBool wait;
    TPckg <TBool> waitPckg(wait);
    
    aMessage.ReadL(1, waitPckg);
    if (Server().BootUpMode() == KTextShell) 
        {
        // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
        DEBUG_PRINTF2(_L8("Sis Launcher Server - textshell - skipping start document by file handle. wait = %d"), wait);    
        }
    else
        { 
        // emulatore running with GUI
        #ifndef SWI_TEXTSHELL_ROM
            Server().StartDocumentL(filename, wait);
        #endif
        }

    aMessage.Complete(KErrNone);    
    }


void CSisLauncherSession::DoStartDocumentByHandleL(const RMessage2& aMessage)
    {
    RFile file;
    file.AdoptFromClient(aMessage, 0, 1);
    CleanupClosePushL(file);

    TBool wait;
    TPckg <TBool> waitPckg(wait);

    aMessage.ReadL(2, waitPckg);
    if (Server().BootUpMode() == KTextShell)
        {
        // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
        DEBUG_PRINTF3(_L8("Sis Launcher Server - textshell - skipping start document %S, wait = %d"),
                &file, wait);
        }
    else
        {
        // emulatore running with GUI
#ifndef SWI_TEXTSHELL_ROM
        Server().StartDocumentL(file, wait);
#endif
        }
    CleanupStack::PopAndDestroy(&file);
    aMessage.Complete(KErrNone);
}
void CSisLauncherSession::DoStartByMimeL(const RMessage2& aMessage)
    {
    TFileName filename;
    aMessage.ReadL(0, filename);

    TInt srcLen = aMessage.GetDesLengthL(1);

    HBufC8* mimeType = HBufC8::NewLC(srcLen);
    TPtr8 ptr(mimeType->Des());
    aMessage.ReadL(1, ptr);

    TBool wait;
    TPckg <TBool> waitPckg(wait);
    aMessage.ReadL(2, waitPckg);
    if (Server().BootUpMode() == KTextShell) 
        {
        // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
        DEBUG_PRINTF3(_L8("Sis Launcher Server - textshell - skipping start document by file handle mimetype %S, wait = %d"),
                mimeType, wait);    
        }
    else
        {
        // emulatore running with GUI
#ifndef SWI_TEXTSHELL_ROM
        Server().StartByMimeL(filename, *mimeType, wait);
#endif
        }       
    CleanupStack::PopAndDestroy(mimeType);

    aMessage.Complete(KErrNone);
    }
void CSisLauncherSession::DoStartByMimeByHandleL(const RMessage2& aMessage)
    {
    RFile file;
    file.AdoptFromClient(aMessage, 0, 1);           
    CleanupClosePushL(file);

    TInt srcLen = aMessage.GetDesLengthL(2);

    HBufC8* mimeType = HBufC8::NewLC(srcLen);
    TPtr8 ptr(mimeType->Des());
    aMessage.ReadL(2, ptr);

    TBool wait;
    TPckg <TBool> waitPckg(wait);

    aMessage.ReadL(3, waitPckg);
    if (Server().BootUpMode() == KTextShell) 
        {
        // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
        DEBUG_PRINTF4(_L("Sis Launcher Server - textshell - skipping launch of document %S, mimetype %s, wait %d"),
                &file, mimeType, wait);
        }
    else
        {
        // emulatore running with GUI
#ifndef SWI_TEXTSHELL_ROM
        Server().StartByMimeL(file, *mimeType, wait);
#endif
        }       
    CleanupStack::PopAndDestroy(mimeType);
    CleanupStack::PopAndDestroy(&file);

    aMessage.Complete(KErrNone);

    }
void CSisLauncherSession::ServiceL(const RMessage2& aMessage)
    {
    DEBUG_PRINTF2(_L8("Sis Launcher Server - Servicing Message %d"), aMessage.Function());
    
    switch (aMessage.Function())
        {
        case ERunExecutable:
            DoRunExecutableL(aMessage);
            break;
        case EStartDocument:
            DoStartDocumentL(aMessage);         
            break;
        case EStartDocumentByHandle:
            DoStartDocumentByHandleL(aMessage);
            break;  
        case EStartByMime:
            DoStartByMimeL(aMessage);
            break;
        case EStartByMimeByHandle:
            DoStartByMimeByHandleL(aMessage);
            break;
        case EShutdown:
            {
            TInt srcLen=aMessage.GetDesLengthL(0);
            
            HBufC8* uidBuffer = HBufC8::NewLC(srcLen);
            TPtr8 uidPtr = uidBuffer->Des();
            aMessage.ReadL(0, uidPtr, 0);
            
            TUint8* dataPtr=const_cast<TUint8*>(uidPtr.Ptr());
            TUid* tUidPtr=reinterpret_cast<TUid*>(dataPtr);
            TInt8 uidCount=srcLen/sizeof(TUid);
            TInt shutdownTimeout = aMessage.Int1();
            if (Server().BootUpMode() == KTextShell) 
                {
                // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
                DEBUG_PRINTF(_L8("Sis Launcher Server - textshell - skipping graceful shutdown of GUI applications"));
                }
            else
                {
                // emulatore running with GUI
                #ifndef SWI_TEXTSHELL_ROM
                    for (TInt i = 0; i < uidCount; i++)
                        {
                        // graceful shutdown
                        Server().ShutdownL(tUidPtr[i], shutdownTimeout);    
                        }
                #endif
                }
            // Having tried graceful shutdown, we need to kill any remaining processes
            // matching the SID.  Note that killing a process may re-order the list of
            // remaining processes, so the search must start from the top again.
            for (TInt i = 0; i < uidCount; i++)
                {
                Server().ForceShutdownL(tUidPtr[i]);
                }           
            CleanupStack::PopAndDestroy(uidBuffer);
            aMessage.Complete(KErrNone);
            
            break;
            }
        case EShutdownAll:
            {
            if (Server().BootUpMode() == KTextShell) 
                {
                // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
                DEBUG_PRINTF(_L8("Sis Launcher Server - textshell - skipping shutdown of user applications"));  
                }
            else
                {
                // emulatore running with GUI
                #ifndef SWI_TEXTSHELL_ROM
                Server().ShutdownL();
                #endif
                }
            aMessage.Complete(KErrNone);
            break;  
            }
        case ECheckApplicationInUse:
            {
            TInt srcLen=aMessage.GetDesLengthL(0);
                
            HBufC8* appInUseBuffer = HBufC8::NewLC(srcLen);
            TPtr8 appInUseBufferPtr = appInUseBuffer->Des();    
            aMessage.ReadL(0, appInUseBufferPtr, 0);
     
            TAppInUse* appInUsePtr = (TAppInUse*) User::AllocL(srcLen);
            CleanupStack::PushL(appInUsePtr);   
            Mem::Copy(appInUsePtr, appInUseBufferPtr.Ptr(), srcLen);
 
            TUint appInUseCount=srcLen/sizeof(TAppInUse);
            for (TInt i=0;i<appInUseCount;i++)
                {
                TRAPD(err, CheckApplicationInUseL(appInUsePtr[i].iAppUid));
                if (err==KErrInUse)  
                    {
                    appInUsePtr[i].iInUse=ETrue;
                    }            
                }   
     
            TUint8* dataPtr=reinterpret_cast<TUint8*>(appInUsePtr);
            const TPtrC8 data(dataPtr, srcLen); 
        
            //Indicate the client apps in use
            aMessage.WriteL(0, data);                           
            aMessage.Complete(KErrNone);
            CleanupStack::PopAndDestroy(appInUsePtr);
            CleanupStack::PopAndDestroy(appInUseBuffer);    
            break;
            }
        case ENotifyNewApps:
            {
            TInt size = aMessage.GetDesLengthL(0);

            HBufC8* buf = HBufC8::NewLC(size);
            TPtr8 bufPtr = buf->Des();
            aMessage.ReadL(0, bufPtr);

            RDesReadStream stream(*buf);
            RPointerArray<TDesC> files;
            InternalizePointerArrayL(files, stream);
            
            if (Server().BootUpMode() == KTextShell) 
                {
                // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
                DEBUG_PRINTF(_L8("Sis Launcher Server - TextShell - skipping notification of new applications (ENotifyNewApps)."));
                }
            else
                {
                // emulatore running with GUI
                #ifndef SWI_TEXTSHELL_ROM
                Server().NotifyNewAppsL(files);
                #endif // SWI_TEXTSHELL_ROM
                }
            
            files.ResetAndDestroy();
            CleanupStack::PopAndDestroy(buf);
            
            aMessage.Complete(KErrNone);
            break;
            }
#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
        case EParseSwTypeRegFile:
            #ifndef SWI_TEXTSHELL_ROM
            ParseSwTypeRegFileL(aMessage);
            #endif
            aMessage.Complete(KErrNone);
            break;
        case ERegisterSifLauncherMimeTypes:
            #ifndef SWI_TEXTSHELL_ROM
            RegisterSifLauncherMimeTypesL(aMessage);
            #endif
            aMessage.Complete(KErrNone);
            break;
        case EUnregisterSifLauncherMimeTypes:
            #ifndef SWI_TEXTSHELL_ROM            
            UnregisterSifLauncherMimeTypesL(aMessage);
            #endif
            aMessage.Complete(KErrNone);
            break;
        case EAsyncParseResourceFileSize:
            {
            TRAPD(err,err = AsyncParseResourceFileSizeL(aMessage));            
            aMessage.Complete(err);            
            break;
            }
        case EAsyncParseResourceFileData:
            {
            TRAPD(err,AsyncParseResourceFileDataL(aMessage));
            aMessage.Complete(err);
            break;
            }
        case ENotifyNewAppsData:
            {
            RIpcReadStream readStream;
            readStream.Open(aMessage, 0);
            CleanupClosePushL(readStream);

            RPointerArray<Usif::CApplicationRegistrationData> appRegInfo;
            CleanupClosePushL(appRegInfo);

            const TInt numElems = readStream.ReadInt32L();
            for (TInt i=0; i<numElems; ++i)
                {
                Usif::CApplicationRegistrationData* info = Usif::CApplicationRegistrationData::NewL(readStream);
                CleanupStack::PushL(info);
                appRegInfo.AppendL(info);
                CleanupStack::Pop(info);
                }

            if (Server().BootUpMode() == KTextShell) 
                {
                // emulator tests running in textshell or in textshell ROM (#def SWI_TEXTSHELL_ROM)
                DEBUG_PRINTF(_L8("Sis Launcher Server - TextShell - Skipping notification of force registered applications."));
                }
            else
                {
                // emulatore running with GUI
                #ifndef SWI_TEXTSHELL_ROM
                Server().NotifyNewAppsL(appRegInfo);
                #endif // SWI_TEXTSHELL_ROM
                }
            appRegInfo.ResetAndDestroy();
            CleanupStack::PopAndDestroy(2);
            aMessage.Complete(KErrNone);
            break;
            }
        case ENotifyApparcForApps:
            {
            if (Server().BootUpMode() == KTextShell) 
                {
                DEBUG_PRINTF(_L8("Sis Launcher Server - TextShell - Skipping notification of applications (ENotifyApparcForApps)."));
                }
            else
                {
                #ifndef SWI_TEXTSHELL_ROM
                NotifyApparcForAppsL(aMessage);  
                #endif
                }
            aMessage.Complete(KErrNone);
            break;
            }
#endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
        case EQueueRunExecutable:
            //fall through
        case EQueueStartDocumentByHandle:
            //fall through
        case EQueueStartByMimeByHandle:
            Server().RunQueue().AddToQueueL(aMessage);
            aMessage.Complete(KErrNone);
            break;
        case EExecuteQueue:
            aMessage.Complete(Server().RunQueue().ExecuteQueue());
            break;
        case EKillQueue:
            Server().RunQueue().ResetQueue();
            aMessage.Complete(KErrNone);
            break;
        default:
            {
            PanicClient(aMessage,EPanicIllegalFunction);
            break;
            }
        }
    }


void CSisLauncherSession::ServiceError(const RMessage2& aMessage,TInt aError)
    {
    DEBUG_PRINTF2(_L8("Sis Launcher Server - ServiceL failed with error code %d."), aError);
    
    if (aError==KErrBadDescriptor)
        {
        PanicClient(aMessage,EPanicBadDescriptor);
        }
    CSession2::ServiceError(aMessage,aError);
    }


void CSisLauncherSession::CheckApplicationInUseL(TUid aUid)
    {
    
    TFindProcess findProcess;
    TFullName fullName;
 
    while(findProcess.Next(fullName) == KErrNone)
        {
        RProcess process;
        User::LeaveIfError(process.Open(findProcess));
        TUid sid(process.SecureId());
        TExitType exitType = process.ExitType();
        process.Close();
        if (sid == aUid && exitType == EExitPending)
                    User::Leave(KErrInUse);
        }
    }


#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK   
TInt CSisLauncherSession::AsyncParseResourceFileSizeL(const RMessage2& aMessage)
    {
    // We only support one call at once currently
    if (iInAsyncParseResourceFile)
        {
        return KErrInUse;
        }
    else
        {
        iInAsyncParseResourceFile=ETrue;
        delete iCurrentAppRegData;
        iCurrentAppRegData=NULL;

        RFs fs;
        RFile file;
        User::LeaveIfError(fs.Connect());
        CleanupClosePushL(fs);
        file.AdoptFromClient(aMessage, 0, 1);   
        CleanupClosePushL(file);
        //Read languages need to pass
        TInt bufSize=0;
        bufSize = aMessage.GetDesMaxLength(2);
        HBufC8* bufToHoldLanguages = HBufC8::NewLC(bufSize);
        TPtr8 bufPtrDscToHoldLanguages = bufToHoldLanguages->Des();
        aMessage.ReadL(2, bufPtrDscToHoldLanguages, 0);
      
        RDesReadStream inStream(bufPtrDscToHoldLanguages);
        CleanupClosePushL(inStream);
        TInt32 languageCount = inStream.ReadInt32L();

        RArray<TLanguage> appLanguages;
        CleanupClosePushL(appLanguages);

        for (TInt i=0; i<languageCount; i++)
           appLanguages.AppendL((TLanguage)inStream.ReadInt32L());
                           
        CAppRegInfoReader *appRegInfoReader = CAppRegInfoReader::NewL(fs,file);
        CleanupStack::PushL(appRegInfoReader);
        
        TRAPD(err,iCurrentAppRegData = appRegInfoReader->ReadL(appLanguages));
        if (KErrNone != err)
            {
            iInAsyncParseResourceFile=EFalse;
            User::Leave(err);
            }
        
        iInAsyncParseResourceFile=EFalse;   
        TInt objectSize=0;
        objectSize= GetObjectSizeL(iCurrentAppRegData);
        if (objectSize > 0)
            {
            //Everything went fine so return the buffer size.            
            CleanupStack::PopAndDestroy(6,&fs);  
            return objectSize;          
            }
        else
            User::Leave(KErrUnknown);
        }
    return KErrNone;
    }
   
void CSisLauncherSession::AsyncParseResourceFileDataL(const RMessage2& aMessage)
    {
    if (iCurrentAppRegData)
        {
        WriteObjectDataL(aMessage, 0, iCurrentAppRegData); 
        delete iCurrentAppRegData;
        iCurrentAppRegData=NULL;
        }
    else
        User::Leave(KErrArgument);
    }

void CSisLauncherSession::ParseSwTypeRegFileL(const RMessage2& aMessage)
    {
    // Unpack the file handle
    RFile file;
    User::LeaveIfError(file.AdoptFromClient(aMessage, 0, 1));
    CleanupClosePushL(file);
    
    // Read the registration file
    TInt fileSize = 0;
    User::LeaveIfError(file.Size(fileSize));
    HBufC8* buf = HBufC8::NewLC(fileSize);
    TPtr8 bufPtr = buf->Des();
    User::LeaveIfError(file.Read(bufPtr));

    // Parse the registration file
	RCPointerArray<Usif::CSoftwareTypeRegInfo> regInfoArray;
    CleanupClosePushL(regInfoArray);
    
    CSoftwareTypeRegInfoParser* parser = CSoftwareTypeRegInfoParser::NewL();
    CleanupStack::PushL(parser);
    parser->ParseL(*buf, regInfoArray);

    // Pack the registration data
    RBuf8 serializedRegInfo;
    serializedRegInfo.CleanupClosePushL();
    SoftwareTypeRegInfoUtils::SerializeArrayL(regInfoArray, serializedRegInfo);
    aMessage.Write(2, serializedRegInfo);

    CleanupStack::PopAndDestroy(5, &file); // buf, regInfoArray, parser, serializedRegInfo
    }

#ifndef SWI_TEXTSHELL_ROM
void CSisLauncherSession::NotifyApparcForAppsL(const RMessage2& aMessage)
    {
    DEBUG_PRINTF(_L8("Sending the notification to AppArc."));
    RIpcReadStream readStream;
    readStream.Open(aMessage, 0);
    CleanupClosePushL(readStream);    
    RArray<TApaAppUpdateInfo> apparcAppInfoArray;
    CleanupClosePushL(apparcAppInfoArray);
    
    RApaLsSession apaSession;
    TInt err = apaSession.Connect();
    if(KErrNone != err)
        {
        DEBUG_PRINTF2(_L8("RApaLsSession::Connect failed with %d. Notification to AppArc failed."), err);
        User::LeaveIfError(err);
        }
    CleanupClosePushL(apaSession);
    TApaAppUpdateInfo::TApaAppAction appaction = TApaAppUpdateInfo::EAppNotPresent;
    const TInt numElems = readStream.ReadInt32L();
    DEBUG_PRINTF2(_L8("Number of applications to be notified is %d."), numElems);
    //Convert the local structure into the structure required by apparc
    for (TInt i=0; i<numElems; ++i)
        {
        TAppUpdateInfo appInfo;
        appInfo.InternalizeL(readStream);   
        if(appInfo.iAction == EAppInstalled)
            {
            appaction = TApaAppUpdateInfo::EAppPresent;
            }
        else if(appInfo.iAction == EAppUninstalled)
            {
            appaction = TApaAppUpdateInfo::EAppNotPresent;
            }
        TApaAppUpdateInfo apparcAppUpdateInfo(appInfo.iAppUid, appaction);
        apparcAppInfoArray.AppendL(apparcAppUpdateInfo);                    
        DEBUG_PRINTF2(_L("AppUid is 0x%x"), appInfo.iAppUid);
        DEBUG_PRINTF2(_L("Action is %d"), appInfo.iAction);         
        }    
    
    err = 0;
    TRAP(err, err = apaSession.UpdateAppListL(apparcAppInfoArray));
    if(KErrNone != err)
        {
        DEBUG_PRINTF2(_L8("RApaLsSession::UpdateAppListL failed with %d. Notification to AppArc failed."), err);
        User::LeaveIfError(err);
        }

    CleanupStack::PopAndDestroy(3, &readStream);       
    }

void CSisLauncherSession::RegisterSifLauncherMimeTypesL(const RMessage2& aMessage)
    {
    RegisterSifLauncherMimeTypesImplL(aMessage, ETrue);
    }

void CSisLauncherSession::UnregisterSifLauncherMimeTypesL(const RMessage2& aMessage)
    {
    RegisterSifLauncherMimeTypesImplL(aMessage, EFalse);
    }

void CSisLauncherSession::RegisterSifLauncherMimeTypesImplL(const RMessage2& aMessage, TBool aRegister)
    {
    // Read serialized MIME types from aMessage
    HBufC8* buf = HBufC8::NewLC(aMessage.GetDesLengthL(0));
    TPtr8 bufPtr(buf->Des());
    aMessage.ReadL(0, bufPtr);
    
    // Unserialize MIME types
    RDesReadStream rs(*buf);
    CleanupClosePushL(rs);
    
    RCPointerArray<HBufC8> mimeTypes;
    CleanupClosePushL(mimeTypes);
    
    InternalizePointerArrayL(mimeTypes, rs);
    
    // Connect to AppArc
    RApaLsSession apa;
    TInt err = apa.Connect();
    if (err != KErrNone)
        {
        DEBUG_PRINTF2(_L8("Failed to connect to the AppArc server, err = %d\n"),err);
        User::Leave(err);
        }
    CleanupClosePushL(apa);

    // Iterate over the MIME types and (un)register them
    for (TInt i=0; i<mimeTypes.Count(); ++i)
        {
        TDataType dataType(*mimeTypes[i]);
        if (aRegister)
            {
            const TUid KSifLauncherUid = {0x10285BD0};
            err = apa.InsertDataMapping(dataType, KDataTypePriorityTrustedHigh, KSifLauncherUid);
            }
        else
            {
            err = apa.DeleteDataMapping(dataType);
            }
        if (err != KErrNone)
            {
            DEBUG_PRINTF2(_L8("Failed to (un)register MIME types to AppArc, err = %d\n"),err);
            }
        }
    
    CleanupStack::PopAndDestroy(4, buf); //rs, mimeTypes, apa
    }

#endif // SWI_TEXTSHELL_ROM
#endif // SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK

} // namespace Swi