/*
* Copyright (c) 2010 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:
*
*/
#include "applicationsplugin.h"
#include "harvesterserverlogger.h"
#include <common.h>
#include <ccpixindexer.h>
#include <csearchdocument.h>
#include <e32base.h>
//#include <menu2internalcrkeys.h> //for KCRUidMenu
#include <widgetpropertyvalue.h> // EBundleDisplayName
#include <centralrepository.h>
//Hidden applications
//#define KHiddenAppRepositoryUid KCRUidMenu
_LIT( KMimeTypeField, CPIX_MIMETYPE_FIELD );
_LIT( KMimeTypeApplication, APPLICATION_MIMETYPE);
/** Field names */
_LIT(KApplicationFieldCaption, "Name");
_LIT(KApplicationFieldUid, "Uid");
_LIT(KApplicationFieldAbsolutePath, "Path");
// TAppInfo.Name() returns [121345678]. The below constants are used to extract '[' & ']'
const TInt KUidStartIndex = 1;
const TInt KUidEndIndex = 8;
/** The delay between harvesting chunks. */
const TInt KHarvestingDelay = 1000;
// -----------------------------------------------------------------------------
CApplicationsPlugin* CApplicationsPlugin::NewL()
{
CPIXLOGSTRING("CApplicationsPlugin::NewL()");
CApplicationsPlugin* instance = CApplicationsPlugin::NewLC();
CleanupStack::Pop(instance);
return instance;
}
// -----------------------------------------------------------------------------
CApplicationsPlugin* CApplicationsPlugin::NewLC()
{
CApplicationsPlugin* instance = new (ELeave) CApplicationsPlugin();
CleanupStack::PushL(instance);
instance->ConstructL();
return instance;
}
// -----------------------------------------------------------------------------
CApplicationsPlugin::CApplicationsPlugin()
{
}
// -----------------------------------------------------------------------------
CApplicationsPlugin::~CApplicationsPlugin()
{
if (iAsynchronizer)
iAsynchronizer->CancelCallback();
iApplicationServerSession.Close();
iWidgetRegistry.Close();
//delete iHiddenApplicationsRepository;
delete iAsynchronizer;
delete iNotifier;
delete iIndexer;
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::ConstructL()
{
iAsynchronizer = CDelayedCallback::NewL( CActive::EPriorityIdle );
iNotifier = CApaAppListNotifier::NewL( this, CActive::EPriorityHigh );
//iHiddenApplicationsRepository = CRepository::NewL( KHiddenAppRepositoryUid );
User::LeaveIfError( iWidgetRegistry.Connect() );
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::StartPluginL()
{
User::LeaveIfError( iApplicationServerSession.Connect() );
User::LeaveIfError(iSearchSession.DefineVolume( _L(APPLICATIONS_QBASEAPPCLASS), KNullDesC ));
// Open database
iIndexer = CCPixIndexer::NewL(iSearchSession);
iIndexer->OpenDatabaseL( _L(APPLICATIONS_QBASEAPPCLASS) );
// Start harvester for this plugin
iObserver->AddHarvestingQueue( this, iIndexer->GetBaseAppClass() );
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::StartHarvestingL(const TDesC& /* aQualifiedBaseAppClass */)
{
// Harvest items on each call
User::LeaveIfError( iApplicationServerSession.GetAllApps() );//if not KErrNone
iIndexer->ResetL();
//No need to check IsStatred() since this is the first start.
#ifdef __PERFORMANCE_DATA
iStartTime.UniversalTime();
#endif
iAsynchronizer->Start( 0, this, KHarvestingDelay );
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::AddWidgetInfoL( CSearchDocument* aDocument, TUid aUid )
{
TBuf<KMaxFileName> temp;//we can reuse this.
iWidgetRegistry.GetWidgetPath( aUid, temp );
aDocument->AddFieldL(KApplicationFieldAbsolutePath, temp, CDocumentField::EStoreYes | CDocumentField::EIndexTokenized );
CPIXLOGSTRING2("AddApplicationInfo(): PATH = %S ", &temp);
//GetWidgetPropertyValueL returns CWidgetPropertyValue* which in turn has an operator to convert to TDesC
aDocument->AddFieldL(KApplicationFieldCaption, *(iWidgetRegistry.GetWidgetPropertyValueL( aUid, EBundleDisplayName )), CDocumentField::EStoreYes | CDocumentField::EIndexTokenized );
iWidgetRegistry.GetWidgetBundleName( aUid, temp );
aDocument->AddExcerptL( temp );
CPIXLOGSTRING2("AddApplicationInfo(): DisplayName = %S ", &temp );
}
// -----------------------------------------------------------------------------
//This need not be a member function.
void AddApplicationInfoL( CSearchDocument* aDocument, TApaAppInfo& aAppInfo )
{
TBuf<KMaxFileName> docidString = aAppInfo.iUid.Name(); //This returns stuff in the form "[UID]". So remove the brackets.
docidString = docidString.Mid( KUidStartIndex, KUidEndIndex );
aDocument->AddFieldL(KApplicationFieldCaption, aAppInfo.iShortCaption, CDocumentField::EStoreYes | CDocumentField::EIndexTokenized );
aDocument->AddFieldL(KApplicationFieldAbsolutePath, aAppInfo.iFullName, CDocumentField::EStoreYes | CDocumentField::EIndexTokenized );
aDocument->AddExcerptL( aAppInfo.iCaption );
CPIXLOGSTRING3("AddApplicationInfo(): UID = %S, PATH = %S ", &docidString, &aAppInfo.iFullName );
CPIXLOGSTRING3("AddApplicationInfo(): Excerpt = %S, Caption = %S ", &aAppInfo.iCaption, &aAppInfo.iShortCaption );
}
// -----------------------------------------------------------------------------
TBool CApplicationsPlugin::IsAppHiddenL(TUid aUid)
{
//Application should not have 'hidden' capability.
TBool ret( EFalse );
TApaAppCapabilityBuf cap;
CPIXLOGSTRING2("CApplicationsPlugin::IsAppHidden(): UID = %d", aUid );
if ( iApplicationServerSession.GetAppCapability(cap, aUid) == KErrNone )
{
CPIXLOGSTRING("CApplicationsPlugin::IsAppHidden(): GetCapability returned KErrNone");
ret = cap().iAppIsHidden;
}
//Application should not be listed hidden in application shell.
// TBuf<NCentralRepositoryConstants::KMaxUnicodeStringLength> uidResult;
// if( iHiddenApplicationsRepository->Get( KMenuHideApplication, uidResult ) == KErrNone )
// {
// CPIXLOGSTRING2("CApplicationsPlugin::CreateApplicationsIndexItemL(): Hidden UIDs = %S", &uidResult );
// TBufC16<NCentralRepositoryConstants::KMaxUnicodeStringLength> buf(uidResult);
// HBufC* uidString = buf.AllocLC();
// //If not in the list, it means it is hidden; so dont harvest
// if( uidString->FindF( aUid.Name().Mid( KUidStartIndex, KUidEndIndex ) ) != KErrNotFound )
// {
// CleanupStack::PopAndDestroy( uidString );
// CPIXLOGSTRING("CApplicationsPlugin::IsAppHidden(): UID in hidden app repository");
// return EFalse;
// }
// CleanupStack::PopAndDestroy( uidString );
// }
CPIXLOGSTRING2("CApplicationsPlugin::IsAppHidden(): %d", &ret);
return ret;
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::CreateApplicationsIndexItemL( TApaAppInfo& aAppInfo, TCPixActionType /*aActionType*/ )
{
//If application has 'hidden' capability, don't index.
if( IsAppHiddenL( aAppInfo.iUid ) ) return;
TBuf<KMaxFileName> docidString;
docidString.Append( aAppInfo.iUid.Name() ); //This returns descriptor in the form "[UID]". So remove the brackets.
docidString = docidString.Mid( KUidStartIndex, KUidEndIndex );
CSearchDocument* document = CSearchDocument::NewLC( docidString, _L(APPLICATIONS_APPCLASS) );
document->AddFieldL(KMimeTypeField, KMimeTypeApplication, CDocumentField::EStoreYes | CDocumentField::EIndexUnTokenized );
document->AddFieldL(KApplicationFieldUid, docidString, CDocumentField::EStoreYes | CDocumentField::EIndexTokenized );
if( iWidgetRegistry.IsWidget( aAppInfo.iUid ) )
AddWidgetInfoL( document, aAppInfo.iUid );
else
AddApplicationInfoL( document, aAppInfo );
TRAPD( error, iIndexer->AddL( *document ) );
if( KErrNone == error )
{
CPIXLOGSTRING("CApplicationsPlugin::CreateApplicationsIndexItemL(): No Error" );
}
else
{
CPIXLOGSTRING2("CApplicationsPlugin::CreateApplicationsIndexItemL(): Error = %d", error );
}
CleanupStack::PopAndDestroy( document );
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::DelayedCallbackL( TInt /*aCode*/ )
{
TApaAppInfo appInfo;
const TInt error = iApplicationServerSession.GetNextApp( appInfo );
if( error == KErrNone )
{
CreateApplicationsIndexItemL( appInfo, ECPixAddAction );
}
if ( error != RApaLsSession::ENoMoreAppsInList )
{
//No need to check IsStatred() since control reaches
//here only on asynchornize complete.
iAsynchronizer->Start( 0, this, KHarvestingDelay );
}
else
{
Flush( *iIndexer );
#ifdef __PERFORMANCE_DATA
UpdatePerformaceDataL();
#endif
iObserver->HarvestingCompleted( this, iIndexer->GetBaseAppClass(), KErrNone );
}
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::DelayedError( TInt aCode )
{
Flush(*iIndexer);
iObserver->HarvestingCompleted(this, iIndexer->GetBaseAppClass(), aCode);
}
// -----------------------------------------------------------------------------
void CApplicationsPlugin::HandleAppListEvent( TInt aEvent )
{
CPIXLOGSTRING2("CApplicationsPlugin::HandleAppListEvent: Start with Event = %d", aEvent );
if( aEvent == EAppListChanged )
{
if( iAsynchronizer->CallbackPending() )
{
iAsynchronizer->CancelCallback(); //first cancel any ongoing harvesting.
}
TRAP_IGNORE( StartHarvestingL( KNullDesC ) ); //simply reharvest
}
CPIXLOGSTRING("CApplicationsPlugin::HandleAppListEvent: Exit" );
}
#ifdef __PERFORMANCE_DATA
void CApplicationsPlugin::UpdatePerformaceDataL()
{
TTime now;
iCompleteTime.UniversalTime();
TTimeIntervalMicroSeconds timeDiff = iCompleteTime.MicroSecondsFrom(iStartTime);
RFs fileSession;
RFile perfFile;
User::LeaveIfError( fileSession.Connect () );
/* Open file if it exists, otherwise create it and write content in it */
if(perfFile.Open(fileSession, _L("c:\\data\\ApplicationsPerf.txt"), EFileWrite))
User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\ApplicationsPerf.txt"), EFileWrite));
HBufC8 *heap = HBufC8::NewL(100);
TPtr8 ptr = heap->Des();
now.HomeTime();
TBuf<50> timeString;
_LIT(KOwnTimeFormat,"%:0%H%:1%T%:2%S");
now.FormatL(timeString,KOwnTimeFormat);
ptr.AppendNum(now.DateTime().Day());
ptr.Append(_L("/"));
ptr.AppendNum(now.DateTime().Month());
ptr.Append(_L("/"));
ptr.AppendNum(now.DateTime().Year());
ptr.Append(_L(":"));
ptr.Append(timeString);
ptr.Append( _L(": Ani: Time took for Harvesting Applications is : "));
ptr.AppendNum(timeDiff.Int64()/1000) ;
ptr.Append(_L(" MilliSeonds \n"));
TInt myInt = 0;
perfFile.Seek(ESeekEnd,myInt);
perfFile.Write (ptr);
perfFile.Close ();
fileSession.Close ();
delete heap;
}
#endif
// End of file