|
1 /* |
|
2 * Copyright (c) 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 "tstaskmonitor_p.h" |
|
18 #include "tstaskmonitor.h" |
|
19 |
|
20 #include <eikenv.h> |
|
21 #include <fbs.h> |
|
22 #include <s32mem.h> |
|
23 |
|
24 #include <XQConversions> |
|
25 |
|
26 #include "tstaskmonitorclient.h" |
|
27 #include "tstask.h" |
|
28 #include "tstaskcontent.h" |
|
29 #include "tstaskchangeinfo.h" |
|
30 #include "tsutils.h" |
|
31 #include "tstaskmonitorhistory.h" |
|
32 using TaskSwitcher::CleanupResetAndDestroyPushL; |
|
33 |
|
34 TsTaskMonitorPrivate::TsTaskMonitorPrivate(TsTaskMonitor *q) : q_ptr(q), mClient(0), mWsSession(CEikonEnv::Static()->WsSession()) |
|
35 { |
|
36 QT_TRAP_THROWING(mClient = CTsTaskMonitorClient::NewL()); |
|
37 mClient->Subscribe(*this); |
|
38 } |
|
39 |
|
40 TsTaskMonitorPrivate::~TsTaskMonitorPrivate() |
|
41 { |
|
42 mClient->CancelSubscribe(); |
|
43 delete mClient; |
|
44 } |
|
45 |
|
46 |
|
47 QList<TsTaskChange> TsTaskMonitorPrivate::changeList(bool fullList) |
|
48 { |
|
49 QList<TsTaskChange> retVal; |
|
50 |
|
51 QT_TRAP_THROWING ( |
|
52 |
|
53 HBufC8 *data = mClient->TasksContentLC(); |
|
54 if (data->Size() == 0) { |
|
55 CleanupStack::PopAndDestroy(data); |
|
56 return retVal; |
|
57 } |
|
58 TPtr8 dataPointer(data->Des()); |
|
59 RDesReadStream dataStream(dataPointer); |
|
60 CleanupClosePushL(dataStream); |
|
61 |
|
62 int count = dataStream.ReadInt32L(); |
|
63 |
|
64 QT_TRYCATCH_LEAVING( |
|
65 QList< QSharedPointer<TsTaskContent> > taskList; |
|
66 QList<TsTaskMonitorHistory> newTaskHistory; |
|
67 for (int iter(0); iter < count; iter++) { |
|
68 QSharedPointer<TsTaskContent> content(new TsTaskContent); |
|
69 TsTaskMonitorHistory newHistoryItem = internalizeContentL(dataStream, content); |
|
70 newHistoryItem.setOffset(iter); |
|
71 newTaskHistory.append(newHistoryItem); |
|
72 taskList.append(content); |
|
73 } |
|
74 if (fullList) { |
|
75 mTaskHistory.clear(); |
|
76 } |
|
77 QList<int> insertsList = findInserts(newTaskHistory); |
|
78 QList<int> deletesList = findDeletes(newTaskHistory); |
|
79 QList<TsTaskMonitorHistory> newMinusInserts; |
|
80 if (insertsList.count() > 0 ) { |
|
81 newMinusInserts = substractInsertsFromNew(insertsList, newTaskHistory); |
|
82 } else { |
|
83 newMinusInserts = newTaskHistory; |
|
84 } |
|
85 QList<TsTaskMonitorHistory> interimList; |
|
86 if (deletesList.count() > 0 ) { |
|
87 retVal.append(getDeletesChangeset(deletesList)); |
|
88 interimList = substractDeletesFromOld(deletesList); |
|
89 } else { |
|
90 interimList = mTaskHistory; |
|
91 } |
|
92 retVal.append(findMovesAndUpdates(newMinusInserts, taskList, interimList)); |
|
93 if (mTaskHistory.isEmpty()) { |
|
94 retVal.append(TsTaskChange(TsTaskChangeInfo(), QSharedPointer<TsTask>())); |
|
95 } |
|
96 retVal.append(getInsertsChangeset(insertsList, taskList)); |
|
97 mTaskHistory = newTaskHistory; |
|
98 )//QT_TRYCATCH_LEAVING |
|
99 CleanupStack::PopAndDestroy(&dataStream); |
|
100 CleanupStack::PopAndDestroy(data); |
|
101 );//QT_TRAP_THROWING |
|
102 |
|
103 return retVal; |
|
104 } |
|
105 |
|
106 TsTaskMonitorHistory TsTaskMonitorPrivate::internalizeContentL(RDesReadStream & dataStream, |
|
107 QSharedPointer<TsTaskContent> &content) |
|
108 { |
|
109 // get name |
|
110 TInt nameLength(dataStream.ReadInt32L()); |
|
111 if (0 < nameLength) { |
|
112 HBufC* name = HBufC::NewLC(dataStream, nameLength); |
|
113 content->mName = XQConversions::s60DescToQString(*name); |
|
114 CleanupStack::PopAndDestroy(name); |
|
115 } |
|
116 TPckgBuf<TTime> updateTime; |
|
117 dataStream.ReadL(updateTime); |
|
118 QDateTime historyTime = dateTimeFromS60(updateTime()); |
|
119 |
|
120 // get screenshot |
|
121 TInt screenshotHandle = dataStream.ReadInt32L(); |
|
122 CFbsBitmap *screenshot = new (ELeave) CFbsBitmap; |
|
123 CleanupStack::PushL(screenshot); |
|
124 if (KErrNone == screenshot->Duplicate(screenshotHandle)) { |
|
125 content->mScreenshot = QPixmap::fromSymbianCFbsBitmap(screenshot); |
|
126 } |
|
127 CleanupStack::PopAndDestroy(screenshot); |
|
128 // get key |
|
129 TInt keyLength(dataStream.ReadInt32L()); |
|
130 if (0 < keyLength) { |
|
131 HBufC8* key = HBufC8::NewLC(keyLength); |
|
132 TPtr8 des(key->Des()); |
|
133 dataStream.ReadL(des, keyLength); |
|
134 content->mKey = XQConversions::s60Desc8ToQByteArray(*key); |
|
135 CleanupStack::PopAndDestroy(key); |
|
136 } |
|
137 // get other values |
|
138 content->mActive = dataStream.ReadInt32L(); |
|
139 content->mClosable = dataStream.ReadInt32L(); |
|
140 return TsTaskMonitorHistory(content->mKey, historyTime); |
|
141 } |
|
142 |
|
143 QDateTime TsTaskMonitorPrivate::dateTimeFromS60(const TTime &s60Time) |
|
144 { |
|
145 TTime posixEpoch(_L("19700000:")); |
|
146 TTimeIntervalSeconds secondsFrom; |
|
147 TTimeIntervalMicroSeconds microSecondsFrom; |
|
148 s60Time.SecondsFrom(posixEpoch, secondsFrom); |
|
149 microSecondsFrom = s60Time.MicroSecondsFrom(posixEpoch); |
|
150 QDateTime retVal = QDateTime::fromTime_t(secondsFrom.Int()); |
|
151 retVal = retVal.addMSecs((microSecondsFrom.Int64() % TInt64(1000000) ) / TInt64(1000)); |
|
152 return retVal; |
|
153 } |
|
154 |
|
155 int TsTaskMonitorPrivate::findItemIndex( |
|
156 const QList<TsTaskMonitorHistory> &historyList, |
|
157 const TsTaskMonitorHistory &item ) |
|
158 { |
|
159 for (int iter(0); iter < historyList.count(); iter++) { |
|
160 if(historyList[iter].isEqual(item)) { |
|
161 return iter; |
|
162 } |
|
163 } |
|
164 return -1; |
|
165 } |
|
166 |
|
167 QList<int> TsTaskMonitorPrivate::findInserts( |
|
168 const QList<TsTaskMonitorHistory> &newHistory) |
|
169 { |
|
170 QList<int> retVal = QList<int>(); |
|
171 for (int iter(0); iter < newHistory.count(); iter++) { |
|
172 if (findItemIndex(mTaskHistory, newHistory[iter]) == -1) { |
|
173 retVal.append(iter); |
|
174 } |
|
175 } |
|
176 return retVal; |
|
177 } |
|
178 |
|
179 QList<int> TsTaskMonitorPrivate::findDeletes( |
|
180 const QList<TsTaskMonitorHistory> &newHistory) |
|
181 { |
|
182 QList<int> retVal = QList<int>(); |
|
183 //iterate backwards to keep order during model operations |
|
184 for (int iter(mTaskHistory.count() -1); iter >= 0 ; iter--) { |
|
185 if (findItemIndex(newHistory, mTaskHistory[iter]) == -1) { |
|
186 retVal.append(iter); |
|
187 } |
|
188 } |
|
189 return retVal; |
|
190 } |
|
191 |
|
192 QList<TsTaskChange> TsTaskMonitorPrivate::getDeletesChangeset( |
|
193 const QList<int> &deleteList) |
|
194 { |
|
195 QList<TsTaskChange> retVal; |
|
196 foreach (int index, deleteList) { |
|
197 TsTaskChangeInfo deleteChange(TsTaskChangeInfo::KInvalidOffset, |
|
198 index); |
|
199 retVal.append(TsTaskChange(deleteChange, QSharedPointer<TsTask>())); |
|
200 } |
|
201 return retVal; |
|
202 } |
|
203 |
|
204 QList<TsTaskChange> TsTaskMonitorPrivate::getInsertsChangeset(const QList<int> &insertList, |
|
205 const QList< QSharedPointer<TsTaskContent> > &taskList) |
|
206 { |
|
207 QList<TsTaskChange> retVal; |
|
208 foreach (int index, insertList) { |
|
209 TsTaskChangeInfo insertChange(index, |
|
210 TsTaskChangeInfo::KInvalidOffset); |
|
211 retVal.append(TsTaskChange( |
|
212 insertChange, |
|
213 QSharedPointer<TsTask>(new TsTask(taskList[index], *this)))); |
|
214 } |
|
215 return retVal; |
|
216 } |
|
217 |
|
218 QList<TsTaskMonitorHistory> TsTaskMonitorPrivate::substractInsertsFromNew( |
|
219 const QList<int> &insertList, |
|
220 const QList<TsTaskMonitorHistory> &newHistory ) |
|
221 { |
|
222 QList<TsTaskMonitorHistory> retVal(newHistory); |
|
223 for ( int iter(insertList.count() - 1); iter >= 0 ; iter--) { |
|
224 retVal.removeAt(insertList[iter]); |
|
225 } |
|
226 return retVal; |
|
227 } |
|
228 |
|
229 QList<TsTaskMonitorHistory> TsTaskMonitorPrivate::substractDeletesFromOld( |
|
230 const QList<int> &deleteList) |
|
231 { |
|
232 QList<TsTaskMonitorHistory> retVal(mTaskHistory); |
|
233 for (int iter(0); iter < deleteList.count() ; iter++) { |
|
234 retVal.removeAt(deleteList[iter]); |
|
235 } |
|
236 return retVal; |
|
237 } |
|
238 |
|
239 QList<TsTaskChange> TsTaskMonitorPrivate::findMovesAndUpdates( |
|
240 const QList<TsTaskMonitorHistory> &newMinusInserts, |
|
241 const QList< QSharedPointer<TsTaskContent> > &taskList, |
|
242 QList<TsTaskMonitorHistory> &workingList) |
|
243 { |
|
244 QList<TsTaskChange> retVal; |
|
245 for (int newPos(0); newPos < newMinusInserts.count(); newPos++) { |
|
246 //case 1 item has moved |
|
247 int previousPos = findItemIndex(workingList, newMinusInserts[newPos]); |
|
248 if (newPos != previousPos) { |
|
249 TsTaskChangeInfo moveChange(newPos, previousPos); |
|
250 retVal.append( |
|
251 TsTaskChange(moveChange, QSharedPointer<TsTask>())); |
|
252 workingList.move(previousPos, newPos); |
|
253 } |
|
254 // case 2 item has changed |
|
255 if (newMinusInserts[newPos].isUpdated(workingList[newPos])) { |
|
256 TsTaskChangeInfo updateChange(newPos, newPos); |
|
257 int taskListOffset = newMinusInserts[newPos].offset(); |
|
258 retVal.append( TsTaskChange( |
|
259 updateChange, |
|
260 QSharedPointer<TsTask>(new TsTask(taskList[taskListOffset], *this)))); |
|
261 } |
|
262 } |
|
263 return retVal; |
|
264 } |
|
265 |
|
266 void TsTaskMonitorPrivate::HandleRunningAppChange() |
|
267 { |
|
268 emit q_ptr->taskListChanged(); |
|
269 } |
|
270 |
|
271 void TsTaskMonitorPrivate::openTask(const QByteArray &key) |
|
272 { |
|
273 TPtrC8 desC(reinterpret_cast<const TUint8*>(key.constData()), key.length()); |
|
274 mClient->OpenTask(desC); |
|
275 |
|
276 } |
|
277 |
|
278 void TsTaskMonitorPrivate::closeTask(const QByteArray &key) |
|
279 { |
|
280 TPtrC8 desC(reinterpret_cast<const TUint8*>(key.constData()), key.length()); |
|
281 mClient->CloseTask(desC); |
|
282 } |