|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (developer.feedback@nokia.com) |
|
6 ** |
|
7 ** This file is part of the HbCore module of the UI Extensions for Mobile. |
|
8 ** |
|
9 ** GNU Lesser General Public License Usage |
|
10 ** This file may be used under the terms of the GNU Lesser General Public |
|
11 ** License version 2.1 as published by the Free Software Foundation and |
|
12 ** appearing in the file LICENSE.LGPL included in the packaging of this file. |
|
13 ** Please review the following information to ensure the GNU Lesser General |
|
14 ** Public License version 2.1 requirements will be met: |
|
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
16 ** |
|
17 ** In addition, as a special exception, Nokia gives you certain additional |
|
18 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
20 ** |
|
21 ** If you have questions regarding the use of this file, please contact |
|
22 ** Nokia at developer.feedback@nokia.com. |
|
23 ** |
|
24 ****************************************************************************/ |
|
25 |
|
26 #include <QByteArray> |
|
27 #include <qlist.h> |
|
28 #include <qdatastream.h> |
|
29 #include <QVariantMap> |
|
30 #include <hbdevicedialogtrace_p.h> |
|
31 #include "hbdevicedialogsession_p.h" |
|
32 #include "hbdevicedialogserversym_p_p.h" |
|
33 #include "hbdevicedialogserverdefs_p.h" |
|
34 #include "hbindicatorsessionhandler_p.h" |
|
35 #include "hbdevicedialogserver_p.h" |
|
36 #include <e32base.h> |
|
37 |
|
38 /*! |
|
39 HbIndicatorSession |
|
40 \internal |
|
41 */ |
|
42 |
|
43 //stream operators for IndicatorQueueItem |
|
44 QDataStream& operator << (QDataStream &outStream, |
|
45 const IndicatorQueueItem &obj) |
|
46 { |
|
47 outStream << obj.state; |
|
48 outStream << obj.clientInfo; |
|
49 return outStream; |
|
50 } |
|
51 |
|
52 QDataStream& operator >> (QDataStream &inStream, |
|
53 IndicatorQueueItem &obj) |
|
54 { |
|
55 int state; |
|
56 inStream >> state; |
|
57 obj.state = static_cast<IndicatorState>(state); |
|
58 inStream >> obj.clientInfo; |
|
59 return inStream; |
|
60 } |
|
61 |
|
62 /*! |
|
63 \internal |
|
64 */ |
|
65 HbIndicatorSessionHandler* HbIndicatorSessionHandler::NewL( |
|
66 HbDeviceDialogSession *aSession) |
|
67 { |
|
68 TRACE_STATIC_ENTRY |
|
69 HbIndicatorSessionHandler* session = |
|
70 new (ELeave) HbIndicatorSessionHandler(aSession); |
|
71 TRACE_EXIT |
|
72 return session; |
|
73 } |
|
74 |
|
75 /*! |
|
76 \internal |
|
77 */ |
|
78 HbIndicatorSessionHandler::~HbIndicatorSessionHandler() |
|
79 { |
|
80 TRACE_ENTRY |
|
81 Server().RemoveIndicatorHandlerFromList(this); |
|
82 TRACE_EXIT |
|
83 } |
|
84 |
|
85 /*! |
|
86 \internal |
|
87 Handles the servicing of a client request that has been passed |
|
88 to the server. |
|
89 */ |
|
90 void HbIndicatorSessionHandler::HandleMessageL( const RMessage2 &aMessage ) |
|
91 { |
|
92 TRACE_ENTRY |
|
93 |
|
94 switch( aMessage.Function() ) { |
|
95 case EHbSrvActivateIndicator: { |
|
96 ActivateIndicatorL( aMessage ); |
|
97 break; |
|
98 } |
|
99 case EHbSrvDeactivateIndicator: { |
|
100 DeactivateIndicatorL( aMessage ); |
|
101 break; |
|
102 } |
|
103 case EHbSrvGetActivatedIndicatorsStart: { |
|
104 iIndicatorQueue.clear(); |
|
105 addToIndicatorQueue(Server().indicatorClientInfoList(), |
|
106 IndicatorActivated); |
|
107 iMsgType = EHbIndicatorAllActivated; |
|
108 IndicatorChannelRequestL( aMessage ); |
|
109 break; |
|
110 } |
|
111 case EHbSrvGetActivatedIndicatorContinue: { |
|
112 if (iMsgType == -1) { |
|
113 iMsgType = EHbIndicatorUpdates; |
|
114 } |
|
115 IndicatorChannelRequestL( aMessage ); |
|
116 break; |
|
117 } |
|
118 case EhbSrvGetActivatedIndicatorsClose: { |
|
119 Server().RemoveIndicatorHandlerFromList(this); |
|
120 if (iIndicatorChannelOpen) { |
|
121 iIndicatorChannelOpen = EFalse; |
|
122 iIndicatorChannel.Complete(KErrNone); |
|
123 } |
|
124 aMessage.Complete( KErrNone ); |
|
125 break; |
|
126 } |
|
127 default: { |
|
128 break; |
|
129 } |
|
130 |
|
131 }; // end switch |
|
132 TRACE_EXIT |
|
133 } |
|
134 |
|
135 /*! |
|
136 \internal |
|
137 Called, when indicator(s) have been activated. |
|
138 */ |
|
139 void HbIndicatorSessionHandler::IndicatorsActivated( |
|
140 const QList<IndicatorClientInfo> &activated) |
|
141 { |
|
142 TRACE_ENTRY |
|
143 addToIndicatorQueue(activated, IndicatorActivated); |
|
144 TRAP_IGNORE( WriteIndicatorInfoL() ); |
|
145 TRACE_EXIT |
|
146 } |
|
147 |
|
148 void HbIndicatorSessionHandler::IndicatorsUpdated( |
|
149 const QList<IndicatorClientInfo> &updated) |
|
150 { |
|
151 TRACE_ENTRY |
|
152 addToIndicatorQueue(updated, IndicatorUpdated); |
|
153 TRAP_IGNORE( WriteIndicatorInfoL() ); |
|
154 TRACE_EXIT |
|
155 } |
|
156 |
|
157 /*! |
|
158 \internal |
|
159 Called, when indicator(s) have been deactivated. |
|
160 */ |
|
161 void HbIndicatorSessionHandler::IndicatorsDeactivated( |
|
162 const QList<IndicatorClientInfo> &deactivated) |
|
163 { |
|
164 TRACE_ENTRY |
|
165 addToIndicatorQueue(deactivated, IndicatorDeactivated); |
|
166 TRAP_IGNORE( WriteIndicatorInfoL() ); |
|
167 TRACE_EXIT |
|
168 } |
|
169 |
|
170 HbDeviceDialogServerPrivate& HbIndicatorSessionHandler::Server() |
|
171 { |
|
172 return iSession->Server(); |
|
173 } |
|
174 |
|
175 /*! |
|
176 \internal |
|
177 handle indicator activation. |
|
178 */ |
|
179 void HbIndicatorSessionHandler::ActivateIndicatorL( const RMessage2 &aMessage ) |
|
180 { |
|
181 TRACE_ENTRY |
|
182 QVariant parameter; |
|
183 QString type = indicatorTypeFromMessageL(aMessage, parameter); |
|
184 HbDeviceDialogServer::IndicatorParameters indicatorParameters(type, aMessage, parameter); |
|
185 TInt result = Server().activateIndicator(indicatorParameters); |
|
186 aMessage.Complete(result); |
|
187 TRACE_EXIT_ARGS("result: " << result) |
|
188 } |
|
189 |
|
190 /*! |
|
191 \internal |
|
192 handle indicator deactivation. |
|
193 */ |
|
194 void HbIndicatorSessionHandler::DeactivateIndicatorL( const RMessage2 &aMessage ) |
|
195 { |
|
196 TRACE_ENTRY |
|
197 QVariant parameter; |
|
198 QString type = indicatorTypeFromMessageL(aMessage, parameter); |
|
199 HbDeviceDialogServer::IndicatorParameters indicatorParameters(type, aMessage, parameter); |
|
200 TInt result = Server().deactivateIndicator(indicatorParameters); |
|
201 aMessage.Complete(result); |
|
202 TRACE_EXIT_ARGS("result: " << result) |
|
203 } |
|
204 |
|
205 void HbIndicatorSessionHandler::IndicatorChannelRequestL( |
|
206 const RMessage2 &aMessage ) |
|
207 { |
|
208 TRACE_ENTRY |
|
209 iIndicatorChannelOpen = ETrue; |
|
210 iIndicatorChannel = aMessage; |
|
211 |
|
212 TInt result = Server().AddIndicatorHandlerToList(this); |
|
213 if ( result != KErrNone ) { |
|
214 // Nothing to do if adding fails. |
|
215 iIndicatorChannel.Complete( result ); |
|
216 iIndicatorChannelOpen = false; |
|
217 return; |
|
218 } |
|
219 |
|
220 WriteIndicatorInfoL(); |
|
221 TRACE_EXIT |
|
222 } |
|
223 |
|
224 /*! |
|
225 \internal |
|
226 add client infos to queue, where they are sent to client. |
|
227 */ |
|
228 void HbIndicatorSessionHandler::addToIndicatorQueue( |
|
229 const QList<IndicatorClientInfo> &clientInfoList, |
|
230 IndicatorState state) |
|
231 { |
|
232 foreach(const IndicatorClientInfo &clientInfo, clientInfoList) { |
|
233 iIndicatorQueue.append(IndicatorQueueItem(clientInfo, state)); |
|
234 } |
|
235 } |
|
236 |
|
237 /*! |
|
238 \internal |
|
239 write indicator info from indicator queue to client. |
|
240 */ |
|
241 void HbIndicatorSessionHandler::WriteIndicatorInfoL() |
|
242 { |
|
243 if ( iIndicatorChannelOpen ) { |
|
244 // Client is listening and ready to receive data |
|
245 |
|
246 if (iIndicatorQueue.count() > 0) { |
|
247 iIndicatorChannelOpen = EFalse; |
|
248 |
|
249 TPckgBuf<TInt> buf( iMsgType ); |
|
250 TInt error = iIndicatorChannel.Write( KSlot1, buf ); |
|
251 User::LeaveIfError( error ); |
|
252 |
|
253 TInt leftOver = DoWriteIndicatorInfoL(error); |
|
254 if (leftOver >= 0) { |
|
255 //remove those, that were sent. |
|
256 iIndicatorQueue.erase(iIndicatorQueue.begin(), |
|
257 iIndicatorQueue.begin() |
|
258 + (iIndicatorQueue.count() - leftOver)); |
|
259 if (iMsgType == EHbIndicatorAllActivated |
|
260 && iIndicatorQueue.count() == 0) { |
|
261 iMsgType = EHbIndicatorUpdates; //send only updates from now on. |
|
262 } |
|
263 } |
|
264 iIndicatorChannel.Complete( error ); |
|
265 } |
|
266 } |
|
267 } |
|
268 |
|
269 /*! |
|
270 \internal |
|
271 helper function fo WriteIndicatorInfoL |
|
272 */ |
|
273 TInt HbIndicatorSessionHandler::DoWriteIndicatorInfoL(TInt &error) |
|
274 { |
|
275 TRACE_ENTRY |
|
276 error = KErrNone; |
|
277 quint16 clientInfoCount = static_cast<quint16>(iIndicatorQueue.count()); |
|
278 quint16 clientInfoStoreCount = 0; |
|
279 |
|
280 // Get client data buffer size. |
|
281 QByteArray array; |
|
282 TInt desSize = iIndicatorChannel.GetDesMaxLength( KSlot0 ); |
|
283 if (desSize > sizeof(quint16) + 16) { |
|
284 //check, how many activated indicator infos will fit the size. |
|
285 QDataStream outStream(&array, QIODevice::WriteOnly); |
|
286 |
|
287 clientInfoStoreCount = clientInfoCount; //assume all fits. |
|
288 outStream << clientInfoCount; |
|
289 for(int i = 0; i < clientInfoCount; ++i) { |
|
290 outStream << iIndicatorQueue[i]; |
|
291 if (array.size() > desSize) { |
|
292 clientInfoStoreCount = i; //can't fit all. |
|
293 break; |
|
294 } |
|
295 } |
|
296 } |
|
297 |
|
298 TBool hasLeftOver = ETrue; |
|
299 if (clientInfoStoreCount > 0) { |
|
300 hasLeftOver = EFalse; |
|
301 if (clientInfoStoreCount < clientInfoCount) { |
|
302 hasLeftOver = ETrue; |
|
303 // fill the buffer again with correct count. |
|
304 array.clear(); |
|
305 QDataStream outStream(&array, QIODevice::WriteOnly); |
|
306 outStream << clientInfoStoreCount; |
|
307 for(int i = 0; i < clientInfoStoreCount; ++i) { |
|
308 outStream << iIndicatorQueue[i]; |
|
309 } |
|
310 } |
|
311 //write data to message. |
|
312 TPtr8 ptr( reinterpret_cast<TUint8*>(array.data()), |
|
313 array.size(), array.size()); |
|
314 error = iIndicatorChannel.Write( KSlot0, ptr ); |
|
315 User::LeaveIfError( error ); |
|
316 } |
|
317 |
|
318 if (hasLeftOver) { |
|
319 //not all infos fitted, calculate how much size is needed to get the rest. |
|
320 array.clear(); |
|
321 QDataStream stream(&array, QIODevice::WriteOnly); |
|
322 stream << quint16(0); |
|
323 for (int i = clientInfoStoreCount; i < clientInfoCount; ++i) { |
|
324 stream << iIndicatorQueue[i]; |
|
325 } |
|
326 |
|
327 // Complete with data length |
|
328 error = array.size(); |
|
329 } |
|
330 |
|
331 TRACE_EXIT |
|
332 return clientInfoCount - clientInfoStoreCount; |
|
333 } |
|
334 |
|
335 /*! |
|
336 \internal |
|
337 get the indicator type and parameter from the message. |
|
338 */ |
|
339 QString HbIndicatorSessionHandler::indicatorTypeFromMessageL(const RMessage2 &aMessage, |
|
340 QVariant ¶meter) const |
|
341 { |
|
342 TRACE_ENTRY |
|
343 TInt dataSize = aMessage.GetDesLength( KSlot0 ); |
|
344 |
|
345 HBufC8* data = HBufC8::NewLC( dataSize ); |
|
346 TPtr8 ptr( data->Des() ); |
|
347 aMessage.ReadL( KSlot0, ptr ); |
|
348 |
|
349 QByteArray resArray( (const char*) ptr.Ptr(), ptr.Size() ); |
|
350 QDataStream outStream( &resArray, QIODevice::ReadOnly ); |
|
351 QString indicatorType; |
|
352 |
|
353 outStream >> indicatorType; |
|
354 outStream >> parameter; |
|
355 |
|
356 CleanupStack::PopAndDestroy( data ); |
|
357 TRACE_EXIT |
|
358 return indicatorType; |
|
359 } |
|
360 |
|
361 /*! |
|
362 \internal |
|
363 */ |
|
364 HbIndicatorSessionHandler::HbIndicatorSessionHandler( |
|
365 HbDeviceDialogSession *aSession) : iSession(aSession), iMsgType(-1) |
|
366 { |
|
367 TRACE_ENTRY |
|
368 TRACE_EXIT |
|
369 } |