|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include <e32svr.h> |
|
18 #include <harvestereventenum.h> |
|
19 |
|
20 #include "harvestereventobserverao.h" |
|
21 #include "harvesterclient.h" |
|
22 |
|
23 const TInt KHarverterEventQueueSize = 32; |
|
24 |
|
25 CHarvesterEventObserverAO::CHarvesterEventObserverAO( |
|
26 RHarvesterClient& aHarvesterClient ) : |
|
27 CActive(CActive::EPriorityStandard), // Standard priority |
|
28 iHarvesterClient( aHarvesterClient ) |
|
29 { |
|
30 } |
|
31 |
|
32 CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewLC( |
|
33 RHarvesterClient& aHarvesterClient ) |
|
34 { |
|
35 CHarvesterEventObserverAO* self = |
|
36 new ( ELeave ) CHarvesterEventObserverAO( aHarvesterClient ); |
|
37 CleanupStack::PushL(self); |
|
38 self->ConstructL(); |
|
39 return self; |
|
40 } |
|
41 |
|
42 CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewL( |
|
43 RHarvesterClient& aHarvesterClient ) |
|
44 { |
|
45 CHarvesterEventObserverAO* self = |
|
46 CHarvesterEventObserverAO::NewLC( aHarvesterClient ); |
|
47 CleanupStack::Pop( self ); // self; |
|
48 return self; |
|
49 } |
|
50 |
|
51 void CHarvesterEventObserverAO::ConstructL() |
|
52 { |
|
53 CActiveScheduler::Add( this ); // Add to scheduler |
|
54 } |
|
55 |
|
56 CHarvesterEventObserverAO::~CHarvesterEventObserverAO() |
|
57 { |
|
58 Cancel(); // Cancel any request, if outstanding |
|
59 |
|
60 for(TInt i = iObservers.Count(); --i >= 0;) |
|
61 { |
|
62 THarvesterEventObserver& observer = *(iObservers[i]); |
|
63 |
|
64 TIpcArgs ipcArgs( observer.iObserverInfo.iObserverId, |
|
65 iHarvesterEventQueue.Handle() ); |
|
66 |
|
67 iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs ); |
|
68 } |
|
69 |
|
70 iHarvesterEventQueue.Close(); |
|
71 |
|
72 iObservers.ResetAndDestroy(); |
|
73 } |
|
74 |
|
75 void CHarvesterEventObserverAO::DoCancel() |
|
76 { |
|
77 iHarvesterEventQueue.CancelDataAvailable(); |
|
78 } |
|
79 |
|
80 void CHarvesterEventObserverAO::AddHarvesterEventObserverL( |
|
81 MHarvesterEventObserver& aHarvesterEventObserver, |
|
82 TInt aHEObserverType, |
|
83 TInt aNotificationInterval ) |
|
84 { |
|
85 RHandleBase& queueHandle = GetEventQueueHandleL(); |
|
86 |
|
87 THarvesterEventObserver* observer = |
|
88 new (ELeave) THarvesterEventObserver( aHarvesterEventObserver ); |
|
89 CleanupStack::PushL( observer ); |
|
90 |
|
91 // Init client side values |
|
92 observer->iObserverInfo.iQueueHandle = queueHandle.Handle(); |
|
93 observer->iObserverInfo.iObserverId = NextObserverId(); |
|
94 observer->iObserverInfo.iObserverType = aHEObserverType; |
|
95 observer->iObserverInfo.iNotificationInterval = aNotificationInterval; |
|
96 |
|
97 iObservers.AppendL( observer ); |
|
98 |
|
99 CleanupStack::Pop( observer ); |
|
100 |
|
101 TPckg<THarvesterEventObserverInfo> pckgObserverInfo( observer->iObserverInfo ); |
|
102 TIpcArgs ipcArgs( &pckgObserverInfo, queueHandle ); |
|
103 |
|
104 TInt err = iHarvesterClient.SendReceive( ERegisterHarvesterEvent, ipcArgs ); |
|
105 |
|
106 User::LeaveIfError( err ); |
|
107 |
|
108 if( !IsActive() ) |
|
109 { |
|
110 iHarvesterEventQueue.NotifyDataAvailable( iStatus ); |
|
111 SetActive(); // Tell scheduler a request is active |
|
112 } |
|
113 } |
|
114 |
|
115 void CHarvesterEventObserverAO::RemoveHarvesterEventObserverL( |
|
116 MHarvesterEventObserver& aHarvesterEventObserver ) |
|
117 { |
|
118 // clear all observers which match to callback instance |
|
119 for(TInt i = iObservers.Count(); --i >= 0;) |
|
120 { |
|
121 THarvesterEventObserver* observer = iObservers[i]; |
|
122 if( &observer->iObserver == &aHarvesterEventObserver ) |
|
123 { |
|
124 TIpcArgs ipcArgs( observer->iObserverInfo.iObserverId, |
|
125 iHarvesterEventQueue.Handle() ); |
|
126 iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs ); |
|
127 iObservers.Remove( i ); |
|
128 delete observer; |
|
129 } |
|
130 } |
|
131 |
|
132 // close event queue if all observers are removed |
|
133 if( iObservers.Count() == 0 ) |
|
134 { |
|
135 Cancel(); |
|
136 iHarvesterEventQueue.Close(); |
|
137 } |
|
138 } |
|
139 |
|
140 void CHarvesterEventObserverAO::RunL() |
|
141 { |
|
142 User::LeaveIfError( iStatus.Int() ); |
|
143 |
|
144 THarvesterEventNotification received; |
|
145 while( iHarvesterEventQueue.Receive( received ) != KErrUnderflow ) |
|
146 { |
|
147 for(TInt i = iObservers.Count(); --i >= 0;) |
|
148 { |
|
149 THarvesterEventObserver& observer = *(iObservers[i]); |
|
150 if( observer.iObserverInfo.iObserverId == received.iObserverId ) |
|
151 { |
|
152 observer.iObserver.HarvestingUpdated( received.iObserverType, |
|
153 received.iCurrentState, received.iItemsLeft ); |
|
154 break; |
|
155 } |
|
156 } |
|
157 } |
|
158 |
|
159 if( iObservers.Count() > 0 ) |
|
160 { |
|
161 SetActive(); |
|
162 iHarvesterEventQueue.NotifyDataAvailable( iStatus ); |
|
163 } |
|
164 } |
|
165 |
|
166 TInt CHarvesterEventObserverAO::RunError(TInt /*aError*/) |
|
167 { |
|
168 return KErrNone; |
|
169 } |
|
170 |
|
171 TUint CHarvesterEventObserverAO::NextObserverId() |
|
172 { |
|
173 // Sort by observer IDs |
|
174 iObservers.Sort( TLinearOrder<THarvesterEventObserver>( |
|
175 THarvesterEventObserver::CompareObserverIds ) ); |
|
176 |
|
177 // Find smallest unused observer ID |
|
178 const TUint count = iObservers.Count(); |
|
179 for( TUint i = 0; i < count; i++ ) |
|
180 { |
|
181 // Return first free observer ID |
|
182 if( iObservers[i]->iObserverInfo.iObserverId != i ) |
|
183 { |
|
184 return i; |
|
185 } |
|
186 } |
|
187 |
|
188 if( count ) |
|
189 { |
|
190 // No free observer ID found, so return largest observer ID + 1 |
|
191 return iObservers[count - 1]->iObserverInfo.iObserverId + 1; |
|
192 } |
|
193 // No observer IDs assigned |
|
194 return 0; |
|
195 } |
|
196 |
|
197 RHandleBase& CHarvesterEventObserverAO::GetEventQueueHandleL() |
|
198 { |
|
199 // create new message queue |
|
200 if( KNullHandle == iHarvesterEventQueue.Handle() ) |
|
201 { |
|
202 TInt err = iHarvesterEventQueue.CreateGlobal( KNullDesC, KHarverterEventQueueSize ); |
|
203 User::LeaveIfError( err ); |
|
204 } |
|
205 |
|
206 return iHarvesterEventQueue; |
|
207 } |