void CViewSubSessionQueue::RequestEvent(const RMessage2& aMessage) { __ASSERT_DEBUG(!iRequestPending,User::Leave(KErrAlreadyExists)); // can only leave in debug mode if (!iRequestPending) { iMessage=aMessage; iRequestPending=ETrue; if (iQueueError) { TContactViewEvent errorEvent(TContactViewEvent::EServerError,iQueueError); iQueueError=KErrNone; SendEventL(errorEvent); } else if (iEvents.Count()>0) { SendEventL(iEvents[0]); iEvents.Remove(0); } } }
void CDeviceEventQueue::StartL() { OstTraceFunctionEntry0( CDEVICEEVENTQUEUE_STARTL_ENTRY ); if (IsActive()) { OstTraceFunctionExit0( CDEVICEEVENTQUEUE_STARTL_EXIT ); return; } if (IsEventAvailable()) { SendEventL(); } OstTraceFunctionExit0( CDEVICEEVENTQUEUE_STARTL_EXIT_DUP1 ); }
void CDeviceEventQueue::RunL() { OstTraceFunctionEntry0( CDEVICEEVENTQUEUE_RUNL_ENTRY ); // Check the completion code from CDeviceEventHandler. If there // is some error occured. We need issue error notification here. TInt err = iStatus.Int(); if ((KErrNone != err) && (KErrCancel != err)) { iServer.PolicyPlugin()-> SendErrorNotificationL(iHandler->ErrNotiData()); } iHandler->ResetHandler(); if (IsEventAvailable()) { SendEventL(); } OstTraceFunctionExit0( CDEVICEEVENTQUEUE_RUNL_EXIT ); }
EXPORT_C void CHarvesterEventManager::RegisterEventObserverL( const RMessage2& aMessage ) { THarvesterEventObserverInfo* observerInfo = new (ELeave) THarvesterEventObserverInfo; CleanupStack::PushL( observerInfo ); TPckg<THarvesterEventObserverInfo> pckgObserverInfo( *observerInfo ); TInt err = aMessage.Read( 0, pckgObserverInfo ); // Init server side values observerInfo->iQueuePtr = NULL; observerInfo->iDelta = 0; observerInfo->iProcessUid = aMessage.Identity().iUid; // Check if observer ID is not yet used // and if event queue already exists TBool found = EFalse; for(TInt i = iRegisteredObservers.Count(); --i >= 0;) { THarvesterEventObserverInfo* info = iRegisteredObservers[i]; if( info->iProcessUid == observerInfo->iProcessUid && info->iQueueHandle == observerInfo->iQueueHandle ) { if( info->iObserverId == observerInfo->iObserverId ) { User::Leave( KErrAlreadyExists ); } observerInfo->iQueuePtr = info->iQueuePtr; found = ETrue; } } // create new event queue if no match was found if ( !found ) { THarvesterEventQueue* msgQueue = new (ELeave) THarvesterEventQueue; CleanupStack::PushL( msgQueue ); User::LeaveIfError( msgQueue->Open( aMessage, 1 ) ); User::LeaveIfError( iEventQueues.InsertInOrderAllowRepeats(msgQueue, TLinearOrder<THarvesterEventQueue>(CHarvesterEventManager::CompareProperties))); observerInfo->iQueuePtr = msgQueue; CleanupStack::Pop( msgQueue ); } iRegisteredObservers.AppendL( observerInfo ); // send event if register is coming in the middle of harvesting for( TInt i = iEventStatuses.Count(); --i >= 0; ) { TEventStatus& eventStatus = iEventStatuses[i]; if( CheckObserverType( observerInfo->iObserverType, eventStatus.iObserverType) ) { TRAP_IGNORE( SendEventL( eventStatus.iObserverType, eventStatus.iCurrentState, eventStatus.iItemsLeft ) ); } } //no events in queue, signal registered client anyways if( !iEventStatuses.Count() ) { if(observerInfo->iObserverType & EHEObserverTypeOverall) { SendSingleEvent(*observerInfo, EHEObserverTypeOverall, EHEStateUninitialized, 0); } if(observerInfo->iObserverType & EHEObserverTypeMMC) { SendSingleEvent(*observerInfo, EHEObserverTypeMMC, EHEStateUninitialized, 0); } if(observerInfo->iObserverType & EHEObserverTypePlaceholder) { SendSingleEvent(*observerInfo, EHEObserverTypePlaceholder, EHEStateUninitialized, 0); } } CleanupStack::Pop( observerInfo ); }
EXPORT_C TBool CHarvesterEventManager::DecreaseItemCountL( HarvesterEventObserverType aHEObserverType, TUint aCount ) { TEventStatus* eventStatus = GetEventStatus( aHEObserverType ); WRITELOG2( "CHarvesterEventManager::DecreaseItemCountL(%d) type = %d ", aCount, aHEObserverType); #ifdef _DEBUG switch(aHEObserverType) { case EHEObserverTypePlaceholder: { WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypePlaceholder"); OstTrace0( TRACE_NORMAL, CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL EHEObserverTypePlaceholder" ); break; } case EHEObserverTypeMMC: { WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeMMC"); OstTrace0( TRACE_NORMAL, DUP1_CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL EHEObserverTypeMMC" ); break; } case EHEObserverTypeOverall: { WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeOverall"); OstTrace0( TRACE_NORMAL, DUP2_CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL EHEObserverTypeOverall" ); break; } default: { WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() Unknown type!"); OstTrace0( TRACE_NORMAL, DUP3_CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL Unknown type!" ); } }; #endif if( eventStatus ) { WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d old", eventStatus->iItemsLeft); OstTrace1( TRACE_NORMAL, DUP4_CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL iItemsLeft = %d old", eventStatus->iItemsLeft ); TUint newCount = eventStatus->iItemsLeft - aCount; // check for wrap if( newCount > eventStatus->iItemsLeft ) { newCount = 0; } // event doesn't need to be sent, if count hasn't changed if( newCount == eventStatus->iItemsLeft ) { return EFalse; } eventStatus->iItemsLeft = newCount; } else { return EFalse; } WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d", eventStatus->iItemsLeft ); OstTrace1( TRACE_NORMAL, DUP5_CHARVESTEREVENTMANAGER_DECREASEITEMCOUNTL, "CHarvesterEventManager::DecreaseItemCountL iItemsLeft = %d", eventStatus->iItemsLeft ); // send finished event to all matching observers if ( eventStatus->iItemsLeft <= 0 ) { eventStatus->iItemsLeft = 0; eventStatus->iCurrentState = EHEStateFinished; // EHEObserverTypeOverall state is handled directly in harvesterao during harvesting if( aHEObserverType != EHEObserverTypeOverall ) { const TInt err = SendEventL( aHEObserverType, eventStatus->iCurrentState, eventStatus->iItemsLeft ); return err == KErrNone; } } // still harvesting eventStatus->iCurrentState = EHEStateHarvesting; // send harvesting event to all matching observers TBool wasSent = EFalse; TInt count = iRegisteredObservers.Count(); for ( TInt i = count; --i >= 0; ) { THarvesterEventObserverInfo& observer = *(iRegisteredObservers[i]); if( CheckObserverType( observer.iObserverType, aHEObserverType ) ) { observer.iDelta += aCount; // observers interval full if ( observer.iDelta >= observer.iNotificationInterval ) { TInt err = SendSingleEvent( observer, aHEObserverType, eventStatus->iCurrentState, eventStatus->iItemsLeft ); if ( err == KErrNone ) { wasSent = ETrue; } } } } return wasSent; }
void CViewSubSessionQueue::QueueEvent(const TContactViewEvent& aEvent) { const TInt KInvalidValueForRemoteView = -1; TBool haveToAddEventInQueue = ETrue; if (iRequestPending) { if(aEvent.iEventType == TContactViewEvent::EItemAdded) { // is this first event sent? If yes and if the event is an // EItemAdded event send first a fake event. // This is because all EItemAdded should be sorted before send them TContactViewEvent event; event.iEventType = TContactViewEvent::EItemAdded; event.iContactId = KInvalidValueForRemoteView; event.iInt = KInvalidValueForRemoteView; SendEventL(event); } else { SendEventL(aEvent); haveToAddEventInQueue = EFalse; } } if (haveToAddEventInQueue && !iQueueError) { // There are two requirements for this queue of events: // 1. The iInt values for events in the Q at any given point in time // should match the index of the underlying localview array. i.e If the addition/removal // of a contact has caused the position of other contacts items to change in the underlying localview // then previous events sent by them in this Q will have old iInt values and these need to be corrected. // 2. When the client gets these events in order, it should have a valid view after every event, // ie. if we have 2 additions, at positions 0 and 1, // we cannot send the event for addition at position 1 before the addition at position 0. // // These requirements are fulfilled using the following algorithm. // Events are inserted in the queue using following two condition // 1. EItemAdded - // 1.1 Find if an existing EItemAdded events iInt is greater or equal with incoming events iInt. // if found,insert event before the found one and increment the iInt of the rest event by 1 // 1.2 if no match is found with same iInt, modify its iInt value with incoming events iInt, // then append to the event queue. // 1.3 If no EItemAdded events are in queue, append this one to Queue. // 2. EItemRemoved - // 2.1 Find if an existing EItemAdded events iInt matches with incoming EItemRemoved events iInt. // if found, then remove that EItemAdded event from the Queue and decrement rest of the // events iInt by 1. // 2.2 if no match is found with same iInt, then insert the event before next greater iInt event // and then decerement the iInt value of rest of the event by 1. // 2.3 if no events greater than this then append this one to Queue. TContactViewEvent event; event.iEventType = aEvent.iEventType; event.iContactId = aEvent.iContactId; event.iInt = aEvent.iInt; TInt eventsCount = iEvents.Count(); TUint pos=0; if( event.iEventType == TContactViewEvent::EItemAdded ) { TInt lastItemRemovedPosition = KErrNotFound; //first check if this add event is not generated by a contact item change for( pos=0; pos<eventsCount; ++pos ) { if( iEvents[pos].iContactId == aEvent.iContactId && iEvents[pos].iEventType == TContactViewEvent::EItemRemoved ) { lastItemRemovedPosition = pos; } } if( lastItemRemovedPosition != KErrNotFound ) { ++lastItemRemovedPosition; if(lastItemRemovedPosition < eventsCount) { for( pos = lastItemRemovedPosition-1; pos < eventsCount;++pos ) { if(iEvents[pos].iInt >= aEvent.iInt && iEvents[pos].iContactId != aEvent.iContactId) { if( iEvents[pos].iEventType == TContactViewEvent::EItemRemoved || iEvents[pos].iEventType == TContactViewEvent::EItemAdded) { iEvents[pos].iInt++; } } } iQueueError = iEvents.Insert(aEvent, lastItemRemovedPosition); } else { iQueueError = iEvents.Append(aEvent); } } else { TBool haveToAppendEvent = ETrue; for( pos=0; pos<eventsCount; ++pos ) { if(iEvents[pos].iEventType == TContactViewEvent::EItemAdded) { if(iEvents[pos].iInt >= event.iInt) { iQueueError = iEvents.Insert(event, pos); eventsCount=iEvents.Count(); for(TUint loop=pos+1; loop<eventsCount; ++loop) { if( iEvents[pos].iEventType == TContactViewEvent::EItemRemoved || iEvents[pos].iEventType == TContactViewEvent::EItemAdded) { iEvents[loop].iInt++; } } haveToAppendEvent = EFalse; break; } } } if( haveToAppendEvent ) { iQueueError = iEvents.Append(event); } } } else { iQueueError = iEvents.Append(event); } DEBUG_PRINTVN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] CViewSubSessionQueue::QueueEvent(): ->Q:"), event); } }