diff -r 000000000000 -r ff3b6d0fd310 cbs/CbsServer/ServerSrc/CCbsReceiverHelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbs/CbsServer/ServerSrc/CCbsReceiverHelper.cpp Tue Feb 02 01:11:09 2010 +0200 @@ -0,0 +1,899 @@ +/* +* Copyright (c) 2003-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: This module contains the implementation of CCbsReceiverHelper class +* member functions. +* +* CCbsReceiverHelper gets the messages from the receiver and +* sends them to the database. All received messages are +* sent to CCbsReceiverHelper instance by CCbsRecEtel. +* This class makes subscription and existence checks +* to these messages and also implements topic detection feature. +* +*/ + + +// INCLUDE FILES +#include // Resource access +#include // Resource access + +#include + +#include "CbsCommon.h" +#include "CbsUtils.h" +#include "CbsServerPanic.h" +#include "CCbsServer.h" +#include "CCbsReceiverHelper.h" +#include "CCbsDbImp.H" +#include "CCbsDbImpSettings.H" +#include "CCbsDbImpTopicList.h" +#include "CCbsDbImpTopicMessages.h" +#include "CCbsDbImpTopicCollection.h" +#include "CCbsRecMessage.h" +#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS +#include // View server access +#else +#include +#endif +#include // ECellBroadcastNotification +#include // Soft Notification API +#include +#include +#include + +#include +#include "CbsLogger.h" + +#include // for local variation +#include "cbsinternalcrkeys.h" // for local variation +#include "cbsvariant.hrh" // for local variation + +// CONSTANTS + +// UID of CBS UI application +#define KUidCbsUiappDef 0x101F4CD3 +const TUid KUidCbsUiappApp = { KUidCbsUiappDef }; + +const TInt KCbsImmediateMessageIdInt = 313; +const TUid KCbsImmediateMessageId = { KCbsImmediateMessageIdInt }; + +const TInt KCbsMessageTone = 2; // See SharedDataKeysVariant.h or NcnListInternalPSKeys.h + +// DATA TYPES +// CbsUi application view ID's +enum TCbsUiViewIds + { + ECbsUiTopicViewId = 1, + ECbsUiTopicListViewId, + ECbsUiListAppColumnViewId, + ECbsUiMsgViewId, //message view id + ECbsUiAddFromIndexViewId, + ECbsUiSettingsViewId + }; + +// These values specify a range of accepted topic number values (inclusive). +const TUint KMinTopicNumber = 1; // 000 is not accepted. +const TUint KMaxTopicNumber = 999; + +// LOCAL FUNCTION PROTOTYPES +LOCAL_C void ParseMessageFormatL( + TLex& aLex, CCbsDbImpTopicCollection& aCollection ); +LOCAL_C void ParseIndexElementIntroL( + TLex& aLex, CCbsDbImpTopicCollection& aCollection ); +LOCAL_C void ParseServiceIntroL( + TLex& aLex, CCbsDbImpTopicCollection& aCollection ); +LOCAL_C void ParseMessageIdL( + TLex& aLex, TUint& aMessageId ); +LOCAL_C void ParseSubIndexIntroL( + TLex& aLex ); +LOCAL_C void ParseSubIndexIdL( + TLex& aLex ); +LOCAL_C void ParseNameCharactersCrLfL( + TLex& aLex, TPtrC& aName ); + +// ==================== LOCAL FUNCTIONS ==================== + +// ----------------------------------------------------------------------------- +// ParseMessageFormatL +// Parses an index message. +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseMessageFormatL( + TLex& aLex, + CCbsDbImpTopicCollection& aCollection ) + { + TInt identitiesCount( 0 ); + while ( !aLex.Eos() ) + { + ParseIndexElementIntroL( aLex, aCollection ); + identitiesCount++; + } + + if ( identitiesCount == 0 ) + { + User::Leave( KErrCorrupt ); + } + } + +// ----------------------------------------------------------------------------- +// ParseIndexElementIntroL +// Parses part of an index message. +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseIndexElementIntroL( + TLex& aLex, + CCbsDbImpTopicCollection& aCollection ) + { + TBool hasSubIndexId( EFalse ); + + // subindex-id (optional for service-intro) + if ( aLex.Peek().IsAlpha() ) + { + hasSubIndexId = ETrue; + ParseSubIndexIdL( aLex ); + } + + // subindex-intro | service-intro + // We'll take a peek to discover, which one + if ( hasSubIndexId && aLex.Peek() == EKeySpace ) + { + ParseSubIndexIntroL( aLex ); + } + else + { + ParseServiceIntroL( aLex, aCollection ); + } + } + +// ----------------------------------------------------------------------------- +// ParseServiceIntroL +// Parses part of an index message. +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseServiceIntroL( + TLex& aLex, + CCbsDbImpTopicCollection& aCollection ) + { + // We'll store the results here + TCbsDbTopicIdentity identity; + + // message-id + TUint messageId; + ParseMessageIdL( aLex, messageId ); + identity.iNumber = TUint16( messageId ); + + // delimeter + TChar delimeter( aLex.Get() ); + if ( delimeter != ' ' && delimeter != '.' ) + { + User::Leave( KErrCorrupt ); + } + + // service-name + TPtrC serviceName; + ParseNameCharactersCrLfL( aLex, serviceName ); + // drop crlf + serviceName.Set( serviceName.Left( serviceName.Length()-2 ) ); + + // If the delimeter is ' ', store the identity. Otherwise + // it only refers to a subindex page, so we skip it + if ( delimeter == ' ' ) + { + // Copy max. KCbsDbTopicNameLength characters + identity.iName = serviceName.Left( KCbsDbTopicNameLength ); + // Store the topic identity into the database + aCollection.AddTopicIdentityL( identity ); + } + } + +// ----------------------------------------------------------------------------- +// ParseMessageIdL +// Parses part of an index message. +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseMessageIdL( + TLex& aLex, + TUint& aMessageId ) + { + if ( aLex.Val( aMessageId ) != KErrNone + || aMessageId < KMinTopicNumber + || aMessageId > KMaxTopicNumber ) + { + User::Leave( KErrCorrupt ); + } + } + +// ----------------------------------------------------------------------------- +// ParseSubIndexIntroL +// Parses part of an index message. +// subindex-intro = " " subindex-name crlf +// subindex-name = name-character+ +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseSubIndexIntroL( + TLex& aLex ) + { + if ( aLex.Get() != EKeySpace ) + { + User::Leave( KErrCorrupt ); + } + + // subindex-name crlf + TPtrC subIndexName; + ParseNameCharactersCrLfL( aLex, subIndexName ); + } + +// ----------------------------------------------------------------------------- +// ParseSubIndexIdL +// Parses part of an index message. +// subindex-id = subindex-character+ +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseSubIndexIdL( + TLex& aLex ) + { + // check that there is at least one subindex-character + if ( !aLex.Peek().IsAlpha() ) + { + User::Leave( KErrCorrupt ); + } + + // subindex-id + while ( aLex.Peek().IsAlpha() ) + { + aLex.Inc(); + } + } + +// ----------------------------------------------------------------------------- +// ParseNameCharactersCrLfL +// Parses part of an index message. +// name-character+ crlf +// Returns: None +// ----------------------------------------------------------------------------- +// +LOCAL_C void ParseNameCharactersCrLfL( + TLex& aLex, + TPtrC& aName ) + { + aLex.Mark(); + + // check that we have at least one name-character + TChar currCharacter( aLex.Get() ); + if( currCharacter == EKeyLineFeed + || currCharacter == EKeyEnter + || currCharacter == 0 ) + { + User::Leave( KErrCorrupt ); + } + + // scan until LF or EOS + while( currCharacter != EKeyLineFeed && currCharacter != 0 ) + { + currCharacter = aLex.Get(); + } + + // CR-LF is ok, EOS is not + if( currCharacter == EKeyLineFeed ) + { + aName.Set( aLex.MarkedToken() ); + } + else + { + User::Leave( KErrCorrupt ); + } + } + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::CCbsReceiverHelper +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCbsReceiverHelper::CCbsReceiverHelper( + CCbsDbImp& aDatabase ) + : iDatabase( aDatabase ) + { + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::ConstructL() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::ConstructL()"); + + iVwsSession = CVwsSessionWrapper::NewL(); + + // Array for SIM Topic numbers. This way we know which topics + // to delete also from the SIM card (when deleting all topics). + iSimTopics = new ( ELeave ) CArrayFixFlat( 1 ); + + // Fetch local variation bits from CenRep + CRepository* repository = CRepository::NewL( KCRUidCbsVariation ); + TInt err = repository->Get( KCbsVariationFlags, iLVBits ); + if ( err ) + { + iLVBits = 0; + } + CBSLOGSTRING2("CBSSERVER: CCbsRecEtel::ConstructL(): CenRep error: %d", err ); + delete repository; + + CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::ConstructL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CCbsReceiverHelper* CCbsReceiverHelper::NewL( + CCbsDbImp& aDatabase ) + { + // Normal two phase construction. + CCbsReceiverHelper* self = new ( ELeave ) CCbsReceiverHelper( aDatabase ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Destructor +CCbsReceiverHelper::~CCbsReceiverHelper() + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::~CCbsReceiverHelper()"); + + delete iSimTopics; + delete iVwsSession; + + CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::~CCbsReceiverHelper()"); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::CCbsReceiverHelper +// Processes a message received by the receiver. +// +// This function is called when a message is received. +// +// Assumptions; +// 1. The message doesn't have it's permanent or read +// flags raised - method leaves with KErrNotSupported +// if this is the case. +// 2. If an index message (root or subindex) is passed as +// a parameter, the language indication prefix, if any, +// has been removed before HandleReceivedMessageL() is called. +// +// Assumption (2) holds because language indications are removed +// by Receiver module in an instance of CCbsRecDecoder. +// Message may not be accepted if it is somehow invalid +// or the reception has been disabled. +// This function also handles the detection of new topics +// and the processing of an index message. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::HandleReceivedMessageL( + CCbsMessage& aMessage ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::HandleReceivedMessageL()"); + + if ( aMessage.IsIndexMessage() ) + { + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Index msg."); + + // It is assumed that a language indication prefix, + // if any, has already been removed from the message. + aMessage.RemoveIndexHeaderL(); + + TBool isChildSubindex( aMessage.IsChildSubindex() ); + + // Parse the index message + HandleIndexMessageL( aMessage.Contents(), isChildSubindex ); + + // Child subindex messages won't be displayed to the user. + if ( isChildSubindex ) + { + return; + } + } + + TUint16 topicNumber( aMessage.TopicNumber() ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): topic number: %d.", topicNumber ); + + TCbsDbTopic topic; + iDatabase.TopicListL().FindTopicByNumberL( topicNumber, topic ); + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): iDatabase.TopicListL().FindTopicByNumberL(..) called OK." ); + + // If subscribed, handle the message + if ( topic.iSubscribed ) + { + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Topic subscribed, processing." ); + + // Create and initialize message + TCbsDbMessage message; + + TTime now; + now.UniversalTime(); + message.iDateTime = now.Int64(); + message.iKey = aMessage.Key(); + message.iLanguage = aMessage.Language(); + message.iLength = aMessage.Contents().Length(); + message.iPermanent = EFalse; + message.iRead = EFalse; + TPtrC ptr( aMessage.Contents() ); + + iDatabase.TopicMessagesL().AddMessageL( topicNumber, message, ptr ); + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Msg added OK." ); + + if ( aMessage.RequiresImmediateDisplay() ) + { + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Calling LaunchMessageImmediateDisplay()... " ); + + // If the operator indicates that this message must be displayed + // immediately, request a view switch of CBS UI application. + LaunchMessageImmediateDisplay( message ); + + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): LaunchMessageImmediateDisplay() called OK." ); + } + else if ( topic.iHotmarked ) + { + // The message is of a hotmarked topic => Show a soft notification. + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Calling LaunchMessageSoftNotification()... " ); + LaunchMessageSoftNotificationL( ETrue ); + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): LaunchMessageSoftNotification() called OK." ); + } + } // if ( topic.iSubscribed ) + else + { + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::HandleReceivedMessageL(): Topic NOT subscribed, msg not processed." ); + } + + CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::HandleReceivedMessageL()"); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::CheckForNewTopicL +// Checks if aMessage's topic is in the topic list. +// +// If the topic detection is enabled and the topic of this +// message is not in the topic list, the topic is added +// to the list. The method will then return ETrue. +// Otherwise EFalse is returned. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsReceiverHelper::CheckForNewTopicL( + const CCbsMessage& aMessage ) + { + // Check if the topic detection is on and if so, add topic if the topic + // is a new topic. + TBool detection; + TBool result( EFalse ); + + iDatabase.SettingsL().GetTopicDetectionStatus( detection ); + + if ( detection && HandleTopicDetectedL( aMessage.TopicNumber() ) ) + { + // If a new topic added, we do not send the message to + // the database so return ETrue. + result = ETrue; + } + else + { + // Topic detection disabled or topic already in the database + result = EFalse; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::CheckForSubscriptionAndExistenceL +// Checks if the topic of this message is listed and subscribed. +// Returns ETrue only if the message does not exist in the +// database and the message's topic is subscribed. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsReceiverHelper::CheckForSubscriptionAndExistenceL( + const CCbsMessage& aMessage ) + { + // Check if the message belongs to some subscribed topic. + TCbsDbTopic topic; + TUint16 topicNumber( 0 ); + + // Index messages are stored in topic 0. + if ( !aMessage.IsIndexMessage() ) + { + topicNumber = aMessage.TopicNumber(); + } + + TRAPD( errorCode, iDatabase.TopicListL().FindTopicByNumberL( topicNumber, topic ) ); + + if ( errorCode == KErrNotFound ) + { + return EFalse; + } + User::LeaveIfError( errorCode ); + + return topic.iSubscribed; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::LanguageOfMessageSubscribedL +// Checks if aMessage's language has been subscribed by the user. +// ETrue is returned either if the language specified has been +// subscribed, message language is "Other" or the user has +// prefers to receive messages of all languages. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsReceiverHelper::LanguageOfMessageSubscribedL( + const CCbsMessage& aMessage ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::LanguageOfMessageSubscribedL" ); + + TCbsDbLanguages languages; + iDatabase.SettingsL().GetLanguages( languages ); + + if ( aMessage.Language() < 0 || aMessage.Language() >= ECbsCount ) + { + return EFalse; + } + + TCbsDbLanguage language( aMessage.Language() ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::LanguageOfMessageSubscribedL: language: %d.", language ); + + TBool subscribed( languages.iLanguages[ECbsAll] || + languages.iLanguages[ECbsOther] && language == ECbsOther || + !languages.iLanguages[ECbsOther] && languages.iLanguages[language] ); + + CBSLOGSTRING2("CBSSERVER: <<< CCbsReceiverHelper::LanguageOfMessageSubscribedL, returning %d.", subscribed ); + return subscribed; + } + +// --------------------------------------------------------- +// AddSimTopicL() +// +// Adds the given topic (aNumber, aName) into the DB. +// --------------------------------------------------------- +void CCbsReceiverHelper::AddSimTopicL( + const TUint aNumber, + const TDesC& aName ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::AddSimTopicL()"); + + TCbsDbTopic topic; + if ( aName == KNullDesC ) // Topic name not given, use "SIM topics". + { + // Establish file server session. + RFs fs; + User::LeaveIfError( fs.Connect() ); + CleanupClosePushL( fs ); + + // Open localized resource file. + RResourceFile resourceFile; + CbsUtils::FindAndOpenDefaultResourceFileLC( + fs, resourceFile ); // on CS + + // Read "SIM topic"-string. + TResourceReader reader; + reader.SetBuffer( resourceFile.AllocReadLC( + R_TEXT_SIM_TOPIC ) ); // on CS + + HBufC* text = reader.ReadHBufCL(); + topic.iName = *text; + CleanupStack::PopAndDestroy(3); // fs, resourceFile, readerBuf + + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic name read from resources."); + } + else // Use the given topic name. + { + topic.iName = aName; + } + + topic.iNumber = TUint16( aNumber ); + topic.iHotmarked = EFalse; + topic.iProtected = EFalse; + + // Variated feature + if ( iLVBits & KCbsLVFlagTopicSubscription ) + { + topic.iSubscribed = ETrue; + } + else + { + topic.iSubscribed = EFalse; + } + + // Leaves, if the topic already exists, so we trap that + // error. All other errors are passed as a normal leave. + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic %d from SIM to topic list...", topic.iNumber ); + // Try to add topic to topic list, topic not detected automatically + TRAPD( err, iDatabase.TopicListL().AddTopicL( topic, EFalse ) ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): AddTopicL() TRAPped error: %d.", err ); + + if( err != KErrAlreadyExists && err != KErrArgument ) + { + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Leave if error != -11 || -6"); + User::LeaveIfError( err ); + } + + // Append to SIM Topic array + iSimTopics->AppendL( topic.iNumber ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::AddSimTopicL(): Topic %d appended to array.", topic.iNumber ); + + // Leave so that caller is informed e.g. if topic already exists + User::LeaveIfError( err ); + CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::AddSimTopicL()" ); + + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::SimTopics +// Returns topics currently added from the SIM card. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CArrayFixFlat& CCbsReceiverHelper::SimTopics() const + { + return *iSimTopics; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::DeleteFromSimTopicCache +// Deletes the topic number from local SIM Topic array. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::DeleteFromSimTopicCache( const TUint16 aNumber ) + { + CBSLOGSTRING("CBSSERVER: >>> CCbsReceiverHelper::DeleteFromSimTopicCache()"); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic number: %d", aNumber ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic count in cache (1): %d", iSimTopics->Count() ); + + // Check if this topic is a SIM Topic (can be found in the array) + TKeyArrayFix key( 0, ECmpTUint16 ); + TInt index; + TUint16 topicNumber( aNumber ); + TInt result( iSimTopics->FindIsq( topicNumber, key, index ) ); + + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): FindIsq() result: %d", result ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): FindIsq() result, position: %d", index ); + + // Delete the topic from the array + if ( result == KErrNone ) + { + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic no. %d found from cache.", aNumber ); + iSimTopics->Delete( index ); + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic deleted from cache, index: %d", index ); + iSimTopics->Compress(); + CBSLOGSTRING("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): SIM Topic array compressed."); + } + + CBSLOGSTRING2("CBSSERVER: CCbsReceiverHelper::DeleteFromSimTopicCache(): Topic count in cache (2): %d", iSimTopics->Count() ); + CBSLOGSTRING("CBSSERVER: <<< CCbsReceiverHelper::DeleteFromSimTopicCache()"); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::Database +// Returns a reference to the CCbsDbImp instance. +// If a topic of the same number already exists +// in DB, does nothing. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CCbsDbImp& CCbsReceiverHelper::Database() const + { + return iDatabase; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::TopicsDetected +// Returns the number of detected topics. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TUint CCbsReceiverHelper::TopicsDetected() const + { + return iTopicsDetected; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::ClearTopicsDetectedCounter +// Sets the counter for detected topics to zero. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::ClearTopicsDetectedCounter() + { + // Clear the variable indicating the amount of detected topics. + iTopicsDetected = 0; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::HandleTopicDetectedL +// Handles detected topic. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TBool CCbsReceiverHelper::HandleTopicDetectedL( + const TCbsDbTopicNumber& iTopicNumber ) + { + // Create new topic and initialise it. + TCbsDbTopic topic; + topic.iNumber = iTopicNumber; + topic.iName = KNullDesC; + topic.iProtected = EFalse; + topic.iSubscribed = EFalse; + topic.iHotmarked = EFalse; + + TBool result( ETrue ); + + // Try to add the topic. If succeeded, + // increase counter iTopicsDetected. + TRAPD( error, iDatabase.TopicListL().AddTopicL( topic, ETrue ) ); + + if ( error == KErrAlreadyExists ) + { + result = EFalse; + } + else if ( error != KErrNone && error != KErrAlreadyExists ) + { + User::Leave( error ); + } + else + { + // Update the detected topics counter + iTopicsDetected++; + } + return result; + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::HandleIndexMessageL +// Processes an index message and builds a new topic collection +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::HandleIndexMessageL( + const TDesC& aContents, + const TBool aIsChildSubIndex ) + { + // Previous topic identities are cleared if a root index message + // is received. + if ( !aIsChildSubIndex ) + { + iDatabase.TopicCollectionL().Clear(); + } + // Parses topic identities from the index message. + // The identities are stored in the current topic collection. + // If the index message is corrupt, it should still be stored, + // so trap the error. + TLex lex( aContents ); + TRAPD( error, ParseMessageFormatL( lex, iDatabase.TopicCollectionL() ) ); + switch ( error ) + { + case KErrNone: + // If the message all went fine, apply. + // The topic identities are written into persistent memory. + iDatabase.TopicCollectionL().Apply(); + break; + + case KErrCorrupt: + // Do not react on corrupt messages. + break; + + default: + // All other errors will prevent saving the message. + User::Leave( error ); + break; + } + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::ParseTopicIdentitiesL +// Parses all topic identities from aText which is assumed to be +// an index message's content. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::ParseTopicIdentitiesL( + const TDesC& aText ) + { + // Create a lexer and pass it to the parser + TLex lex( aText ); + + ParseMessageFormatL( lex, iDatabase.TopicCollectionL() ); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::LaunchMessageSoftNotificationL +// Requests to launch a soft notification. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::LaunchMessageSoftNotificationL( const TBool aPlayTone ) + { + TInt numberOfHotMsgs( 0 ); + numberOfHotMsgs = iDatabase.TopicListL().UnreadHotmarkedMessageCount(); + + CAknSoftNotifier* notifier = CAknSoftNotifier::NewLC(); // on CS + + TurnLightsOn(); + + if ( aPlayTone ) + { + PlayCbsTone(); + } + + notifier->SetNotificationCountL( ECellBroadcastNotification, numberOfHotMsgs ); + CleanupStack::PopAndDestroy( notifier ); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::LaunchMessageImmediateDisplay +// Requests to show the message immediately. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::LaunchMessageImmediateDisplay( + const TCbsDbMessage& aMessage ) + { + TUid uiViewUid( TUid::Uid( ECbsUiMsgViewId ) ); + TVwsViewId id( KUidCbsUiappApp, uiViewUid ); + TPckgBuf pckg( aMessage.iHandle ); + + // Ignore result value. + iVwsSession->CreateActivateViewEvent( id, KCbsImmediateMessageId, pckg ); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::TurnLightsOn +// Turns lights on +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::TurnLightsOn() + { + // Change the bit on and off. SysAp will detect that + // the lights should be switched on for the specified time. + RProperty::Set(KPSUidCoreApplicationUIs, KLightsControl, ELightsOn); + RProperty::Set(KPSUidCoreApplicationUIs, KLightsControl, ELightsOff); + } + +// ----------------------------------------------------------------------------- +// CCbsReceiverHelper::PlayCbsTone +// Plays a tone +// ----------------------------------------------------------------------------- +// +void CCbsReceiverHelper::PlayCbsTone() + { + RProperty::Define( KPSUidNcnList, KNcnPlayAlertTone, RProperty::EInt, + ECapability_None , ECapabilityWriteDeviceData ); + RProperty::Set( KPSUidNcnList, KNcnPlayAlertTone, KCbsMessageTone ); + } + +// ================= OTHER EXPORTED FUNCTIONS ============== + +// End of File +