--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/apparchitecture/apserv/APSSES.CPP Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,2120 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// AppArc server session
+//
+// apsses.cpp
+//
+
+#include <e32svr.h>
+#include <apacmdln.h>
+
+#include <apaflrec.h>
+#include "apsserv.h"
+#include "APSSES.H"
+#ifdef _DEBUG
+#include "APSSTD.H"
+#endif //_DEBUG
+#include "APSCLSV.H"
+#include <apsscan.h>
+#include <apgaplst.h>
+#include <apgicnfl.h>
+#include <apmrec.h>
+#include <apmstd.h>
+#include <apmfndr.h>
+#include <datastor.h>
+#include <s32mem.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include "../apgrfx/apprivate.h"
+#include "apgnotif.h"
+#include "../aplist/aplappregfinder.h"
+#include "ApLaunchChecker.h"
+#include "apsnnapps.h"
+#include "../aplist/aplapplistitem.h"
+
+#include "apsecutils.h"
+
+const TInt KApaAppListServMaxBuffer=256;
+#include "APSRECCACHE.h"
+const TInt KApaAppInfoArrayGranularity = 4;
+const TInt KApaAppInfoDesMaxLength = sizeof(TApaAppInfo);
+
+#if defined(__PROFILE)
+_LIT(KProfileAppForDocumentL, "AppForDocumentL - %d.%06d seconds");
+_LIT(KProfileAppForDocumentPassedByFileHandleL, "AppForDocumentPassedByFileHandleL - %d.%06d seconds");
+#endif
+_LIT(KApaPanicCli,"APSERV-CLI");
+const TInt KFinishedScanning=-2;
+
+
+class MArrayItemWriter
+ {
+public:
+ virtual TInt ArrayItemCount() const=0;
+ virtual TInt ArrayItemSize() const=0;
+ virtual void WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const=0;
+ };
+
+NONSHARABLE_CLASS(TSizeArrayItemWriter) : public MArrayItemWriter
+ {
+public:
+ inline TSizeArrayItemWriter(const CArrayFix<TSize>& aArray) : iArray(aArray) {}
+public: // from MArrayItemWriter
+ TInt ArrayItemCount() const;
+ TInt ArrayItemSize() const;
+ void WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const;
+private:
+ const CArrayFix<TSize>& iArray;
+ };
+
+NONSHARABLE_CLASS(TViewDataArrayItemWriter) : public MArrayItemWriter
+ {
+public:
+ inline TViewDataArrayItemWriter(const CArrayPtr<CApaAppViewData>& aArray) : iArray(aArray) {}
+public: // from MArrayItemWriter
+ TInt ArrayItemCount() const;
+ TInt ArrayItemSize() const;
+ void WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const;
+private:
+ const CArrayPtr<CApaAppViewData>& iArray;
+ };
+
+NONSHARABLE_CLASS(TDesCArrayItemWriter) : public MArrayItemWriter
+ {
+public:
+ inline TDesCArrayItemWriter(const CDesCArray& aArray) : iArray(aArray) {}
+public: // from MArrayItemWriter
+ TInt ArrayItemCount() const;
+ TInt ArrayItemSize() const;
+ void WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const;
+private:
+ const CDesCArray& iArray;
+ };
+
+NONSHARABLE_CLASS(CApaAppListServSession::CApaAppInfo) : public CBase
+ {
+public:
+ CApaAppInfo();
+ ~CApaAppInfo();
+ void SetUid(const TUid aUid);
+ void SetCaptionL(const TDesC& aCaption);
+ void SetShortCaptionL(const TDesC& aShortCaption);
+ void SetFullNameL(const TDesC& aFullName);
+ inline TPtrC Caption() const;
+ inline TPtrC ShortCaption() const;
+ inline TPtrC FullName() const;
+ inline TUid Uid() const;
+private:
+ TUid iUid;
+ HBufC* iCaption;
+ HBufC* iShortCaption;
+ HBufC* iFullName;
+ };
+
+inline TPtrC CApaAppListServSession::CApaAppInfo::Caption() const
+ { return *iCaption; }
+
+inline TPtrC CApaAppListServSession::CApaAppInfo::ShortCaption() const
+ { return *iShortCaption; }
+
+inline TPtrC CApaAppListServSession::CApaAppInfo::FullName() const
+ { return *iFullName; }
+
+inline TUid CApaAppListServSession::CApaAppInfo::Uid() const
+ { return iUid; }
+
+//
+// CApaAppListServSession
+//
+
+CApaAppListServSession* CApaAppListServSession::NewL(RFs& aFs, CApaAppArcServer& aAppArcSrv, CApaAppList& aAppList)
+ {
+ CApaAppListServSession* self = new (ELeave) CApaAppListServSession(aFs, aAppArcSrv, aAppList);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CApaAppListServSession::CApaAppListServSession(RFs& aFs, CApaAppArcServer& aAppArcSrv, CApaAppList& aAppList)
+ : iFs(aFs), iAppArcSrv(aAppArcSrv), iAppList(aAppList), iApaAppInfoArray(KApaAppInfoArrayGranularity)
+ {
+
+ }
+
+void CApaAppListServSession::ConstructL()
+ {
+ iNonNativeApplicationsManager = CApsNonNativeApplicationsManager::NewL(iAppArcSrv,iFs);
+ }
+
+
+CApaAppListServSession::~CApaAppListServSession()
+ {
+ delete iNonNativeApplicationsManager;
+ iApaAppInfoArray.ResetAndDestroy();
+ iApaAppInfoArray.Close();
+ }
+
+CApaAppList& CApaAppListServSession::AppList()
+ {
+ return iAppList;
+ }
+
+
+void CApaAppListServSession::DoServiceL(const RMessage2& aMessage)
+ {
+ TBool completeMessage = ETrue;
+ const TInt opcode = aMessage.Function();
+ switch (opcode)
+ {
+ case ESetNotify:
+ SetNotify(aMessage);
+ completeMessage=EFalse;
+ break;
+ case ERegisterListPopulationCompleteObserver:
+ RegisterListPopulationCompleteObserver(aMessage);
+ completeMessage=EFalse;
+ break;
+ case ECancelListPopulationCompleteObserver:
+ CancelListPopulationCompleteObserver();
+ break;
+ case EAppListServInitFullList:
+ User::Leave(KErrNotSupported);
+ case EAppListServInitEmbedList:
+ User::Leave(KErrNotSupported);
+ case EAppListServInitFilteredEmbedList:
+ InitListL(aMessage,EListFilteredEmbeddedApps);
+ break;
+ case EAppListServInitAttrFilteredList:
+ InitListL(aMessage,EListCapabilityAttrFilteredApps);
+ break;
+ case EAppListServInitServerAppList:
+ InitListL(aMessage,EListServerApps);
+ break;
+ case EAppListServGetNextApp:
+ GetNextAppL(aMessage);
+ break;
+ case EAppListServEmbedCount:
+ EmbedCount(aMessage);
+ break;
+ case EAppListServAppCount:
+ AppCount(aMessage);
+ break;
+ case EAppListServGetAppInfo:
+ GetAppInfoL(aMessage);
+ break;
+ case EAppListServGetAppCapability:
+ GetAppCapabilityL(aMessage);
+ break;
+ case EAppListServGetDefaultScreenNumber:
+ GetDefaultScreenNumberL(aMessage);
+ break;
+ case EAppListServAppIconByUid:
+ IconForAppL(aMessage);
+ break;
+ case ECancelNotify:
+ CancelNotify();
+ break;
+ case EAppListServAppIconByUidAndSize:
+ IconForAppBySizeL(aMessage);
+ break;
+ case EAppListServAppIconFileHandle:
+ IconFileHandleForAppL(aMessage);
+ break;
+ case EAppListServGetAppIconSizes:
+ AppIconSizesL(aMessage);
+ break;
+ case EAppListServViewIconByUidAndSize:
+ IconForViewBySizeL(aMessage);
+ break;
+ case EAppListServGetAppViews:
+ AppViewsL(aMessage);
+ break;
+ case EAppListServGetFileOwnershipInfo:
+ AppFileOwnershipInfoL(aMessage);
+ break;
+ case EAppListServNumberOfOwnDefinedIcons:
+ NumberOfOwnDefinedIconsL(aMessage);
+ break;
+ case EAppListServApplicationLanguage:
+ ApplicationLanguageL(aMessage);
+ break;
+ case EAppListServAppInfoProvidedByRegistrationFile: // private OpCode for CEikApplication's use only
+ AppInfoProvidedByRegistrationFileL(aMessage);
+ break;
+ case EAppListServAppIconFileName:
+ IconFileNameL(aMessage);
+ break;
+ case EAppListServAppViewIconFileName:
+ ViewIconFileNameL(aMessage);
+ break;
+ case EAppListServPrepareNonNativeApplicationsUpdates:
+ iNonNativeApplicationsManager->PrepareNonNativeApplicationsUpdatesL();
+ break;
+ case EAppListServRegisterNonNativeApplication:
+ iNonNativeApplicationsManager->RegisterNonNativeApplicationL(aMessage);
+ break;
+ case EAppListServDeregisterNonNativeApplication:
+ iNonNativeApplicationsManager->DeregisterNonNativeApplicationL(aMessage);
+ break;
+ case EAppListServCommitNonNativeApplications:
+ iNonNativeApplicationsManager->CommitNonNativeApplicationsUpdatesL(aMessage);
+ completeMessage=EFalse;
+ break;
+ case EAppListServRollbackNonNativeApplications:
+ iNonNativeApplicationsManager->RollbackNonNativeApplicationsUpdates();
+ break;
+ case EAppListServGetAppType:
+ GetAppTypeL(aMessage);
+ break;
+ case EAppListServForceRegistration:
+ ForceRegistrationL(aMessage);
+ completeMessage=EFalse;
+ break;
+ case EMatchesSecurityPolicy:
+ MatchesSecurityPolicyL(aMessage);
+ break;
+ case EAppListServSetAppShortCaption:
+ SetAppShortCaptionL(aMessage);
+ break;
+ case EDebugClearAppInfoArray:
+ #ifdef _DEBUG
+ iApaAppInfoArray.ResetAndDestroy();
+ iApaAppInfoArray.Compress();
+ #endif
+ break;
+ case EDebugAddFailingNonNativeApplicationsUpdate:
+ #ifdef _DEBUG
+ iNonNativeApplicationsManager->ForceFailInNonNativeApplicationsUpdatesL();
+ #endif
+ break;
+ case EDebugAddPanicingNonNativeApplicationsUpdate:
+ #ifdef _DEBUG
+ iNonNativeApplicationsManager->ForcePanicInNonNativeApplicationsUpdatesL();
+ #endif
+ break;
+ case EDebugAddRollbackPanicingNonNativeApplicationsUpdate:
+ #ifdef _DEBUG
+ iNonNativeApplicationsManager->ForcePanicInNonNativeApplicationsRollbackL();
+ #endif
+ break;
+ default:
+ aMessage.Panic(KApaPanicCli,EClientBadRequest);
+ break;
+ }
+
+ if (completeMessage && !aMessage.IsNull())
+ aMessage.Complete(KErrNone);
+ }
+
+
+// CApaAppArcServSession
+
+CApaAppArcServSession* CApaAppArcServSession::NewL(CApaAppArcServer& aServer, RFs& aFs)
+ {
+ CApaAppArcServSession* self=new(ELeave) CApaAppArcServSession(aServer, aFs);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+CApaAppArcServSession::CApaAppArcServSession(CApaAppArcServer& aServer, RFs& aFs)
+ : CSession2(),
+ iServ(aServer),
+ iFs(aFs),
+ iMaxBufSize(KApaAppListServMaxBuffer),
+ iOpaqueData_pendingDispatchToClient(NULL)
+ {}
+
+void CApaAppArcServSession::ConstructL()
+ {
+ iAppListSession = CApaAppListServSession::NewL(iFs, iServ, iServ.AppList());
+ iFileRecognitionUtility = new (ELeave) CFileRecognitionUtility(iServ, iMaxBufSize, iFs);
+ }
+
+CApaAppArcServSession::~CApaAppArcServSession()
+ {
+ delete iAppListSession;
+ delete iBuffer;
+ delete iFileRecognitionUtility;
+ delete iRecognitionResult;
+ delete iOpaqueData_pendingDispatchToClient;
+ }
+
+void CApaAppArcServSession::ServiceL(const RMessage2& aMessage)
+ {
+ TBool completeMessage = ETrue;
+ switch (aMessage.Function())
+ {
+ case EAppListServStartAppWithoutReturningThreadId:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServStartAppReturningThreadId:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServRecognizeData:
+ RecognizeDataL(aMessage);
+ break;
+ case EAppListServRecognizeDataPassedByFileHandle:
+ RecognizeDataPassedByFileHandleL(aMessage);
+ break;
+ case EAppListServRecognizeSpecificData:
+ RecognizeSpecificDataL(aMessage);
+ break;
+ case EAppListServRecognizeSpecificDataPassedByFileHandle:
+ RecognizeSpecificDataPassedByFileHandleL(aMessage);
+ break;
+ case EAppListServAppForDataType:
+ AppForDataTypeL(aMessage);
+ break;
+ case EAppListServStartDocument:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServStartDocumentByDataType:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServStartDocumentByUid:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServCreateDocumentByUid:
+ ASSERT(0); // panic debug only
+ User::Leave(KErrNotSupported);
+ break;
+ case EAppListServGetExecutableNameGivenDocument:
+ GetExecutableNameGivenDocumentL(aMessage);
+ break;
+ case EAppListServGetExecutableNameGivenDocumentPassedByFileHandle:
+ GetExecutableNameGivenDocumentPassedByFileHandleL(aMessage);
+ break;
+ case EAppListServGetExecutableNameGivenDataType:
+ GetExecutableNameGivenDataTypeL(aMessage);
+ break;
+ case EAppListServGetExecutableNameGivenAppUid:
+ GetExecutableNameGivenAppUidL(aMessage);
+ break;
+ case EAppListServGetOpaqueData:
+ GetOpaqueDataL(aMessage);
+ break;
+ case EAppListServGetNativeExecutableNameIfNonNative:
+ GetNativeExecutableNameIfNonNativeL(aMessage);
+ break;
+ case EAppListServAppForDocument:
+ AppForDocumentL(aMessage, NULL);
+ break;
+ case EAppListServAppForDocumentPassedByFileHandle:
+ AppForDocumentPassedByFileHandleL(aMessage, NULL);
+ break;
+ case EAppListServGetConfidence:
+ GetConfidenceL(aMessage);
+ break;
+ case EAppListServSetConfidence:
+ SetConfidence(aMessage);
+ break;
+ case EAppListServGetBufSize:
+ GetBufSize(aMessage);
+ break;
+ case EAppListServSetBufSize:
+ SetBufSize(aMessage);
+ break;
+ case EAppListServGetDataTypesPhase1:
+ GetDataTypesCountL(aMessage);
+ break;
+ case EAppListServGetDataTypesPhase2:
+ GetDataTypesL(aMessage);
+ break;
+ case EAppListInsertDataMapping:
+ case EAppListInsertDataMappingIfHigher:
+ InsertDataMappingL(aMessage);
+ break;
+ case EAppListDeleteDataMapping:
+ DeleteDataMappingL(aMessage);
+ break;
+ case EAppListServGetAppByDataType:
+ GetAppByDataTypeL(aMessage);
+ break;
+ case EAppListServGetAppServices:
+ case EAppListServGetServiceImplementations:
+ case EAppListServGetServiceImplementationsDataType:
+ case EAppListServGetAppServiceUids:
+ case EAppListServGetAppServiceOpaqueData:
+ GetAppServicesL(aMessage);
+ break;
+ case EAppListServAppForDataTypeAndService:
+ AppForDataTypeAndServiceL(aMessage);
+ break;
+ case EAppListServAppForDocumentAndService:
+ {
+ const TUid serviceUid=TUid::Uid(aMessage.Int1());
+ AppForDocumentL(aMessage, &serviceUid);
+ }
+ break;
+ case EAppListServAppForDocumentAndServicePassedByFileHandle:
+ {
+ const TUid serviceUid(TUid::Uid(aMessage.Int1()));
+ AppForDocumentPassedByFileHandleL(aMessage, &serviceUid);
+ }
+ break;
+ case EAppListServRegisterNonNativeApplicationType:
+ RegisterNonNativeApplicationTypeL(aMessage);
+ break;
+ case EAppListServDeregisterNonNativeApplicationType:
+ DeregisterNonNativeApplicationTypeL(aMessage);
+ break;
+ case EAppListServPreferredBufSize:
+ aMessage.Complete(PreferredBufSize());
+ break;
+ case EAppListServRecognizeFiles:
+ RecognizeFilesL(aMessage);
+ break;
+ case EAppListServTransferRecognitionResult:
+ TransferRecognitionResultL(aMessage);
+ break;
+ case EAppListServRecognizeFilesAsync:
+ RecognizeFilesAsyncL(aMessage);
+ completeMessage=EFalse;
+ break;
+ case ECancelRecognizeFiles:
+ CancelRecognizeFiles();
+ break;
+ case EAppListServRuleBasedLaunching:
+ AquirePermissionToLaunchAppL(aMessage);
+ break;
+ case ENotifyOnDataMappingChange:
+ NotifyOnDataMappingChange(aMessage);
+ completeMessage=EFalse;
+ break;
+ case ECancelNotifyOnDataMappingChange:
+ CancelNotifyOnDataMappingChange();
+ break;
+ case EDebugHeapMark:
+ #ifdef _DEBUG
+ __UHEAP_MARK;
+ #endif
+ break;
+ case EDebugHeapMarkEnd:
+ #ifdef _DEBUG
+ __UHEAP_MARKENDC(aMessage.Int0());
+ #endif
+ break;
+ case EDebugHeapFailNext:
+ #ifdef _DEBUG
+ __UHEAP_FAILNEXT(aMessage.Int0());
+ #endif
+ break;
+ case EDebugFlushRecognitionCache:
+ #ifdef _DEBUG
+ iServ.FlushRecognitionCache();
+ #endif
+ break;
+ case EDebugSetLoadRecognizersOnDemand:
+ #ifdef _DEBUG
+ iServ.SetLoadRecognizersOnDemandL(aMessage.Int0());
+ #endif
+ break;
+ case EDebugPerformOutstandingRecognizerUnloading:
+ #ifdef _DEBUG
+ iServ.PerformOutstandingRecognizerUnloading();
+ REComSession::FinalClose();
+ #endif
+ break;
+ default:
+ iAppListSession->DoServiceL(aMessage);
+ return;
+ }
+
+ if (completeMessage && !aMessage.IsNull())
+ aMessage.Complete(KErrNone);
+ }
+
+
+void CApaAppArcServSession::NotifyOnDataMappingChange(const RMessage2& aMessage)
+ {
+ if (!iMessage_NotifyOnDataMappingChange.IsNull())
+ aMessage.Panic(KApaPanicCli,ENotifyOnDataMappingChangeRequestOutstanding);
+ else
+ iMessage_NotifyOnDataMappingChange=aMessage;
+ }
+
+void CApaAppArcServSession::CancelNotifyOnDataMappingChange()
+ {
+ if (!iMessage_NotifyOnDataMappingChange.IsNull())
+ iMessage_NotifyOnDataMappingChange.Complete(KErrCancel);
+ } //lint !e1762 Suppress member function could be made const
+
+
+TInt CApaAppArcServSession::PreferredBufSize() const
+ {
+ TInt preferredBufferSize = 0;
+ TRAPD(err, preferredBufferSize = iServ.DataRecognizerPreferredBufSizeL());
+ return (err==KErrNone) ? Min(iMaxBufSize, preferredBufferSize) : iMaxBufSize;
+ }
+
+void CApaAppArcServSession::RegisterNonNativeApplicationTypeL(const RMessage2& aMessage)
+ {
+ const TUid applicationType(TUid::Uid(aMessage.Int0()));
+ HBufC* const nativeExecutable=HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
+ {TPtr nativeExecutable_asWritable(nativeExecutable->Des());
+ aMessage.ReadL(1, nativeExecutable_asWritable);}
+ iServ.RegisterNonNativeApplicationTypeL(applicationType, *nativeExecutable);
+ CleanupStack::PopAndDestroy(nativeExecutable);
+ }
+
+void CApaAppArcServSession::DeregisterNonNativeApplicationTypeL(const RMessage2& aMessage)
+ {
+ const TUid applicationType(TUid::Uid(aMessage.Int0()));
+ iServ.DeregisterNonNativeApplicationTypeL(applicationType);
+ }
+
+void CApaAppListServSession::GetAppTypeL(const RMessage2& aMessage)
+ {
+ TInt uid = aMessage.Int0();
+ CApaAppData* appData = iAppList.AppDataByUid(TUid::Uid(uid));
+ if (!appData)
+ aMessage.Complete(KErrNotFound);
+ else
+ {
+ TPckgBuf<TUid> typeUid(appData->NonNativeApplicationType());
+ aMessage.WriteL(1,typeUid);
+ aMessage.Complete(KErrNone);
+ }
+ }
+
+void CApaAppListServSession::ForceRegistrationL(const RMessage2& aMessage)
+ {
+ TInt bufferSize = aMessage.GetDesLength(0);
+ User::LeaveIfError(bufferSize);
+ HBufC8* const buffer=HBufC8::NewLC(bufferSize);
+ TPtr8 buffer_asWritable(buffer->Des());
+ aMessage.ReadL(0,buffer_asWritable);
+
+ RDesReadStream readStream(*buffer);
+ CleanupClosePushL(readStream);
+ const TUint count=readStream.ReadUint32L();
+ for (TUint i = 0; i < count; ++i)
+ {
+ TUint length = readStream.ReadUint32L();
+ HBufC* regFile = HBufC::NewLC(length);
+ TPtr ptr(regFile->Des());
+ readStream.ReadL(ptr, length);
+ iAppList.AddForcedRegistrationL(*regFile);
+ CleanupStack::PopAndDestroy(regFile);
+ }
+
+ CleanupStack::PopAndDestroy(&readStream);
+ CleanupStack::PopAndDestroy(buffer);
+
+ // Trigger a rescan, when rescan completes it will complete iNotifyOnScanCompleteMsg
+ iNotifyOnScanCompleteMsg=aMessage;
+ iAppArcSrv.UpdateAppsByForceRegistration();
+ }
+
+void CApaAppArcServSession::AppForDocumentPassedByFileHandleL(const RMessage2& aMessage, const TUid* aServiceUid)
+ {
+#if defined(__PROFILE)
+ TProfile profile;
+ RDebug::ProfileReset(5,1);
+ RDebug::ProfileStart(5);
+#endif
+ RFile file;
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.AdoptFromClient(aMessage, 2, 3));
+ SReturnData_AppForDocument returnData;
+ returnData.iDataType=iServ.RecognizeDataL(file, PreferredBufSize()).iDataType;
+ returnData.iUid=(returnData.iDataType!=TDataType())? AppForDataTypeL(returnData.iDataType, aServiceUid): TUid::Null();
+ CleanupStack::PopAndDestroy(&file);
+ aMessage.WriteL(0,TPckgC<SReturnData_AppForDocument>(returnData));
+#if defined(__PROFILE)
+ RDebug::ProfileEnd(5);
+ RDebug::ProfileResult(&profile,5,1);
+ RDebug::Print(KProfileAppForDocumentPassedByFileHandleL,profile.iTime/1000000,profile.iTime%1000000);
+ RDebug::ProfileStart(5);
+#endif
+ }
+
+/**
+Call the recognizer framework to find the MIME-type of the data buffer,
+then find and return the UID of the "best" application to handle that data.
+*/
+void CApaAppArcServSession::AppForDocumentL(const RMessage2& aMessage, const TUid* aServiceUid)
+ {
+#if defined(__PROFILE)
+ TProfile profile;
+ RDebug::ProfileReset(5,1);
+ RDebug::ProfileStart(5);
+#endif
+
+ // Get the document file name from the IPC message
+ HBufC* const docFileName = HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(2)));
+ {TPtr docFileName_asWritable(docFileName->Des());
+ aMessage.ReadL(2, docFileName_asWritable);}
+
+ // Get the data read from the document that will be used for recognition from the IPC message
+ HBufC8* const buffer = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(3)));
+ {TPtr8 buffer_asWritable(buffer->Des());
+ aMessage.ReadL(3,buffer_asWritable);}
+
+ // Call the recognizer framework to get the MIME-type
+ SReturnData_AppForDocument returnData;
+ returnData.iDataType = iServ.RecognizeDataL(*docFileName, *buffer).iDataType;
+ // If a MIME-type was found, get the UID of the "best" app registered for that type
+ returnData.iUid = (returnData.iDataType!=TDataType() ? AppForDataTypeL(returnData.iDataType, aServiceUid) : TUid::Null());
+
+#if defined(__PROFILE)
+ RDebug::ProfileEnd(5);
+ RDebug::ProfileResult(&profile,5,1);
+ RDebug::Print(KProfileAppForDocumentL,profile.iTime/1000000,profile.iTime%1000000);
+ RDebug::ProfileStart(5);
+#endif
+
+ // Send back the answer
+ CleanupStack::PopAndDestroy(2, docFileName);
+ aMessage.WriteL(0,TPckgC<SReturnData_AppForDocument>(returnData));
+ }
+
+void CApaAppArcServSession::GetConfidenceL(const RMessage2& aMessage)
+// void GetAcceptedConfidence(TInt& aConfidence);
+ {
+ aMessage.WriteL(0,TPckgBuf<TInt>(iServ.MimeTypeRecognizer()->AcceptedConfidence()));
+ }
+
+void CApaAppArcServSession::SetConfidence(const RMessage2& aMessage)
+// SetAcceptedConfidence(TInt aConfidence);
+ {
+ __ASSERT_DEBUG(iServ.MimeTypeRecognizer(), Panic(EPanicNullPointer));
+ iServ.MimeTypeRecognizer()->SetAcceptedConfidence(aMessage.Int0());
+ }
+
+void CApaAppArcServSession::GetBufSize(const RMessage2& aMessage)
+// GetMaxDataBufSize(TInt& aBufSize);
+ {
+ aMessage.Complete(iMaxBufSize);
+ }
+
+void CApaAppArcServSession::SetBufSize(const RMessage2& aMessage)
+// SetMaxDataBufSize(TInt aBufSize);
+ {
+ iMaxBufSize=aMessage.Int0();
+ }
+
+void CApaAppArcServSession::GetDataTypesCountL(const RMessage2& aMessage)
+ {
+ delete iBuffer;
+ iBuffer = NULL;
+ CDataTypeArray* const dataTypes = new(ELeave) CDataTypeArray(5);
+ CleanupStack::PushL(dataTypes);
+ iServ.DataTypeL(*dataTypes);
+
+ TInt completionCode=0; // not KErrNone, as completion code of zero tells the client that zero data types were found
+ if (dataTypes->Count()>0)
+ {
+ CBufBase* const buffer = CBufFlat::NewL(sizeof(TDataType));
+ CleanupStack::PushL(buffer);
+ RBufWriteStream writeStream(*buffer);
+ writeStream << *dataTypes;
+ CleanupStack::Pop(buffer);
+ iBuffer = buffer;
+ completionCode = iBuffer->Ptr(0).Size(); // number of bytes in buffer (not number of data types)
+ }
+
+ CleanupStack::PopAndDestroy(dataTypes);
+ aMessage.Complete(completionCode);
+ }
+
+void CApaAppArcServSession::GetDataTypesL(const RMessage2& aMessage)
+// GetSupportedDataTypes(CDataTypeArray& aDataTypes);
+ {
+ if(!iBuffer)
+ aMessage.Panic(KApaPanicCli,ENoSupportedDataTypes);
+ else
+ {
+ aMessage.WriteL(0,iBuffer->Ptr(0));
+ delete iBuffer;
+ iBuffer=NULL;
+ }
+ }
+
+CApaAppData& CApaAppListServSession::FindAppInListL(TUid aUid)
+ {
+ TApaAppEntry dummy;
+ CApaAppData* app = NULL;
+ if (!FindAppInList(app, dummy, aUid))
+ User::Leave(KErrNotFound);
+
+ return *app;
+ }
+
+void CApaAppListServSession::SendArrayL(const MArrayItemWriter& aArrayItemWriter,const RMessage2& aMessage) const
+ {
+ const TInt sizeOfBuffer=aMessage.Int1();
+ const TInt arrayItemCount=aArrayItemWriter.ArrayItemCount();
+ const TInt sizeRequired=sizeof(TInt)+(arrayItemCount*aArrayItemWriter.ArrayItemSize());
+ ASSERT(sizeRequired > 0);
+ if (sizeRequired>sizeOfBuffer)
+ User::Leave(sizeRequired); // causes aMessage to complete with sizeRequired
+
+ CBufFlat* const buf=CBufFlat::NewL(sizeRequired);
+ CleanupStack::PushL(buf);
+ buf->ExpandL(0,sizeRequired);
+ RBufWriteStream writeStream;
+ writeStream.Open(*buf);
+ writeStream.WriteUint32L(arrayItemCount);
+ for (TInt i=0; i<arrayItemCount; ++i)
+ aArrayItemWriter.WriteArrayItemL(writeStream,i);
+
+ writeStream.CommitL();
+ aMessage.WriteL(2,buf->Ptr(0));
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+void CApaAppListServSession::AppIconSizesL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+ if (app.NonMbmIconFile())
+ User::Leave(KErrNotSupported);
+
+ CArrayFixFlat<TSize>* array = app.IconSizesL();
+ CleanupStack::PushL(array);
+ TSizeArrayItemWriter arrayItemWriter(*array);
+ SendArrayL(arrayItemWriter, aMessage);
+ CleanupStack::PopAndDestroy(array);
+ }
+
+void CApaAppListServSession::AppViewsL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+ TViewDataArrayItemWriter arrayItemWriter(*app.Views());
+ SendArrayL(arrayItemWriter,aMessage);
+ }
+
+void CApaAppListServSession::AppFileOwnershipInfoL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+ TDesCArrayItemWriter arrayItemWriter(*app.OwnedFiles());
+ SendArrayL(arrayItemWriter,aMessage);
+ }
+
+void CApaAppListServSession::NumberOfOwnDefinedIconsL(const RMessage2& aMessage)
+ {
+ const TUid uid = TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+ if (app.NonMbmIconFile())
+ User::Leave(KErrNotSupported);
+
+ TInt count, defaultIconsUsed;
+ app.GetIconInfo(count, defaultIconsUsed);
+ if (defaultIconsUsed)
+ count=0;
+
+ TPckgC<TInt> pckg(count);
+ aMessage.Write(1,pckg);
+ }
+
+void CApaAppListServSession::ApplicationLanguageL(const RMessage2& aMessage)
+ {
+ const TUid appUid = TUid::Uid(aMessage.Int0());
+ const CApaAppData& appData = FindAppInListL(appUid);
+
+ const TLanguage appLanguage = appData.ApplicationLanguage();
+ TPckgC<TLanguage> pckg(appLanguage);
+ aMessage.Write(1,pckg);
+ }
+
+
+void CApaAppListServSession::IconForViewBySizeL(const RMessage2& aMessage)
+ // Passes back handles to the icon and mask bitmaps for bitmap sharing
+ {
+ TApaAppViewIconSizeData appViewIconSizeData;
+ {TPckg<TApaAppViewIconSizeData> appViewIconSizeData_asDescriptor(appViewIconSizeData);
+ aMessage.ReadL(0,appViewIconSizeData_asDescriptor);}
+ const CApaAppData& app = FindAppInListL(appViewIconSizeData.iAppUid);
+
+ ASSERT(app.Views());
+ const CArrayPtr<CApaAppViewData>& viewDataArray = *app.Views();
+ CApaMaskedBitmap* icon = NULL;
+ const TInt count = viewDataArray.Count();
+ for (TInt ii=0; ii<count; ii++)
+ {
+ const CApaAppViewData& appViewData = *viewDataArray[ii];
+ if (appViewData.Uid() == appViewIconSizeData.iViewUid)
+ {
+ if (appViewData.NonMbmIconFile())
+ User::Leave(KErrNotSupported);
+
+ icon=appViewData.Icon(appViewIconSizeData.iSize);
+ break;
+ }
+ }
+
+ if (!icon)
+ User::Leave(KErrNotFound);
+
+ SReturnData_ViewIconByUidAndSize returnData;
+ returnData.iIcon = icon->Handle();
+ returnData.iIconMask = icon->Mask()->Handle();
+ aMessage.WriteL(1,TPckgC<SReturnData_ViewIconByUidAndSize>(returnData));
+ }
+
+void CApaAppListServSession::IconForAppBySizeL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ const TSize size(aMessage.Int1(),aMessage.Int2());
+ const CApaAppData& app=FindAppInListL(uid);
+
+ if (app.NonMbmIconFile())
+ User::Leave(KErrNotSupported);
+
+ CApaMaskedBitmap* const icon=app.Icon(size);
+ if (!icon)
+ User::Leave(KErrNotFound);
+
+ SReturnData_AppIconByUidAndSize returnData;
+ returnData.iIcon=icon->Handle();
+ returnData.iIconMask=icon->Mask()->Handle();
+ aMessage.WriteL(3,TPckgC<SReturnData_AppIconByUidAndSize>(returnData));
+ }
+
+void CApaAppListServSession::IconFileHandleForAppL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ TApaAppEntry entry;
+ CApaAppData* app=NULL;
+ if (!FindAppInList(app,entry,uid))
+ User::Leave(KErrNotFound);
+
+ TPtrC iconFileName = app->IconFileName();
+ if (iconFileName.Length()==0)
+ User::Leave(KErrNotFound);
+
+ RFs fs;
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ User::LeaveIfError(fs.ShareProtected());
+
+ RFile file;
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.Open(fs, iconFileName, EFileShareReadersOnly));
+ User::LeaveIfError(file.TransferToClient(aMessage, 1));
+ CleanupStack::PopAndDestroy(2, &fs); //file and fs
+ }
+
+void CApaAppListServSession::IconForAppL(const RMessage2& aMessage)
+// from GetAppIcon(TUid aAppUid, TInt aSideInPixels, CApaMaskedBitmap& aAppBitmap);
+// BUT! It's interface is uid, side, icon handle, mask handle for bitmap sharing
+// and avoiding IPC overhead
+ {
+ const TUid uid = TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+
+ if (app.NonMbmIconFile())
+ User::Leave(KErrNotSupported);
+
+ const TInt side = aMessage.Int1();
+ CApaMaskedBitmap* const icon = app.Icon(side);
+ if (!icon)
+ User::Leave(KErrNotFound);
+
+ SReturnData_AppIconByUid returnData;
+ returnData.iIcon = icon->Handle();
+ returnData.iIconMask = icon->Mask()->Handle();
+ aMessage.WriteL(2,TPckgC<SReturnData_AppIconByUid>(returnData));
+ }
+
+void CApaAppArcServSession::AppForDataTypeL(const RMessage2& aMessage)
+// from AppForDataType(const TDataType& aDataType, TUid& aAppUid);
+ {
+ if (sizeof(TDataType) != aMessage.GetDesLengthL(0))
+ {
+ //Leave with KErrArgument if client passes other than TDataType
+ User::Leave(KErrArgument);
+ }
+ TDataType dataType;
+ {TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(0,dataType_asDescriptor);}
+ TPckgBuf<TUid> uid_asDescriptor(AppForDataTypeL(dataType, NULL));
+ aMessage.WriteL(1,uid_asDescriptor);
+ aMessage.Complete(KErrNone);
+ }
+
+void CApaAppArcServSession::AppForDataTypeAndServiceL(const RMessage2& aMessage)
+ {
+ TDataType dataType;
+ {TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(0,dataType_asDescriptor);}
+ const TUid serviceUid=TUid::Uid(aMessage.Int1());
+ TPckgBuf<TUid> uid(AppForDataTypeL(dataType, &serviceUid));
+ aMessage.WriteL(2,uid);
+ aMessage.Complete(KErrNone);
+ }
+
+TUid CApaAppArcServSession::AppForDataTypeL(const TDataType& aDataType, const TUid* aServiceUid)
+ {
+ // It is possible to register apps as datatype handlers with system priority,
+ // which means that they are not overridable by user mappings.
+ // So search the list of apps for a datahandler and get the associated
+ // priority
+
+ TInt priority = KDataTypePriorityNormal;
+ TUid uid = iAppListSession->AppList().PreferredDataHandlerL(aDataType, aServiceUid, priority);
+ if (priority == KDataTypePrioritySystem)
+ return uid; // We have found a handler with system priority
+
+ // No handler with system priority so see if there is a user mapping
+ TUid userUid = KNullUid;
+ if (aServiceUid)
+ iServ.GetAppForMimeType(aDataType,*aServiceUid,userUid);
+ else
+ iServ.GetAppForMimeType(aDataType,userUid);
+
+ TApaAppEntry entry;
+ const CApaAppData* app = NULL;
+ if (userUid.iUid && iAppListSession->FindAppInList(app,entry,userUid))
+ return userUid; // The user mapping is valid
+
+ // A user mapping was not found or is invalid so try to use
+ // the uid returned by PreferredDataHandlerL.
+ if (!uid.iUid && aDataType.IsNative())
+ uid = aDataType.Uid();
+
+ return uid;
+ }
+
+void CApaAppArcServSession::InsertDataMappingL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TDataType> dataType;
+ aMessage.ReadL(0, dataType);
+ TDataTypePriority priority = aMessage.Int1();
+ const TUid appUid = { aMessage.Int2() };
+
+ if(priority>KDataTypeUnTrustedPriorityThreshold || priority == KDataTypePrioritySystem )
+ {
+ CApaAppData* appData = iAppListSession->AppList().AppDataByUid(appUid);
+ if( appData )
+ {
+ TBool hasWriteDeviceDataCap( EFalse );
+ TBool isSidTrusted( EFalse );
+
+ CApaSecurityUtils::CheckAppSecurity( appData->AppEntry().iFullName,
+ hasWriteDeviceDataCap,
+ isSidTrusted);
+
+ if (priority == KDataTypePrioritySystem )
+ {
+ // Check if the app has capability WriteDeviceData
+ if ( !hasWriteDeviceDataCap )
+ {
+ priority = KDataTypePriorityNormal;
+ }
+ }
+ else
+ {
+ TPtrC registrationFilePath = appData->RegistrationFileName();
+ TInt match = registrationFilePath.MatchF (
+ KLitPathForUntrustedRegistrationResourceFiles );
+ //Check if registration file is in path for untrusted apps
+ //and its SID is untrusted
+ if (match != KErrNotFound && !isSidTrusted )
+ {
+ // "cap" the priority if UnTrusted apps claim for priority higher
+ // than UnTrusted apps Threshold priority
+ priority = KDataTypeUnTrustedPriorityThreshold;
+ }
+ }
+ }
+ else
+ {
+ //if the application is not present in the applist
+ //then the priority will be reduced to Threshold
+ priority = KDataTypeUnTrustedPriorityThreshold;
+ }
+ }
+
+ const TUid serviceUid = { aMessage.Int3() };
+ if(aMessage.Function() == EAppListInsertDataMappingIfHigher)
+ {
+ const TBool response = iServ.InsertAndStoreIfHigherL(dataType(), priority, appUid);
+ aMessage.WriteL(3, TPckgC<TBool>(response));
+ }
+ else
+ iServ.InsertAndStoreDataMappingL(dataType(), priority, appUid, serviceUid);
+ }
+
+void CApaAppArcServSession::DeleteDataMappingL(const RMessage2& aMessage)
+ {
+ TPckgBuf<TDataType> dataType;
+ aMessage.ReadL(0, dataType);
+ const TUid serviceUid = { aMessage.Int1() };
+ TUid uid;
+ iServ.GetAppForMimeType(dataType(),serviceUid,uid);
+ if (uid != KNullUid)
+ {
+ // TypeStore doesn't support deletion of an inexistent mapping
+ iServ.DeleteAndStoreDataMappingL(dataType(), serviceUid);
+ aMessage.Complete(KErrNone);
+ }
+ else
+ aMessage.Complete(KErrNotFound);
+ }
+
+void CApaAppArcServSession::GetAppByDataTypeL(const RMessage2& aMessage) const
+ {
+ TPckgBuf<TDataType> dataType;
+ aMessage.ReadL(0,dataType);
+ const TUid serviceUid = { aMessage.Int1() };
+ TUid uid;
+ iServ.GetAppForMimeType(dataType(),serviceUid,uid);
+ TPckgC<TUid> uidpckg(uid);
+ aMessage.WriteL(2,uidpckg);
+ aMessage.Complete(KErrNone);
+ }
+
+void CApaAppArcServSession::GetExecutableNameGivenDocumentL(const RMessage2& aMessage)
+ {
+ HBufC* const name=HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(2)));
+ {TPtr name_asWritable(name->Des());
+ aMessage.ReadL(2, name_asWritable);}
+ HBufC8* const buffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(3)));
+ {TPtr8 buffer_asWritable(buffer->Des());
+ aMessage.ReadL(3, buffer_asWritable);}
+ const TDataType dataType(iServ.RecognizeDataL(*name, *buffer).iDataType);
+ CleanupStack::PopAndDestroy(2, name);
+
+ const TUid appUid(AppForDataTypeL(dataType, NULL));
+ GetExecutableNameL(aMessage, appUid);
+ }
+
+void CApaAppArcServSession::GetExecutableNameGivenDocumentPassedByFileHandleL(const RMessage2& aMessage)
+ {
+ RFile file;
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.AdoptFromClient(aMessage, 2, 3));
+ const TDataType dataType(iServ.RecognizeDataL(file, PreferredBufSize()).iDataType);
+ CleanupStack::PopAndDestroy(&file);
+
+ const TUid appUid(AppForDataTypeL(dataType, NULL));
+ GetExecutableNameL(aMessage, appUid);
+ }
+
+void CApaAppArcServSession::GetExecutableNameGivenDataTypeL(const RMessage2& aMessage)
+ {
+ if (sizeof(TDataType) != aMessage.GetDesLengthL(2))
+ {
+ //Leave with KErrArgument if client passes other than TDataType
+ User::Leave(KErrArgument);
+ }
+ TDataType dataType;
+ {TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(2, dataType_asDescriptor);}
+ const TUid appUid(AppForDataTypeL(dataType, NULL));
+ GetExecutableNameL(aMessage, appUid);
+ }
+
+void CApaAppArcServSession::GetExecutableNameGivenAppUidL(const RMessage2& aMessage)
+ {
+ const TUid appUid(TUid::Uid(aMessage.Int2()));
+ GetExecutableNameL(aMessage, appUid);
+ }
+
+void CApaAppArcServSession::GetExecutableNameL(const RMessage2& aMessage, TUid aAppUid)
+ {
+ const CApaAppData* appData=NULL;
+ TApaAppEntry entry;
+ if (!iAppListSession->FindAppInList(appData, entry, aAppUid))
+ User::Leave(iAppListSession->AppList().IsFirstScanComplete() ? KErrNotFound : RApaLsSession::EAppListInvalid);
+
+ const TDesC& executableName(entry.iFullName);
+ if (!executableName.Length())
+ User::Leave(KErrNotFound);
+
+ aMessage.WriteL(1, executableName); // the "logical" executable name - for non-native applications this is the name of the MIDlet, Python script, etc
+ WriteNativeExecutableIfNonNativeAndPrepareForClientRetrievalOfOpaqueDataL(aMessage, 0, *appData);
+ }
+
+void CApaAppArcServSession::GetNativeExecutableNameIfNonNativeL(const RMessage2& aMessage)
+ {
+ RBuf logicalExecutableName;
+ logicalExecutableName.CreateL(User::LeaveIfError(aMessage.GetDesLength(1)));
+ CleanupClosePushL(logicalExecutableName);
+ aMessage.ReadL(1, logicalExecutableName);
+ CApaAppData* const appData=iAppListSession->AppList().AppDataByFileName(logicalExecutableName);
+ if (appData!=NULL)
+ WriteNativeExecutableIfNonNativeAndPrepareForClientRetrievalOfOpaqueDataL(aMessage, 0, *appData);
+
+ CleanupStack::PopAndDestroy(&logicalExecutableName);
+ }
+
+void CApaAppArcServSession::WriteNativeExecutableIfNonNativeAndPrepareForClientRetrievalOfOpaqueDataL(const RMessage2& aMessage, TInt aMessageSlotForNativeExecutable, const CApaAppData& aAppData)
+ {
+ HBufC8* opaqueData=NULL;
+ const TPtrC8 opaqueData_asTPtrC8(aAppData.OpaqueData());
+ const TInt lengthOfOpaqueData(opaqueData_asTPtrC8.Length());
+ if (lengthOfOpaqueData>0)
+ opaqueData=opaqueData_asTPtrC8.AllocLC();
+
+ const TUid nonNativeApplicationType(aAppData.NonNativeApplicationType());
+ if (nonNativeApplicationType!=TUid::Null())
+ aMessage.WriteL(aMessageSlotForNativeExecutable, iServ.NativeExecutableL(nonNativeApplicationType));
+
+ delete iOpaqueData_pendingDispatchToClient; // only done when the potentially leaving stuff has all succeeded
+ iOpaqueData_pendingDispatchToClient=opaqueData; // want to do this, even if opaqueData is NULL
+ if (opaqueData)
+ {
+ CleanupStack::Pop(opaqueData);
+ aMessage.Complete(lengthOfOpaqueData);
+ }
+ }
+
+void CApaAppArcServSession::GetOpaqueDataL(const RMessage2& aMessage)
+ {
+ if (iOpaqueData_pendingDispatchToClient==NULL)
+ User::Leave(KErrGeneral); // the protocol was broken: EAppListServGetOpaqueData can only be called immediately after one of the EAppListServGetExecutableNameGivenXxx or EAppListServGetNativeExecutableNameGivenXxx opcodes - see the client-side implementation of this protocol in RApaLsSession::GetOpaqueData (and the places that call it)
+
+ aMessage.WriteL(0, *iOpaqueData_pendingDispatchToClient);
+ delete iOpaqueData_pendingDispatchToClient;
+ iOpaqueData_pendingDispatchToClient=NULL;
+ }
+
+void CApaAppListServSession::GetAppInfoL(TUid aUid, TApaAppInfo& aInfo)
+ {
+ const CApaAppData* app = NULL;
+ TApaAppEntry entry;
+ if (!FindAppInList(app, entry, aUid))
+ User::Leave(KErrNotFound);
+
+ aInfo.iUid = entry.iUidType[2];
+ aInfo.iFullName = entry.iFullName;
+ aInfo.iCaption = app->Caption();
+ aInfo.iShortCaption = app->ShortCaption();
+ }
+
+void CApaAppArcServSession::DoRecognizeUnpackLC(HBufC*& aName, HBufC8*& aBuffer, const RMessage2& aMessage)
+ {
+ ASSERT(aName==NULL);
+ ASSERT(aBuffer==NULL);
+ aName=HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(1)));
+ TPtr name(aName->Des());
+ aMessage.ReadL(1, name);
+ aBuffer=HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(2)));
+ TPtr8 buffer(aBuffer->Des());
+ aMessage.ReadL(2, buffer);
+ }
+
+void CApaAppArcServSession::RecognizeDataL(const RMessage2& aMessage)
+// Recognize the data type of an object
+ {
+ HBufC* name=NULL;
+ HBufC8* buffer=NULL;
+ DoRecognizeUnpackLC(name,buffer,aMessage);
+
+ const TDataRecognitionResult result = iServ.RecognizeDataL(*name, *buffer);
+
+ CleanupStack::PopAndDestroy(2); // name & buffer
+ aMessage.WriteL(0,TPckgC<TDataRecognitionResult>(result));
+ }
+
+
+void CApaAppArcServSession::RecognizeFilesL(const RMessage2& aMessage)
+ {
+ // if there is an outstanding async. request, we even don't allow
+ // a synchronous request at the same time (due to the two required
+ // server messages)
+ if (iAsyncRecognitionActive)
+ User::Leave(KErrInUse);
+
+ _LIT8(KAllDataTypes,"*");
+
+ // retrieve pathname
+ HBufC* const path=HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(0)));
+ TPtr pathPtr(path->Des());
+ aMessage.ReadL(0,pathPtr);
+
+ // retrieve data type filter
+ HBufC8* const dataType = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(2)));
+ TPtr8 dataTypePtr(dataType->Des());
+ aMessage.ReadL(2,dataTypePtr);
+
+ delete iRecognitionResult;
+ iRecognitionResult = NULL;
+
+ if(dataType->Compare(KAllDataTypes) == 0)
+ {
+ iRecognitionResult = new (ELeave) CDirectoryRecognitionResult(path, NULL);
+ CleanupStack::PopAndDestroy(dataType);
+ }
+ else
+ {
+ iRecognitionResult = new (ELeave) CDirectoryRecognitionResult(path,dataType);
+ CleanupStack::Pop(dataType);
+ }
+
+ CleanupStack::Pop(path); // ownership transferred to CDirectoryRecognitionResult
+ ASSERT(iFileRecognitionUtility);
+ iFileRecognitionUtility->RecognizeSynchronouslyL(*iRecognitionResult);
+ aMessage.WriteL(1,TPckgBuf<TUint>(iRecognitionResult->RequiredBufferSize()));
+ }
+
+void CApaAppArcServSession::TransferRecognitionResultL(const RMessage2& aMessage)
+ {
+ if(iRecognitionResult == NULL)
+ User::Leave(KErrNotReady);
+
+ iAsyncRecognitionActive = EFalse;
+
+ // if data is too big for buffer, tell client
+ const TInt sizeOfBuffer=aMessage.Int2();
+ if(sizeOfBuffer < iRecognitionResult->RequiredBufferSize())
+ User::Leave(KErrTooBig);
+
+ // buffer is big enough -> write result to buffer
+ CBufFlat* const buf=CBufFlat::NewL(iRecognitionResult->RequiredBufferSize());
+ CleanupStack::PushL(buf);
+ buf->ExpandL(0,iRecognitionResult->RequiredBufferSize());
+
+ RBufWriteStream writeStream;
+ writeStream.Open(*buf);
+ iRecognitionResult->WriteToStreamL(writeStream);
+ aMessage.WriteL(1,buf->Ptr(0));
+
+ delete iRecognitionResult;
+ iRecognitionResult = NULL;
+
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+void CApaAppArcServSession::RecognizeFilesAsyncL(const RMessage2& aMessage)
+ {
+ if (iAsyncRecognitionActive)
+ User::Leave(KErrInUse);
+ else
+ {
+ _LIT8(KAllDataTypes,"*");
+
+ HBufC* path = HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(0)));
+ TPtr pathPtr(path->Des());
+ aMessage.ReadL(0,pathPtr);
+
+ // retrieve data type filter
+ HBufC8* dataType = HBufC8::NewLC(User::LeaveIfError(aMessage.GetDesLength(2)));
+ TPtr8 dataTypePtr(dataType->Des());
+ aMessage.ReadL(2,dataTypePtr);
+
+ delete iRecognitionResult;
+ iRecognitionResult = NULL;
+
+ if(dataType->Compare(KAllDataTypes) == 0)
+ {
+ iRecognitionResult = new (ELeave) CDirectoryRecognitionResult(path,NULL);
+ CleanupStack::PopAndDestroy(dataType);
+ }
+ else
+ {
+ iRecognitionResult = new (ELeave) CDirectoryRecognitionResult(path,dataType);
+ CleanupStack::Pop(dataType);
+ }
+
+ CleanupStack::Pop(path); // ownership transferred to CDirectoryRecognitionResult
+ ASSERT(iFileRecognitionUtility);
+ iFileRecognitionUtility->RecognizeAsynchronously(*iRecognitionResult,aMessage);
+ iAsyncRecognitionActive = ETrue;
+ }
+ }
+
+/** The function interrogates all available rule based plug-ins if apparc can launch application with
+given full name. It loops through all plug-ins until gets value different from
+CAppLaunchChecker::EAppLaunchIndifferent.
+The application will be launched if the return code is not equal to
+CAppLaunchChecker::EAppLaunchDecline
+*/
+void CApaAppArcServSession::AquirePermissionToLaunchAppL(const RMessage2& aMessage) const
+ {
+ const CApaScanningRuleBasedPlugIns* theRuleBasedPlugIns = iServ.RuleBasedPlugIns();
+ const TInt theNumImp = (theRuleBasedPlugIns ? theRuleBasedPlugIns->ImplementationCount() : 0);
+ if(!theNumImp || !iServ.WsSession().Handle())
+ {
+ // Proceed with launch if rule based plug-in framework was not initialized
+ aMessage.Complete(ETrue);
+ return;
+ }
+
+ // Get the name of the app to start from the IPC message object
+ HBufC* theFullFileName = HBufC::NewLC(User::LeaveIfError(aMessage.GetDesLength(0)));
+ TPtr theFullFileNamePtr(theFullFileName->Des());
+ aMessage.ReadL(0, theFullFileNamePtr);
+
+ // Ge the application's UID from its name
+ const TUid theUid = iAppListSession->AppUidFromFullFileNameL(theFullFileNamePtr);
+ CleanupStack::PopAndDestroy(theFullFileName);
+
+ // Iterate through all plug-ins and look for one that's not indifferent
+ CAppLaunchChecker::TAppLaunchCode theLaunchCode = CAppLaunchChecker::EAppLaunchIndifferent;
+ TApaTaskList theTaskList(iServ.WsSession());
+ for(TInt ii = 0; ii < theNumImp; ii++)
+ {
+ CAppLaunchChecker* const theLauncherChecker = (*theRuleBasedPlugIns)[ii];
+ TRAP_IGNORE(theLaunchCode = theLauncherChecker->OkayToLaunchL(theUid, theTaskList));
+ if(theLaunchCode != CAppLaunchChecker::EAppLaunchIndifferent)
+ break;
+ }
+
+ // Return the result
+ const TBool okayToLaunch = (theLaunchCode != CAppLaunchChecker::EAppLaunchDecline);
+ aMessage.Complete(okayToLaunch);
+ }
+
+/**
+@param aFullFileName This filename is parsed and the path is replaced with "\\sys\\bin\\".
+ It uses ".exe" if no other is provided in the filename passed. If drive name is
+ present in the filename then it scans through the \\sys\\bin of that particular drive,
+ otherwise it scans through the \\sys\\bin folders in all the avaliable drives.
+@return Returns the Application Uid for the aFullFileName application.
+*/
+TUid CApaAppListServSession::AppUidFromFullFileNameL(const TDesC& aFullFileName) const
+ {
+
+ // If the appliation still wasn't found, use AppArc's appliation list
+ // Since we cannot get the Uid of NonNative apps by passing filename to RFs::Entry
+ CApaAppData* appData = iAppList.AppDataByFileName(aFullFileName);
+ if (appData)
+ {
+ TApaAppEntry appEntry = appData->AppEntry();
+ return appEntry.iUidType[2];
+ }
+
+
+//mm: Why does this code not use AppArc's application list only?
+//mm: The order in which different methods to locate the app is used seems inefficient.
+ _LIT(KSysBin, "\\sys\\bin\\");
+ _LIT(KFileExtension, ".EXE");
+
+ RLoader loader;
+ User::LeaveIfError(loader.Connect());
+ CleanupClosePushL(loader);
+ TPckgBuf<RLibrary::TInfo> dllInfo;
+
+ TParse parse;
+ parse.Set(aFullFileName,NULL,NULL);
+
+ // If the drive letter has been specified, look on that drive only...
+ TInt error = KErrNotFound;
+ if (parse.DrivePresent())
+ {
+ const TPtrC appDrive = parse.Drive();
+ TBuf<KMaxFileName>fileName(appDrive);
+ fileName.Append(KSysBin);
+ User::LeaveIfError(parse.SetNoWild(fileName, &aFullFileName, &KFileExtension));
+ error = loader.GetInfo(parse.FullName(), dllInfo);
+ }
+ else // ...otherwise scan all drives.
+ {
+ User::LeaveIfError(parse.SetNoWild(KSysBin, &aFullFileName, &KFileExtension));
+ TFileName tempFileName(parse.FullName());
+ TDriveList driveList;
+ User::LeaveIfError(iFs.DriveList(driveList));
+ for (TInt driveNumber = EDriveY; driveNumber != KFinishedScanning; driveNumber = NextDriveToScan(driveNumber))
+ {
+ if (driveList[driveNumber]!=0)
+ {
+ User::LeaveIfError(parse.SetNoWild(TDriveUnit(driveNumber).Name(), &tempFileName, NULL));
+ error = loader.GetInfo(parse.FullName(), dllInfo);
+ if (error == KErrNone)
+ break;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&loader);
+ // Return the UID if found and no errors occured
+ if(!error)
+ return dllInfo().iUids[2];
+
+ // If the application wasn't found
+ // Try looking for the application using normal F32. This won't work in protected directories
+
+ // Since we can't use RFs::Entry if the path refers the protected system directory (i.e. \sys\bin)...
+ User::LeaveIfError(parse.SetNoWild(aFullFileName, NULL, NULL));
+ if(parse.Path().FindF(KSysBin) == 0)
+ User::Leave(KErrNotFound); // ... then return not-found.
+
+//mm: Surely we should still be allowed to use AppArc below?
+
+ // The following is valid for non-native applications only
+ TEntry entry;
+ error = iFs.Entry(aFullFileName, entry);
+ if(!error)
+ return entry.iType[2];
+
+ User::Leave(KErrNotFound);
+ return TUid::Null(); // Won't be called
+ }
+
+/**
+Applies the scanning order Y: through A: then Z: last.
+*/
+TInt CApaAppListServSession::NextDriveToScan(TInt aCurrentDrive)
+ {
+ if (aCurrentDrive == EDriveZ)
+ return KFinishedScanning;
+ else if (aCurrentDrive == 0)
+ return EDriveZ; // finally scan the last one
+ else if (aCurrentDrive > 0 && aCurrentDrive < KMaxDrives)
+ return aCurrentDrive - 1;
+ else
+ return KErrGeneral; // never gets here, but it wont compile otherwise
+ }
+
+void CApaAppArcServSession::CancelRecognizeFiles()
+ {
+ if (iAsyncRecognitionActive)
+ {
+ ASSERT(iFileRecognitionUtility);
+ iFileRecognitionUtility->CancelRecognitionRequest();
+ iAsyncRecognitionActive = EFalse;
+ }
+ }
+
+void CApaAppArcServSession::RecognizeDataPassedByFileHandleL(const RMessage2& aMessage)
+// Recognize the data type of an object
+ {
+ RFile file;
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.AdoptFromClient(aMessage, 1, 2));
+ const TDataRecognitionResult result(iServ.RecognizeDataL(file, PreferredBufSize()));
+ CleanupStack::PopAndDestroy(&file);
+ aMessage.WriteL(0, TPckgC<TDataRecognitionResult>(result));
+ }
+
+void CApaAppArcServSession::RecognizeSpecificDataL(const RMessage2& aMessage)
+// Determine whether an object is of a specific data type
+ {
+ HBufC* name=NULL;
+ HBufC8* buffer=NULL;
+ DoRecognizeUnpackLC(name,buffer,aMessage);
+ TDataType dataType;
+ {TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(0, dataType_asDescriptor);}
+ aMessage.Complete(iServ.RecognizeDataL(*name,*buffer,dataType));
+ CleanupStack::PopAndDestroy(2); // name & buffer
+ }
+
+void CApaAppArcServSession::RecognizeSpecificDataPassedByFileHandleL(const RMessage2& aMessage)
+ {
+ RFile file;
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.AdoptFromClient(aMessage, 1, 2));
+ TDataType dataType;
+ {TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(0,dataType_asDescriptor);}
+ aMessage.Complete(iServ.RecognizeDataL(file, PreferredBufSize(), dataType));
+ CleanupStack::PopAndDestroy(&file);
+ }
+
+void CApaAppListServSession::InitListL(const RMessage2& aMessage, TAppListType aType)
+// carries out initialisation prior to starting to pass a new list across
+ {
+ iAppListType = aType;
+ iAppListScreenMode = aMessage.Int0();
+ if (aType == EListFilteredEmbeddedApps)
+ {
+ TApaEmbeddabilityFilter filter;
+ {TPckg<TApaEmbeddabilityFilter> filter_asDescriptor(filter);
+ aMessage.ReadL(1,filter_asDescriptor);}
+ iEmbeddabilityFilter = filter;
+ }
+
+ if (aType == EListCapabilityAttrFilteredApps)
+ {
+ iCapabilityAttrFilterMask = aMessage.Int1();
+ iCapabilityAttrFilterValue = aMessage.Int2();
+ }
+
+ if (aType == EListServerApps)
+ iServiceUid = TUid::Uid(aMessage.Int1());
+
+ iApaAppInfoArray.ResetAndDestroy();
+ iFlags|=EAppListPopulationPending;
+ }
+
+void CApaAppListServSession::EmbedCount(const RMessage2& aMessage) const
+// writes back the number of embedded apps in the list
+ {
+ TInt count=0;
+ const CApaAppList& list = iAppList;
+ CApaAppData* app = list.FirstApp();
+ TApaEmbeddabilityFilter filter;
+ filter.AddEmbeddability(TApaAppCapability::EEmbeddable);
+ filter.AddEmbeddability(TApaAppCapability::EEmbeddableOnly);
+ while (app)
+ {
+ if (!AppIsControlPanelItem(*app) && AppMatchesEmbeddabilityFilter(*app, filter))
+ count++;
+
+ app = list.NextApp(app);
+ }
+
+ aMessage.Complete(count);
+ }
+
+void CApaAppListServSession::AppCount(const RMessage2& aMessage) const
+// writes back the number of apps in the list
+ {
+ TInt count = 0;
+ const CApaAppList& list = iAppList;
+ CApaAppData* app = list.FirstApp();
+ while (app)
+ {
+ if (!AppIsControlPanelItem(*app))
+ count++;
+
+ app = list.NextApp(app);
+ }
+
+ aMessage.Complete(count);
+ }
+
+void CApaAppListServSession::GetNextAppL(const RMessage2& aMessage)
+ {
+ if (iFlags&EAppListPopulationPending)
+ {
+ const CApaAppList& list=iAppList;
+ if (!(list.IsFirstScanComplete()))
+ User::Leave(KErrCorrupt);
+
+ iApaAppInfoArray.ResetAndDestroy();
+ for (CApaAppData* appData = list.FirstApp(iAppListScreenMode); appData != NULL; appData = list.NextApp(appData, iAppListScreenMode))
+ {
+ if (iAppListType==EListFilteredEmbeddedApps && (AppIsControlPanelItem(*appData) || !AppMatchesEmbeddabilityFilter(*appData, iEmbeddabilityFilter)))
+ continue;
+
+ if (iAppListType==EListCapabilityAttrFilteredApps && !AppMatchesCapabilityAttrFilter(*appData))
+ continue;
+
+ if (iAppListType==EListServerApps && !appData->ImplementsService(iServiceUid))
+ continue;
+
+ CApaAppInfo* apaAppInfo= new (ELeave)CApaAppInfo();
+ CleanupStack::PushL(apaAppInfo);
+ apaAppInfo->SetCaptionL(appData->Caption());
+ apaAppInfo->SetShortCaptionL(appData->ShortCaption());
+ apaAppInfo->SetFullNameL(appData->AppEntry().iFullName);
+ apaAppInfo->SetUid(appData->AppEntry().iUidType[2]);
+ User::LeaveIfError(iApaAppInfoArray.Append(apaAppInfo));
+ CleanupStack::Pop(apaAppInfo);
+ }
+
+ iFlags &= ~EAppListPopulationPending;
+ }
+
+ if (!iApaAppInfoArray.Count())
+ User::Leave(KErrNotFound);
+
+ TApaAppInfo* info=new(ELeave)TApaAppInfo;
+ CleanupStack::PushL(info);
+ CApaAppInfo* apaAppInfo = iApaAppInfoArray[0];
+ info->iUid = apaAppInfo->Uid();
+ info->iFullName = apaAppInfo->FullName();
+ info->iCaption = apaAppInfo->Caption();
+ // Get the length of the target descriptor
+ TInt targetLen=aMessage.GetDesMaxLength(1);
+ if (targetLen==KApaAppInfoDesMaxLength)
+ info->iShortCaption = apaAppInfo->ShortCaption();
+
+ iApaAppInfoArray.Remove(0);
+ delete apaAppInfo;
+ TPckgC<TApaAppInfo> infoPk(*info);
+ if (targetLen<KApaAppInfoDesMaxLength)
+ infoPk.Set(infoPk.Left(_FOFF(TApaAppInfo,iShortCaption))); // reduce the length of infoPk to the 7.0 size of TApaAppInfo
+
+ aMessage.WriteL(1,infoPk);
+ CleanupStack::PopAndDestroy(info);
+ }
+
+TBool CApaAppListServSession::AppMatchesEmbeddabilityFilter(const CApaAppData& aAppData, const TApaEmbeddabilityFilter& aEmbeddabilityFilter) const
+// returns True if aAppData's embeddability matches the filter set by InitListL
+ {
+ TApaAppCapabilityBuf capabilityBuf;
+ aAppData.Capability(capabilityBuf);
+
+ return (aEmbeddabilityFilter.MatchesEmbeddability(capabilityBuf().iEmbeddability));
+ }
+
+TBool CApaAppListServSession::AppMatchesCapabilityAttrFilter(const CApaAppData& aAppData) const
+// returns True if aAppData's capability attributes match the filter set by InitListL
+ {
+ TApaAppCapabilityBuf capabilityBuf;
+ aAppData.Capability(capabilityBuf);
+ return ((capabilityBuf().iAttributes & iCapabilityAttrFilterMask) == (iCapabilityAttrFilterValue & iCapabilityAttrFilterMask));
+ }
+
+TBool CApaAppListServSession::AppIsControlPanelItem(const CApaAppData& aAppData)
+// returns True if aAppData represents a control panel app
+ {
+ TApaAppCapabilityBuf capabilityBuf;
+ aAppData.Capability(capabilityBuf);
+ return (capabilityBuf().iAttributes & TApaAppCapability::EControlPanelItem);
+ }
+
+/**
+locate app in list, return EFalse if it isn't present
+search is regardless of screen mode.
+@internalComponent
+*/
+TBool CApaAppListServSession::FindAppInList(CApaAppData*& aApp, TApaAppEntry& aEntry, TUid aAppUid)
+ {
+ // Look for the app with aAppUid in the app list we keep
+ const CApaAppList& list = iAppList;
+ aApp = list.AppDataByUid(aAppUid);
+ if (aApp)
+ aEntry = aApp->AppEntry();
+
+ // If the app list is currently in flux, try to nail down the app by looking for it specifically
+ const TBool appPendingOnLangChange = (aApp && list.IsLanguageChangePending() && aApp->IsPending());
+ if ((!aApp || appPendingOnLangChange) && !list.IsIdleUpdateComplete())
+ {
+ // 1. App wasn't found, but an app scan is currently in progress,
+ // so try to find and add the specific app we're looking for to the list
+
+ // 2. On language change event, current app scan could not yet update the found app,
+ // so try to update the specific app we're looking for, in the list.
+ if(aAppUid != KNullUid)
+ {
+ CApaAppData* app = NULL;
+ TRAPD(err, app = FindSpecificAppL(aAppUid));
+ if (!err && app)
+ {
+ // app has been found and added to the app list
+ aApp = app;
+ aEntry = aApp->AppEntry();
+ }
+ }
+ }
+
+ return (aApp != NULL);
+ }
+
+CApaAppData* CApaAppListServSession::FindSpecificAppL(TUid aAppUid)
+ {
+ //Scans the drives and folder lists for the specific app
+ CApaAppRegFinder* regFinder = CApaAppRegFinder::NewLC(iFs);
+ CApaAppData* app = iAppList.FindAndAddSpecificAppL(regFinder, aAppUid);
+ CleanupStack::PopAndDestroy(regFinder);
+ return app;
+ }
+
+void CApaAppListServSession::GetAppInfoL(const RMessage2& aMessage)
+ {
+ // get UID of required app
+ const TUid uid = TUid::Uid(aMessage.Int0());
+ TApaAppInfo* info = new(ELeave) TApaAppInfo; // on heap to avoid running out of stack
+ CleanupStack::PushL(info);
+ GetAppInfoL(uid, *info);
+ TPckgC<TApaAppInfo> infoPk(*info);
+ aMessage.WriteL(1, infoPk);
+ CleanupStack::PopAndDestroy(info);
+ }
+
+void CApaAppListServSession::GetAppCapabilityL(const RMessage2& aMessage)
+ {
+ const TUid uid = TUid::Uid(aMessage.Int1());
+ const CApaAppData& app = FindAppInListL(uid);
+
+ TInt targetLen = aMessage.GetDesMaxLength(0);
+ HBufC8* buf = HBufC8::NewLC(User::LeaveIfError(targetLen));
+ TPtr8 ptr = buf->Des();
+ app.Capability(ptr);
+ ptr.SetLength(targetLen);
+ aMessage.WriteL(0, *buf);
+ CleanupStack::PopAndDestroy(buf);
+ }
+
+void CApaAppListServSession::GetDefaultScreenNumberL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ const CApaAppData& app = FindAppInListL(uid);
+
+ aMessage.Complete(app.DefaultScreenNumber());
+ }
+
+
+void CApaAppListServSession::SetNotify(const RMessage2& aMessage)
+ {
+ if (!iNotifyMessage.IsNull())
+ aMessage.Panic(KApaPanicCli,ENotifierAlreadyPresent);
+ else
+ {
+ const TBool completeImmediatelyIfNoScanImpendingOrInProgress=aMessage.Int0();
+ if ((!completeImmediatelyIfNoScanImpendingOrInProgress) ||
+ iAppArcSrv.AppFsMonitor().AnyNotificationImpending() ||
+ iAppList.AppScanInProgress())
+ iNotifyMessage=aMessage;
+ else
+ aMessage.Complete(KErrNone);
+ }
+ }
+
+void CApaAppArcServSession::NotifyClients(TInt aReason)
+ {
+ iAppListSession->NotifyClients(aReason);
+ }
+
+void CApaAppListServSession::CancelNotify()
+ {
+ NotifyClients(KErrCancel);
+ }
+
+void CApaAppListServSession::NotifyClients(TInt aReason)
+ {
+ if (!iNotifyMessage.IsNull())
+ iNotifyMessage.Complete(aReason);
+
+ //Notify client for scan complete.
+ NotifyScanComplete();
+ }
+
+void CApaAppListServSession::AppInfoProvidedByRegistrationFileL(const RMessage2& aMessage)
+ {
+ // get UID of required app
+ const TUid uid = TUid::Uid(aMessage.Int0());
+
+ // locate app in list
+ const CApaAppData& app = FindAppInListL(uid);
+
+ const TBool registrationFileUsed = app.RegistrationFileUsed();
+ TPckgC<TBool> pckg(registrationFileUsed);
+ aMessage.WriteL(1, pckg);
+ }
+
+void CApaAppListServSession::IconFileNameL(const RMessage2& aMessage)
+ {
+ // get UID of required app
+ const TUid uid=TUid::Uid(aMessage.Int0());
+
+ // locate app in list
+ const CApaAppData& app = FindAppInListL(uid);
+
+ if (!app.RegistrationFileUsed())
+ User::Leave(KErrNotSupported);
+ else
+ {
+ TPtrC iconFileName(app.IconFileName());
+ if (iconFileName.Length() == 0)
+ User::Leave(KErrNotFound);
+ else
+ {
+ TFileName fileName = iconFileName;
+ TPckgC<TFileName> pckg(fileName);
+ aMessage.WriteL(1, pckg);
+ }
+ }
+ }
+
+void CApaAppListServSession::ViewIconFileNameL(const RMessage2& aMessage)
+ {
+ // get UID of required app
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ // get UID of required view
+ const TUid viewUid=TUid::Uid(aMessage.Int1());
+
+ TPtrC viewIconFileName;
+
+ // locate app in list
+ const CApaAppData& app = FindAppInListL(uid);
+
+ if (!app.RegistrationFileUsed())
+ User::Leave(KErrNotSupported);
+ else
+ {
+ const CArrayPtr<CApaAppViewData>& viewDataArray = *app.Views();
+ const TInt count = viewDataArray.Count();
+ for (TInt ii=0; ii<count; ii++)
+ {
+ const CApaAppViewData& appViewData = *viewDataArray[ii];
+ if (appViewData.Uid() == viewUid)
+ {
+ viewIconFileName.Set(appViewData.IconFileName());
+ break;
+ }
+ }
+
+ if (viewIconFileName.Length() == 0)
+ User::Leave(KErrNotFound);
+ else
+ {
+ TFileName fileName = viewIconFileName;
+ TPckgC<TFileName> pckg(fileName);
+ aMessage.WriteL(2, pckg);
+ }
+ }
+ }
+
+void CApaAppArcServSession::GetAppServicesL(const RMessage2& aMessage)
+ {
+ const TInt initialBufSize = aMessage.Int2();
+ if (initialBufSize)
+ {
+ delete iBuffer;
+ iBuffer = NULL;
+ iBuffer = GetServiceBufferL(aMessage);
+ if (iBuffer->Size() > initialBufSize)
+ User::Leave(iBuffer->Ptr(0).Size()); // default buffer provided by client is too small, ask client to provide buffer of correct size
+ }
+ __ASSERT_ALWAYS(iBuffer, aMessage.Panic(KApaPanicCli,EClientBadRequest));
+ aMessage.WriteL(3, iBuffer->Ptr(0));
+ delete iBuffer;
+ iBuffer = NULL;
+ }
+
+CBufBase* CApaAppArcServSession::GetServiceBufferL(const RMessage2& aMessage) const
+ {
+ CBufBase* buffer = NULL;
+ const TUid uid = TUid::Uid(aMessage.Int0());
+ switch (aMessage.Function())
+ {
+ case EAppListServGetAppServices:
+ buffer = iAppListSession->AppList().ServiceArrayBufferL(uid);
+ break;
+ case EAppListServGetServiceImplementations:
+ buffer = iAppListSession->AppList().ServiceImplArrayBufferL(uid);
+ break;
+ case EAppListServGetServiceImplementationsDataType:
+ {
+ TDataType dataType;
+ TPckg<TDataType> dataType_asDescriptor(dataType);
+ aMessage.ReadL(1,dataType_asDescriptor);
+ buffer = iAppListSession->AppList().ServiceImplArrayBufferL(uid, dataType);
+ }
+ break;
+ case EAppListServGetAppServiceUids:
+ buffer = iAppListSession->AppList().ServiceUidBufferL(uid);
+ break;
+ case EAppListServGetAppServiceOpaqueData:
+ buffer = iAppListSession->AppList().ServiceOpaqueDataBufferL(uid, TUid::Uid(aMessage.Int1()));
+ break;
+ default:
+ aMessage.Panic(KApaPanicCli,EClientBadRequest);
+ User::Leave(KErrNotSupported);
+ break;
+ }
+
+ return buffer;
+ }
+
+CApaAppListServSession::CApaAppInfo::CApaAppInfo()
+ :iUid(KNullUid), iCaption(NULL), iShortCaption(NULL), iFullName(NULL)
+ {
+ }
+
+CApaAppListServSession::CApaAppInfo::~CApaAppInfo()
+ {
+ delete iCaption;
+ delete iShortCaption;
+ delete iFullName;
+ }
+
+void CApaAppListServSession::CApaAppInfo::SetUid(const TUid aUid)
+ {
+ iUid=aUid;
+ }
+
+void CApaAppListServSession::CApaAppInfo::SetCaptionL(const TDesC& aCaption)
+ {
+ HBufC* caption = aCaption.AllocL();
+ delete iCaption;
+ iCaption = caption;
+ }
+
+void CApaAppListServSession::CApaAppInfo::SetShortCaptionL(const TDesC& aShortCaption)
+ {
+ HBufC* shortCaption = aShortCaption.AllocL();
+ delete iShortCaption;
+ iShortCaption = shortCaption;
+ }
+
+void CApaAppListServSession::CApaAppInfo::SetFullNameL(const TDesC& aFullName)
+ {
+ HBufC* fullName = aFullName.AllocL();
+ delete iFullName;
+ iFullName = fullName;
+ }
+
+void CApaAppListServSession::RegisterListPopulationCompleteObserver(const RMessage2& aMessage)
+ {
+ if (!iCompletionOfListPopulationObserverMsg.IsNull())
+ aMessage.Panic(KApaPanicCli,EObserverAlreadyPresent);
+ else
+ {
+ if(iAppList.IsFirstScanComplete())
+ aMessage.Complete(KErrNone);
+ else
+ iCompletionOfListPopulationObserverMsg=aMessage;
+ }
+ }
+
+void CApaAppArcServSession::NotifyClientForCompletionOfListPopulation()
+ {
+ iAppListSession->NotifyClientForCompletionOfListPopulation();
+ }
+
+void CApaAppListServSession::NotifyClientForCompletionOfListPopulation()
+ {
+ if (!iCompletionOfListPopulationObserverMsg.IsNull())
+ iCompletionOfListPopulationObserverMsg.Complete(KErrNone);
+ } //lint !e1762 Suppress member function could be made const
+
+
+void CApaAppListServSession::CancelListPopulationCompleteObserver()
+ {
+ if (!iCompletionOfListPopulationObserverMsg.IsNull())
+ iCompletionOfListPopulationObserverMsg.Complete(KErrCancel);
+ } //lint !e1762 Suppress member function could be made const
+
+void CApaAppArcServSession::NotifyClientOfDataMappingChange()
+ {
+ if (!iMessage_NotifyOnDataMappingChange.IsNull())
+ iMessage_NotifyOnDataMappingChange.Complete(KErrNone);
+ } //lint !e1762 Suppress member function could be made const
+
+void CApaAppListServSession::MatchesSecurityPolicyL(const RMessage2& aMessage)
+ {
+ const TUid appUid=TUid::Uid(aMessage.Int0());
+ TApaAppInfo* const appInfo=new(ELeave) TApaAppInfo;
+ CleanupStack::PushL(appInfo);
+ //Get the app info for the given App uid.
+ GetAppInfoL(appUid, *appInfo);
+ const TPtrC executableName(appInfo->iFullName);
+ //Create a process only if the executable name is of non zero length
+ if (executableName.Length() != 0)
+ {
+ RProcess process;
+ TInt result = process.Create(executableName, KNullDesC);
+ //Proceed with checking the security policy if the process is created normally
+ if (result == KErrNone)
+ {
+ TPckgBuf<TSecurityPolicy> securityPolicy;
+ aMessage.ReadL(1,securityPolicy);
+ aMessage.Complete(securityPolicy().CheckPolicy(process));
+ process.Close();
+ }
+ else
+ aMessage.Complete(result);
+ }
+ else
+ aMessage.Complete(KErrNotFound);
+
+ CleanupStack::PopAndDestroy(appInfo);
+ }
+
+void CApaAppListServSession::SetAppShortCaptionL(const RMessage2& aMessage)
+ {
+ const TUid uid=TUid::Uid(aMessage.Int0());
+ CApaAppData* app=NULL;
+ TApaAppEntry entry;
+ if (!FindAppInList(app,entry,uid))
+ User::Leave(KErrNotFound);
+
+ const TInt length = aMessage.GetDesLength(1);
+ if(length < 0)
+ User::Leave(length);
+
+ HBufC* const shortCaption = HBufC::NewLC(length);
+ TPtr captionPtr(shortCaption->Des());
+ aMessage.ReadL(1, captionPtr);
+
+ TLanguage appLanguage = TLanguage(aMessage.Int2());
+ iAppList.AddCustomAppInfoInListL(uid, appLanguage, *shortCaption);
+ if(app->ApplicationLanguage() == appLanguage)
+ app->SetShortCaptionL(*shortCaption);
+ else if(appLanguage==ELangNone)
+ iAppList.UpdateAppListByShortCaptionL();
+
+ CleanupStack::PopAndDestroy(shortCaption);
+ }
+
+
+void CApaAppArcServSession::NotifyScanComplete()
+ {
+ iAppListSession->NotifyScanComplete();
+ }
+
+void CApaAppListServSession::NotifyScanComplete()
+ {
+ //See if the session is intrested in scan complete notification.
+ if (!iNotifyOnScanCompleteMsg.IsNull())
+ {
+ iNotifyOnScanCompleteMsg.Complete(KErrNone);
+ }
+ iNonNativeApplicationsManager->NotifyScanComplete();
+ } //lint !e1762 Suppress member function could be made const
+
+// TSizeArrayItemWriter
+
+TInt TSizeArrayItemWriter::ArrayItemCount() const
+ {
+ return iArray.Count();
+ }
+
+TInt TSizeArrayItemWriter::ArrayItemSize() const
+ {
+ return sizeof(TSize);
+ }
+
+void TSizeArrayItemWriter::WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const
+ {
+ const TSize& size = iArray[aIndex];
+ aWriteStream.WriteUint32L(size.iWidth);
+ aWriteStream.WriteUint32L(size.iHeight);
+ }
+
+// TViewDataArrayItemWriter
+
+TInt TViewDataArrayItemWriter::ArrayItemCount() const
+ {
+ return iArray.Count();
+ }
+
+TInt TViewDataArrayItemWriter::ArrayItemSize() const
+ {
+ return sizeof(TApaAppViewInfo);
+ }
+
+void TViewDataArrayItemWriter::WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const
+ {
+ const CApaAppViewData& appViewData=*(iArray[aIndex]);
+ aWriteStream << TApaAppViewInfo(appViewData.Uid(),appViewData.Caption(),appViewData.ScreenMode());
+ }
+
+// TDesCArrayItemWriter
+
+TInt TDesCArrayItemWriter::ArrayItemCount() const
+ {
+ return iArray.Count();
+ }
+
+TInt TDesCArrayItemWriter::ArrayItemSize() const
+ {
+ return sizeof(TFileName);
+ }
+
+void TDesCArrayItemWriter::WriteArrayItemL(RWriteStream& aWriteStream,TInt aIndex) const
+ {
+ aWriteStream << iArray[aIndex];
+ }
+