--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/idlefw/plugins/profileplugin/src/caiprofileplugin.cpp Thu Dec 17 08:54:17 2009 +0200
@@ -0,0 +1,509 @@
+/*
+* Copyright (c) 2005-2007 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: Profile plug-in publisher
+*
+*/
+
+
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include <aicontentobserver.h>
+#include <aiutility.h>
+#include <PUAcodes.hrh>
+#include <AknUtils.h>
+
+#include "aiprofileplugincontentmodel.h"
+#include <aiprofilepluginuids.hrh>
+#include "caiprofileplugin.h"
+#include "caiprofileengine.h"
+#include "aipluginsettings.h"
+
+// PUA code for the timed profile, missing from PUAcodes.hrh
+#define KAiTimedProfilePUA 0xF815
+#define KAiRTL 0x200F
+
+// CONST CLASS VARIABLES
+const TImplementationProxy KImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY( KImplUidProfilePlugin, CAiProfilePlugin::NewL )
+ };
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave
+// ---------------------------------------------------------------------------
+//
+CAiProfilePlugin* CAiProfilePlugin::NewL()
+ {
+ CAiProfilePlugin* self = new (ELeave) CAiProfilePlugin;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CAiProfilePlugin::CAiProfilePlugin()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::ConstructL()
+ {
+ iInfo.iUid.iUid = AI_UID_ECOM_IMPLEMENTATION_CONTENTPUBLISHER_PROFILEPLUGIN;
+
+ iContent = AiUtility::CreateContentItemArrayIteratorL( KAiProfileContent );
+ iEvents = AiUtility::CreateContentItemArrayIteratorL( KAiProfileEvents );
+ iResources = AiUtility::CreateContentItemArrayIteratorL( KAiProfileResources );
+
+ iIsUpdated = ETrue;
+ iAlive = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// Deletes all data created to heap
+// ---------------------------------------------------------------------------
+//
+CAiProfilePlugin::~CAiProfilePlugin()
+ {
+ CleanPublishedProfileNames();
+ Release( iContent );
+ Release( iEvents );
+ Release( iResources );
+ delete iActiveProfileAndChar;
+ delete iPreviousProfileNameAndChar;
+ delete iEngine;
+ iObservers.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Publishes the profiles
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::PublishL()
+ {
+ TInt err( KErrNone );
+ TInt observers( iObservers.Count() );
+ TInt transactionId = reinterpret_cast<TInt>( this );
+
+ iCurrentCount = iEngine->NumberOfProfiles();
+ for ( int i = 0; i < observers; i++ )
+ {
+ MAiContentObserver* observer = iObservers[i];
+ err = observer->StartTransaction( transactionId );
+
+ if ( err == KErrNotSupported )
+ {
+ // The observer does not support transactions, check for real errors.
+ return;
+ }
+
+ //Active Profile name
+ if ( observer->CanPublish( *this, EAiProfileContentActiveProfileName, EAiProfileContentActiveProfileName ) )
+ {
+ observer->Publish( *this, EAiProfileContentActiveProfileName, iEngine->ActiveProfileName(), EAiProfileContentActiveProfileName );
+ }
+
+ if ( observer->CanPublish( *this, EAiProfileActiveProfileNameAndIconChar, 0 ) )
+ {
+ delete iActiveProfileAndChar;
+ iActiveProfileAndChar = NULL;
+ // silent/non-silent icon + timed icon + space + possible RTL*2 = 5
+ TInt maxChars = iEngine->ActiveProfileName().Length() + 5;
+
+ iActiveProfileAndChar = HBufC::NewL( maxChars );
+ TPtr profileNamePtr = iActiveProfileAndChar->Des();
+
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ profileNamePtr.Append( KAiRTL );
+ }
+
+ if ( iEngine->IsActiveProfileTimedL() )
+ {
+ profileNamePtr.Append( KAiTimedProfilePUA );
+ }
+ if( iEngine->IsActiveProfileSilentL() )
+ {
+ profileNamePtr.Append( KPuaCodeSilentSymbol );
+ }
+ else
+ {
+ profileNamePtr.Append( KPuaCodeAprofSound );
+ }
+ _LIT( KSpace, " " );
+ profileNamePtr.Append( KSpace );
+
+ if( AknLayoutUtils::LayoutMirrored() )
+ {
+ profileNamePtr.Append( KAiRTL );
+ }
+
+ profileNamePtr.Append( iEngine->ActiveProfileName() );
+
+ if ( !iPreviousProfileNameAndChar ||
+ iPreviousProfileNameAndChar->CompareC( *iActiveProfileAndChar ) != 0 )
+ {
+ delete iPreviousProfileNameAndChar;
+ iPreviousProfileNameAndChar = NULL;
+ observer->Publish( *this, EAiProfileActiveProfileNameAndIconChar, profileNamePtr, 0 );
+
+ iPreviousProfileNameAndChar = iActiveProfileAndChar->AllocL();
+ }
+ }
+
+ //Swap Profile name ( 1.phase: General or Silent )
+ if ( observer->CanPublish( *this, EAiProfileContentSwapProfileName, EAiProfileContentSwapProfileName ) )
+ {
+ observer->Publish( *this, EAiProfileContentSwapProfileName, iEngine->SwapProfileName(), EAiProfileContentSwapProfileName );
+ }
+
+ //All profile names
+ // clean profiles that are already deleted.
+ // Cleans the array blindly from the end, because in the next
+ // step all the profiles are republished
+ if( iPreviousCount > iCurrentCount )
+ {
+ for( TInt k = iCurrentCount; k < iPreviousCount; k++ )
+ {
+ observer->Clean( *this, EAiProfileContentProfileName, k + 1 );
+ }
+ }
+ for ( TInt j = 0; j < iCurrentCount; j++ )
+ {
+ if ( observer->CanPublish( *this, EAiProfileContentProfileName, j + 1 ) )
+ {
+ observer->Publish(*this, EAiProfileContentProfileName, iEngine->ProfileNameByIndex( j ), j + 1 );
+ }
+ }
+
+ //Active Profile silent indicator char
+ if ( observer->CanPublish( *this, EAiProfileActiveProfileSilentChar, EAiProfileActiveProfileSilentChar ) )
+ {
+ if ( iEngine->IsActiveProfileSilentL() )
+ {
+ TBuf<1> silent; // one character
+ silent.Append( KPuaCodeSilentSymbol );
+ observer->Publish( *this, EAiProfileActiveProfileSilentChar, silent, EAiProfileActiveProfileSilentChar );
+ }
+ else
+ {
+ observer->Clean( *this, EAiProfileActiveProfileSilentChar, EAiProfileActiveProfileSilentChar );
+ }
+ }
+
+ //Active Profile silent indicator resource
+ if ( observer->CanPublish( *this, EAiProfileActiveProfileIcon, EAiProfileActiveProfileIcon ) )
+ {
+ observer->Clean( *this, EAiProfileActiveProfileIcon, EAiProfileActiveProfileSilentIconResource );
+ observer->Clean( *this, EAiProfileActiveProfileIcon, EAiProfileActiveProfileGeneralIconResource );
+ observer->Clean( *this, EAiProfileActiveProfileIcon, EAiProfileActiveProfileTimedIconResource );
+ if ( iEngine->IsActiveProfileTimedL() )
+ {
+ observer->Publish( *this,
+ EAiProfileActiveProfileIcon,
+ EAiProfileActiveProfileTimedIconResource,
+ EAiProfileActiveProfileTimedIconResource );
+ }
+ else if ( iEngine->IsActiveProfileSilentL() )
+ {
+ observer->Publish( *this,
+ EAiProfileActiveProfileIcon,
+ EAiProfileActiveProfileSilentIconResource,
+ EAiProfileActiveProfileSilentIconResource );
+ }
+ else
+ {
+ observer->Publish( *this,
+ EAiProfileActiveProfileIcon,
+ EAiProfileActiveProfileGeneralIconResource,
+ EAiProfileActiveProfileGeneralIconResource );
+ }
+ }
+
+ // in case of Offline profile profile indicator is not shown
+ if ( observer->CanPublish( *this, EAiProfileContentActiveProfileName, EAiProfileContentActiveProfileName ) &&
+ iEngine->IsOffline() )
+ {
+ observer->Clean( *this, EAiProfileActiveProfileSilentChar, EAiProfileActiveProfileSilentChar );
+ observer->Clean( *this, EAiProfileActiveProfileIcon, 1 );
+ observer->Clean( *this, EAiProfileActiveProfileIcon, 2 );
+ // uncomment also this and respective policy lines in profiles.xml if whole widget needs to be hidden in AI3
+ //observer->Clean( *this, EAiProfileContentActiveProfileName, EAiProfileContentActiveProfileName );
+ }
+ if ( err == KErrNone )
+ {
+ err = observer->Commit( transactionId );
+
+ if ( err == KErrNotSupported)
+ {
+ return;
+ }
+ }
+
+ iIsUpdated = EFalse;
+ }
+ iPreviousCount = iCurrentCount;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// Plug-in is requested to unload its engines due backup operation
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::Stop( TAiTransitionReason /*aReason*/ )
+ {
+ FreeEngine();
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// Plug-in is instructed that it is allowed to consume CPU resources
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::Resume( TAiTransitionReason aReason )
+ {
+ TRAP_IGNORE( DoResumeL( aReason ) );
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// Plug-in is instructed that it is not allowed to consume CPU resources
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::Suspend( TAiTransitionReason /*aReason*/ )
+ {
+ if ( iEngine && iAlive )
+ {
+ iEngine->Suspend();
+ }
+
+ iAlive = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// The plug-in MUST maintain a registry of subscribers and send
+// notification to all of them whenever the state changes or new content
+// is available
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::SubscribeL( MAiContentObserver& aObserver )
+ {
+ iObservers.AppendL( &aObserver );
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// Plug-ins take ownership of the settings array, so it must either
+// store it in a member or free it.
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::ConfigureL( RAiSettingsItemArray& aSettings )
+ {
+ aSettings.ResetAndDestroy();
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// Returns the extension interface. Actual type depends on the passed
+// aUid argument.
+// ---------------------------------------------------------------------------
+//
+TAny* CAiProfilePlugin::Extension( TUid aUid )
+ {
+ if (aUid == KExtensionUidProperty)
+ {
+ return static_cast<MAiPropertyExtension*>(this);
+ }
+ else if (aUid == KExtensionUidEventHandler)
+ {
+ return static_cast<MAiEventHandlerExtension*>(this);
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MAiPropertyExtension
+// Read property of publisher plug-in.
+// ---------------------------------------------------------------------------
+//
+TAny* CAiProfilePlugin::GetPropertyL( TInt aProperty )
+ {
+ TAny* property = NULL;
+
+ switch ( aProperty )
+ {
+ case EAiPublisherInfo:
+ {
+ property = static_cast<TAiPublisherInfo*>( &iInfo );
+ break;
+ }
+
+ case EAiPublisherContent:
+ {
+ property = static_cast<MAiContentItemIterator*>( iContent );
+ break;
+ }
+
+ case EAiPublisherEvents:
+ {
+ property = static_cast<MAiContentItemIterator*>( iEvents );
+ break;
+ }
+
+ case EAiPublisherResources:
+ property = static_cast<MAiContentItemIterator*>( iResources );
+ break;
+
+ default:
+ break;
+ }
+
+ return property;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MAiPropertyExtension
+// Write property value to optimize the content model.
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::SetPropertyL( TInt aProperty, TAny* aValue )
+ {
+ if( aProperty == EAiPublisherInfo )
+ {
+ ASSERT( aValue );
+
+ const TAiPublisherInfo* info(
+ static_cast<const TAiPublisherInfo*>( aValue ) );
+
+ iInfo = *info;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// From class MAiEventHandlerExtension.
+// Handles an event sent by the AI framework.
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::HandleEvent(TInt aEvent, const TDesC& aParam)
+ {
+ if ( iEngine )
+ {
+ // We have no way of reporting errors to framework so just ignore them.
+ TRAP_IGNORE( iEngine->HandleAiEventL( aEvent, aParam ) );
+ }
+ }
+
+// ---------------------------------------------------------
+// This method is called from the engine, when the profile
+// data content has been changed. Method call is made through
+// the MAiProfilePluginNotifier interface.
+// ---------------------------------------------------------
+//
+void CAiProfilePlugin::NotifyContentUpdate()
+ {
+ iIsUpdated = ETrue;
+
+ TRAP_IGNORE( PublishL() );
+ }
+
+// ---------------------------------------------------------------------------
+// From class CAiContentPublisher
+// framework instructs plug-in that it is allowed to consume CPU resources
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::DoResumeL( TAiTransitionReason aReason )
+ {
+ if ( !iEngine )
+ {
+ iEngine = CAiProfileEngine::NewL( this );
+ }
+
+ //update in startup phase and idle is on foreground.
+ if( aReason != EAiBacklightOff && aReason != EAiIdleBackground )
+ {
+ // force republish in case layout has changed
+ if ( aReason == EAiScreenLayoutChanged )
+ {
+ delete iPreviousProfileNameAndChar;
+ iPreviousProfileNameAndChar = NULL;
+ }
+
+ if ( !iAlive )
+ {
+ iEngine->ResumeL();
+ }
+
+ iEngine->UpdateProfileNamesL();
+
+ PublishL();
+ iAlive = ETrue;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Frees engine resources
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::FreeEngine()
+ {
+ delete iEngine;
+ iEngine = NULL;
+ iAlive = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// Clean profile names from content
+// ---------------------------------------------------------------------------
+//
+void CAiProfilePlugin::CleanPublishedProfileNames()
+ {
+ TInt obsCount( iObservers.Count() );
+ for ( TInt i( 0 ); i < obsCount; i++ )
+ {
+ MAiContentObserver* observer = iObservers[i];
+ for( TInt j( 0 ); j < iCurrentCount && observer; j++ )
+ {
+ observer->Clean( *this, EAiProfileContentProfileName, j + 1 );
+ }
+ }
+ }
+
+// ======== GLOBAL FUNCTIONS ========
+// ---------------------------------------------------------------------------
+// Constructs and returns an application object.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(
+ TInt& aTableCount )
+ {
+ aTableCount = sizeof( KImplementationTable ) /
+ sizeof( TImplementationProxy );
+ return KImplementationTable;
+ }