|
1 /* |
|
2 * Copyright (c) 2006 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: MPX delete helper |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32base.h> |
|
20 #include <f32file.h> |
|
21 #include <mpxmedia.h> |
|
22 #include <mpxmediageneraldefs.h> |
|
23 #include <mpxcommandgeneraldefs.h> |
|
24 #include <mpxcollectioncommanddefs.h> |
|
25 #include <mpxcollectionpath.h> |
|
26 #include <mpxcollectionplaylist.h> |
|
27 #include <mpxplaybackutility.h> |
|
28 #include <mpxcollectionutility.h> |
|
29 #include <mpxharvesterutility.h> |
|
30 #include <mpxplaybackutility.h> |
|
31 #include <mpxlog.h> |
|
32 #include <mpxmessagegeneraldefs.h> |
|
33 #include <mpxcollectionmessage.h> |
|
34 #include <mpxcollectionmessagedefs.h> |
|
35 #include <mpxsubscription.h> |
|
36 #include <mpxharvestercommon.h> |
|
37 |
|
38 #ifdef RD_MPX_TNM_INTEGRATION |
|
39 #include <hash.h> |
|
40 #include <eikenv.h> |
|
41 #include <f32file.h> |
|
42 #include <sysutil.h> |
|
43 #include <thumbnailmanager.h> |
|
44 #endif //RD_MPX_TNM_INTEGRATION |
|
45 // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode |
|
46 #include <UsbWatcherInternalPSKeys.h> |
|
47 #include <usbpersonalityids.h> |
|
48 #include <mpxcollectionuihelper.h> |
|
49 #include "mpxcollectionuihelperobserver.h" |
|
50 #include "mpxcollectionhelpercommon.h" |
|
51 |
|
52 #include "mpxdeletehelper.h" |
|
53 |
|
54 // Constants |
|
55 const TInt KSQLErrGeneral = -311; // SQL General error. Don't want to include sql header here |
|
56 const TInt KDeleteUpdateCount = 50; // Max # of times to update delete status during a group delete. Value (1-100) |
|
57 #ifdef RD_MPX_TNM_INTEGRATION |
|
58 _LIT( KImageFileType, "image/jpeg" ); |
|
59 #endif //RD_MPX_TNM_INTEGRATION |
|
60 |
|
61 // --------------------------------------------------------------------------- |
|
62 // Constructor |
|
63 // --------------------------------------------------------------------------- |
|
64 // |
|
65 CMPXDeleteHelper::CMPXDeleteHelper(MMPXCollectionUtility& aCollectionUtility, |
|
66 MMPXHarvesterUtility& aHarvesterUtility, |
|
67 MMPXCHelperObserver& aObserver) |
|
68 : CActive(CActive::EPriorityLow), |
|
69 iCollectionUtil(aCollectionUtility), |
|
70 iHarvester(aHarvesterUtility), |
|
71 iObserver(aObserver), |
|
72 iMoreToDo(ETrue), |
|
73 iHadInUse(EFalse), |
|
74 iState(EMPXIdle), |
|
75 iDeletePercent(0), |
|
76 iDeleteIncFactor(1), |
|
77 iDeleteCount(0), |
|
78 iUsbManConnected( EFalse ) |
|
79 { |
|
80 CActiveScheduler::Add(this); |
|
81 } |
|
82 |
|
83 // --------------------------------------------------------------------------- |
|
84 // 2nd Phase Constructor |
|
85 // --------------------------------------------------------------------------- |
|
86 // |
|
87 void CMPXDeleteHelper::ConstructL() |
|
88 { |
|
89 iFiles = new(ELeave)CDesCArrayFlat(4); |
|
90 iMessageArray = CMPXMessageArray::NewL(); |
|
91 // Connect to usbman |
|
92 ConnectUsbMan(); |
|
93 |
|
94 #ifdef __USE_MESSAGE_SUBSCRIPTION |
|
95 // Subscribe to only a few messages from collection utility |
|
96 CMPXSubscription* subscription( CMPXSubscription::NewL() ); |
|
97 CleanupStack::PushL( subscription ); |
|
98 CMPXSubscriptionItem* subItem1( CMPXSubscriptionItem::NewL() ); |
|
99 CleanupStack::PushL( subItem1 ); |
|
100 subItem1->SetTObjectValueL( KMPXMessageGeneralId, KMPXMessageGeneral ); |
|
101 subItem1->SetTObjectValueL( KMPXMessageGeneralEvent, TMPXCollectionMessage::EBroadcastEvent ); |
|
102 subItem1->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgFormatStart ); |
|
103 subscription->AddItemL( *subItem1 ); |
|
104 CMPXSubscriptionItem* subItem2( CMPXSubscriptionItem::CopyL( *subItem1 )); |
|
105 CleanupStack::PushL( subItem2 ); |
|
106 subItem2->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgDiskRemoved ); |
|
107 subscription->AddItemL( *subItem2 ); |
|
108 CMPXSubscriptionItem* subItem3( CMPXSubscriptionItem::CopyL( *subItem1 )); |
|
109 CleanupStack::PushL( subItem3 ); |
|
110 subItem3->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgUSBMassStorageStart ); |
|
111 subscription->AddItemL( *subItem3 ); |
|
112 CMPXSubscriptionItem* subItem4( CMPXSubscriptionItem::CopyL( *subItem1 )); |
|
113 CleanupStack::PushL( subItem4 ); |
|
114 subItem4->SetTObjectValueL( KMPXMessageGeneralType, EMcMsgUSBMTPStart ); |
|
115 subscription->AddItemL( *subItem4 ); |
|
116 CMPXSubscriptionItem* subItem5( CMPXSubscriptionItem::CopyL( *subItem1 )); |
|
117 CleanupStack::PushL( subItem5 ); |
|
118 iCollectionUtil.Collection().AddSubscriptionL( *subscription ); |
|
119 CleanupStack::PopAndDestroy( subItem5 ); |
|
120 CleanupStack::PopAndDestroy( subItem4 ); |
|
121 CleanupStack::PopAndDestroy( subItem3 ); |
|
122 CleanupStack::PopAndDestroy( subItem2 ); |
|
123 CleanupStack::PopAndDestroy( subItem1 ); |
|
124 CleanupStack::PopAndDestroy( subscription ); |
|
125 #endif |
|
126 |
|
127 #ifdef RD_MPX_TNM_INTEGRATION |
|
128 |
|
129 // Create Thumbnail Manager instance. This object is the observer. |
|
130 iTNManager = CThumbnailManager::NewL( *this ); |
|
131 #endif //RD_MPX_TNM_INTEGRATION |
|
132 } |
|
133 |
|
134 |
|
135 // --------------------------------------------------------------------------- |
|
136 // Two-Phased Constructor |
|
137 // --------------------------------------------------------------------------- |
|
138 // |
|
139 CMPXDeleteHelper* CMPXDeleteHelper::NewL(MMPXCollectionUtility& aCollectionUtility, |
|
140 MMPXHarvesterUtility& aHarvesterUtility, |
|
141 MMPXCHelperObserver& aObserver) |
|
142 { |
|
143 CMPXDeleteHelper* self = |
|
144 new(ELeave)CMPXDeleteHelper( aCollectionUtility, |
|
145 aHarvesterUtility, |
|
146 aObserver ); |
|
147 CleanupStack::PushL( self ); |
|
148 self->ConstructL(); |
|
149 CleanupStack::Pop( self ); |
|
150 return self; |
|
151 } |
|
152 |
|
153 // --------------------------------------------------------------------------- |
|
154 // Destructor |
|
155 // --------------------------------------------------------------------------- |
|
156 // |
|
157 CMPXDeleteHelper::~CMPXDeleteHelper() |
|
158 { |
|
159 if( iPbUtil ) |
|
160 { |
|
161 iPbUtil->Close(); |
|
162 } |
|
163 delete iDeletePath; |
|
164 delete iFiles; |
|
165 delete iMessageArray; |
|
166 #ifdef RD_MPX_TNM_INTEGRATION |
|
167 |
|
168 delete iTNManager; |
|
169 #endif //RD_MPX_TNM_INTEGRATION |
|
170 if ( iUsbManConnected ) |
|
171 { |
|
172 iUsbMan.Close(); |
|
173 } |
|
174 } |
|
175 |
|
176 // --------------------------------------------------------------------------- |
|
177 // Start the delete operation |
|
178 // --------------------------------------------------------------------------- |
|
179 // |
|
180 void CMPXDeleteHelper::DeleteL( CMPXCollectionPath& aPath ) |
|
181 { |
|
182 MPX_DEBUG1("CMPXDeleteHelper::DeleteL()"); |
|
183 MPX_DEBUG_PATH(aPath); |
|
184 TInt deletePercentFactor = 100 / KDeleteUpdateCount; |
|
185 |
|
186 if( iPbUtil ) |
|
187 { |
|
188 iPbUtil->Close(); |
|
189 iPbUtil = NULL; |
|
190 } |
|
191 iPbUtil = MMPXPlaybackUtility::UtilityL(); |
|
192 |
|
193 iDeletePath = CMPXCollectionPath::NewL( aPath ); |
|
194 iState = EMPXInitDelete; |
|
195 iDeleteCount = 0; |
|
196 iMessageArray->Reset(); |
|
197 RArray<TMPXItemId> selections; |
|
198 CleanupClosePushL(selections); |
|
199 iDeletePath->SelectionL(selections); |
|
200 iItemsCount = selections.Count(); |
|
201 CleanupStack::PopAndDestroy(&selections); |
|
202 iRetrievedItemsCount = 0; |
|
203 |
|
204 // Calculate percent increment factor used during a delete. |
|
205 if ( (iItemsCount > 0) && (iItemsCount < KDeleteUpdateCount) ) |
|
206 { |
|
207 TReal factor = (KDeleteUpdateCount/iItemsCount) * deletePercentFactor; |
|
208 iDeleteIncFactor = factor; |
|
209 } |
|
210 else |
|
211 { |
|
212 iDeleteIncFactor = deletePercentFactor; |
|
213 } |
|
214 |
|
215 TRequestStatus* status = &iStatus; |
|
216 *status = KRequestPending; |
|
217 User::RequestComplete(status, KErrNone); |
|
218 |
|
219 SetActive(); |
|
220 } |
|
221 |
|
222 // --------------------------------------------------------------------------- |
|
223 // From MMPXCollectionObserver |
|
224 // to-do: this should be changed to HandleCollectionMessage |
|
225 // --------------------------------------------------------------------------- |
|
226 // |
|
227 void CMPXDeleteHelper::HandleCollectionMessage(CMPXMessage* aMessage, TInt /*aErr*/) |
|
228 { |
|
229 if( aMessage && |
|
230 aMessage->IsSupported(KMPXMessageGeneralEvent) && |
|
231 aMessage->IsSupported(KMPXMessageGeneralType) ) |
|
232 { |
|
233 TInt event( aMessage->ValueTObjectL<TInt>( KMPXMessageGeneralEvent ) ); |
|
234 TInt op( aMessage->ValueTObjectL<TInt>( KMPXMessageGeneralType ) ); |
|
235 |
|
236 MPX_DEBUG3( "CMPXDeleteHelper::HandleCollectionMessageL event = %d, type = %d", |
|
237 event, op ); |
|
238 |
|
239 if( event == TMPXCollectionMessage::EBroadcastEvent ) |
|
240 { |
|
241 if( op == EMcMsgFormatStart || |
|
242 op == EMcMsgDiskRemoved || |
|
243 op == EMcMsgUSBMassStorageStart || |
|
244 op == EMcMsgUSBMTPStart ) |
|
245 { |
|
246 iCancelled = ETrue; |
|
247 Cancel(); |
|
248 } |
|
249 } |
|
250 |
|
251 } |
|
252 } |
|
253 |
|
254 // --------------------------------------------------------------------------- |
|
255 // Start the delete operation |
|
256 // --------------------------------------------------------------------------- |
|
257 // |
|
258 void CMPXDeleteHelper::DoTaskStep() |
|
259 { |
|
260 MPX_DEBUG1("CMPXDeleteHelper::DoTaskStep()"); |
|
261 |
|
262 TRequestStatus* status = &iStatus; |
|
263 *status = KRequestPending; |
|
264 |
|
265 TRAPD( error, DoTaskStepL() ); |
|
266 |
|
267 User::RequestComplete( status, error ); |
|
268 } |
|
269 |
|
270 // --------------------------------------------------------------------------- |
|
271 // Start the delete operation |
|
272 // to-do: delete file first before removing it from the collection |
|
273 // --------------------------------------------------------------------------- |
|
274 // |
|
275 void CMPXDeleteHelper::DoTaskStepL() |
|
276 { |
|
277 MPX_DEBUG1("CMPXDeleteHelper::DoTaskStepL()"); |
|
278 |
|
279 switch(iState) |
|
280 { |
|
281 case EMPXInitDelete: |
|
282 { |
|
283 StartDeleteL(); |
|
284 iState = EMPXPreparation; |
|
285 break; |
|
286 } |
|
287 case EMPXPreparation: |
|
288 { |
|
289 RetrieveFileListL(); |
|
290 iState = EMPXDelete; |
|
291 break; |
|
292 } |
|
293 |
|
294 case EMPXDelete: |
|
295 { |
|
296 DeleteL(); |
|
297 break; |
|
298 } |
|
299 |
|
300 default: |
|
301 break; |
|
302 } |
|
303 } |
|
304 |
|
305 // ---------------------------------------------------------------------------- |
|
306 // Handles request completion event |
|
307 // ---------------------------------------------------------------------------- |
|
308 // |
|
309 void CMPXDeleteHelper::RunL() |
|
310 { |
|
311 MPX_DEBUG3("CMPXDeleteHelper::RunL. [iMoreToDo %d] [iStatus %d]", iMoreToDo, iStatus.Int()); |
|
312 |
|
313 // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode |
|
314 TUsbDeviceState deviceState = EUsbDeviceStateConfigured; |
|
315 if ( !iUsbManConnected ) |
|
316 { |
|
317 ConnectUsbMan(); |
|
318 } |
|
319 |
|
320 if ( iUsbManConnected ) |
|
321 { |
|
322 if ( iUsbMan.GetDeviceState( deviceState ) != KErrNone ) |
|
323 { |
|
324 deviceState = EUsbDeviceStateConfigured; |
|
325 } |
|
326 } |
|
327 |
|
328 if ( deviceState == EUsbDeviceStateAddress || |
|
329 deviceState == EUsbDeviceStateConfigured ) |
|
330 { |
|
331 TInt usbStatus; |
|
332 RProperty::Get(KPSUidUsbWatcher, KUsbWatcherSelectedPersonality, usbStatus); |
|
333 if ((usbStatus == KUsbPersonalityIdMTP) || (usbStatus == KUsbPersonalityIdPCSuiteMTP)) |
|
334 { |
|
335 MPX_DEBUG1("USB is active, Stop Delete"); |
|
336 CompleteDelete( KErrLocked ); |
|
337 return; |
|
338 } |
|
339 } |
|
340 |
|
341 if (iMoreToDo && iStatus.Int() == KErrNone) |
|
342 { |
|
343 DoTaskStep(); |
|
344 SetActive(); |
|
345 } |
|
346 else |
|
347 { |
|
348 CompleteDelete(iStatus.Int()); |
|
349 } |
|
350 } |
|
351 |
|
352 // --------------------------------------------------------------------------- |
|
353 // Cancel the delete operation |
|
354 // --------------------------------------------------------------------------- |
|
355 // |
|
356 void CMPXDeleteHelper::DoCancel() |
|
357 { |
|
358 MPX_DEBUG3("CMPXDeleteHelper::DoCancel iStatus %d, iState %d", iStatus.Int(), iState); |
|
359 |
|
360 CompleteDelete(iStatus.Int()); |
|
361 } |
|
362 |
|
363 // --------------------------------------------------------------------------- |
|
364 // End state for a delete operation |
|
365 // --------------------------------------------------------------------------- |
|
366 // |
|
367 void CMPXDeleteHelper::CompleteDelete( TInt aErr ) |
|
368 { |
|
369 MPX_DEBUG2("CMPXDeleteHelper::CompleteDelete %d", aErr); |
|
370 |
|
371 TRAP_IGNORE( DoCompleteDeleteL( aErr ) ); |
|
372 } |
|
373 |
|
374 // --------------------------------------------------------------------------- |
|
375 // End state for a delete operation |
|
376 // --------------------------------------------------------------------------- |
|
377 // |
|
378 void CMPXDeleteHelper::DoCompleteDeleteL( TInt aErr ) |
|
379 { |
|
380 MPX_DEBUG3("CMPXDeleteHelper::CompleteDeleteL error %d cancelled %d", aErr, iCancelled); |
|
381 if( iState != EMPXIdle ) |
|
382 { |
|
383 // Finally callback to observer and complete task queue event |
|
384 // to-do: change HandleOperationCompletedL to HandleOperationComplete |
|
385 TInt error = iHadInUse ? KErrInUse : aErr; |
|
386 // Error cases that need to be ignored when mmc card is removed |
|
387 if( error == KErrBadName || |
|
388 error == KErrNotReady || |
|
389 error == KErrAbort || |
|
390 error == KSQLErrGeneral || |
|
391 (iCancelled && error == KErrNotFound) ) |
|
392 { |
|
393 error = KErrNone; |
|
394 } |
|
395 |
|
396 // Reset all states |
|
397 Reset(); |
|
398 |
|
399 // Close Harvester database transaction |
|
400 TRAP_IGNORE(iHarvester.CloseTransactionL() ); |
|
401 |
|
402 // Send a complete delete command to finish off the delete operation |
|
403 // |
|
404 CMPXCommand* cmd = CMPXCommand::NewL(); |
|
405 CleanupStack::PushL( cmd ); |
|
406 cmd->SetTObjectValueL(KMPXCommandGeneralId,KMPXCommandIdCollectionCompleteDelete); |
|
407 cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue); |
|
408 cmd->SetTObjectValueL(KMPXCommandCollectionDeleteCompactDb, ETrue); |
|
409 cmd->SetCObjectValueL(KMPXCommandCollectionDeleteMsgArray, iMessageArray); |
|
410 iCollectionUtil.Collection().CommandL(*cmd); |
|
411 CleanupStack::PopAndDestroy( cmd ); |
|
412 |
|
413 TRAP_IGNORE(iObserver.HandleOperationCompleteL( EDeleteOp, error, NULL ) ); |
|
414 |
|
415 // Message array ownership passed to engine |
|
416 delete iMessageArray; |
|
417 iMessageArray = NULL; |
|
418 iMessageArray = CMPXMessageArray::NewL(); |
|
419 |
|
420 if( iPbUtil ) |
|
421 { |
|
422 iPbUtil->Close(); |
|
423 iPbUtil = NULL; |
|
424 } |
|
425 iCancelled = EFalse; |
|
426 } |
|
427 } |
|
428 |
|
429 // --------------------------------------------------------------------------- |
|
430 // Resets members to get ready for the next client request |
|
431 // |
|
432 // --------------------------------------------------------------------------- |
|
433 // |
|
434 void CMPXDeleteHelper::Reset() |
|
435 { |
|
436 MPX_DEBUG1("CMPXDeleteHelper::Reset"); |
|
437 iMoreToDo = ETrue; |
|
438 iHadInUse = EFalse; |
|
439 iDeleteCount = 0; |
|
440 iDeletePercent = 0; |
|
441 iDeleteIncFactor = 1; |
|
442 |
|
443 iState = EMPXIdle; |
|
444 |
|
445 delete iDeletePath; |
|
446 iDeletePath = NULL; |
|
447 |
|
448 iFiles->Reset(); |
|
449 } |
|
450 |
|
451 // --------------------------------------------------------------------------- |
|
452 // Perfom cleanup of all unused data before delete |
|
453 // |
|
454 // --------------------------------------------------------------------------- |
|
455 // |
|
456 void CMPXDeleteHelper::StartDeleteL() |
|
457 { |
|
458 // |
|
459 // set up the command to send to the collection |
|
460 // |
|
461 CMPXCommand* command = CMPXCommand::NewL(); |
|
462 CleanupStack::PushL(command); |
|
463 |
|
464 command->SetTObjectValueL<TMPXCommandId>( |
|
465 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionPrepareDelete); |
|
466 command->SetTObjectValueL<TBool>( |
|
467 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue); |
|
468 command->SetCObjectValueL( |
|
469 TMPXAttribute(KMPXCommandIdCollectionPrepareDelete, EMPXCommandCollectionRetrievePath), |
|
470 iDeletePath); |
|
471 |
|
472 // send sync prepare delete URI command |
|
473 iCollectionUtil.Collection().CommandL(*command); |
|
474 CleanupStack::PopAndDestroy(command); |
|
475 } |
|
476 |
|
477 // |
|
478 // Retrieve files associated with the path |
|
479 // |
|
480 // --------------------------------------------------------------------------- |
|
481 // |
|
482 void CMPXDeleteHelper::RetrieveFileListL() |
|
483 { |
|
484 // |
|
485 // set up the command to send to the collection |
|
486 // |
|
487 CMPXCommand* command = CMPXCommand::NewL(); |
|
488 CleanupStack::PushL(command); |
|
489 |
|
490 command->SetTObjectValueL<TMPXCommandId>( |
|
491 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionRetrieveUriForDeletion); |
|
492 command->SetTObjectValueL<TBool>( |
|
493 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue); |
|
494 command->SetCObjectValueL( |
|
495 TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrievePath), |
|
496 iDeletePath); |
|
497 |
|
498 // send sync retrieve URI command |
|
499 iCollectionUtil.Collection().CommandL(*command); |
|
500 |
|
501 // |
|
502 // return command should contain error and URI array |
|
503 // |
|
504 if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveUriError)) || |
|
505 !command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveMediaUriArray))) |
|
506 { |
|
507 User::Leave(KErrAbort); |
|
508 } |
|
509 |
|
510 // |
|
511 // abandon operation if an error occured removing a media from the collection |
|
512 // |
|
513 TInt error = |
|
514 command->ValueTObjectL<TInt>( |
|
515 TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveUriError)); |
|
516 User::LeaveIfError(error); |
|
517 |
|
518 // |
|
519 // retrieve the list of files to be deleted |
|
520 // |
|
521 CDesCArray* files = |
|
522 command->ValueNoNewLCObjectL<CDesCArray>( |
|
523 TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrieveMediaUriArray)); |
|
524 CleanupStack::PushL(files); |
|
525 ::CopyArrayL(*files, *iFiles); |
|
526 iRetrievedItemsCount +=files->MdcaCount(); |
|
527 CleanupStack::PopAndDestroy(files); |
|
528 // |
|
529 // retrieve the updated path. If the original path ends at a particular artist, |
|
530 // album, genre, or composer, the path will have been expended to include the |
|
531 // songs under that category |
|
532 // |
|
533 delete iDeletePath; |
|
534 iDeletePath = NULL; |
|
535 iDeletePath = |
|
536 command->ValueCObjectL<CMPXCollectionPath>( |
|
537 TMPXAttribute(KMPXCommandIdCollectionRetrieveUriForDeletion, EMPXCommandCollectionRetrievePath)); |
|
538 |
|
539 CleanupStack::PopAndDestroy(command); |
|
540 } |
|
541 |
|
542 // --------------------------------------------------------------------------- |
|
543 // Deletes the file from the file system then deletes it from the collection |
|
544 // --------------------------------------------------------------------------- |
|
545 // |
|
546 void CMPXDeleteHelper::DeleteL() |
|
547 { |
|
548 MPX_FUNC("CMPXDeleteHelper::DeleteL()"); |
|
549 // Close the item that we are about to delete |
|
550 // |
|
551 RArray<TMPXItemId> selections; |
|
552 CleanupClosePushL(selections); |
|
553 iDeletePath->SelectionL(selections); |
|
554 |
|
555 TMPXItemId mediaId(0); |
|
556 if (selections.Count()) |
|
557 { |
|
558 // If more than one item |
|
559 mediaId = selections[0]; |
|
560 } |
|
561 else |
|
562 { |
|
563 mediaId = iDeletePath->Id(iDeletePath->Levels() - 1); |
|
564 } |
|
565 |
|
566 CleanupStack::PopAndDestroy(&selections); |
|
567 |
|
568 // Send the real id to playback engine for deletion |
|
569 iPbUtil->CommandL( EPbCmdCloseItem, mediaId ); |
|
570 |
|
571 // |
|
572 // delete the media file from the file system and harvester's database first |
|
573 // before deleting it from the collection |
|
574 // |
|
575 if (DeleteFileL()) |
|
576 { |
|
577 // |
|
578 // set up the command to send to the collection |
|
579 // |
|
580 CMPXCommand* command = CMPXMedia::NewL(); |
|
581 CleanupStack::PushL(command); |
|
582 |
|
583 command->SetTObjectValueL<TMPXCommandId>( |
|
584 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralId), KMPXCommandIdCollectionRemove); |
|
585 command->SetTObjectValueL<TBool>( |
|
586 TMPXAttribute(KMPXCommandContentIdGeneral, EMPXCommandGeneralDoSync), ETrue); |
|
587 command->SetCObjectValueL( |
|
588 TMPXAttribute(KMPXCommandIdCollectionRemove,EMPXCommandCollectionRemovePath), |
|
589 iDeletePath); |
|
590 command->SetTObjectValueL<TInt>( |
|
591 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveMediaCount), 1); |
|
592 command->SetTObjectValueL<TBool>(KMPXCommandCollectionRemoveSuppressMsgs,ETrue); |
|
593 command->SetCObjectValueL<CMPXMessageArray>(KMPXCommandCollectionChangeMsgs, iMessageArray); |
|
594 // send sync remove command |
|
595 MPX_PERF_START( MPX_PERF_DELETE_COLLECTION ); |
|
596 iCollectionUtil.Collection().CommandL(*command); |
|
597 MPX_PERF_END( MPX_PERF_DELETE_COLLECTION ); |
|
598 |
|
599 // |
|
600 // return command should contain error, completed and media Id information |
|
601 // |
|
602 if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveError)) || |
|
603 !command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveCompleted))) |
|
604 { |
|
605 User::Leave(KErrAbort); |
|
606 } |
|
607 |
|
608 // |
|
609 // abandon operation if an error occured removing a media from the collection |
|
610 // |
|
611 TInt error = |
|
612 command->ValueTObjectL<TInt>( |
|
613 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveError)); |
|
614 User::LeaveIfError(error); |
|
615 |
|
616 // |
|
617 // require to send async remove command again if command completed is EFalse |
|
618 // |
|
619 TBool completed = |
|
620 command->ValueTObjectL<TBool>( |
|
621 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemoveCompleted)); |
|
622 iMoreToDo = !completed; |
|
623 |
|
624 // |
|
625 // retrieve the updated path with the removed media deselected and use this |
|
626 // path for the next remove command |
|
627 // |
|
628 delete iDeletePath; |
|
629 iDeletePath = NULL; |
|
630 iDeletePath = |
|
631 command->ValueCObjectL<CMPXCollectionPath>( |
|
632 TMPXAttribute(KMPXCommandIdCollectionRemove, EMPXCommandCollectionRemovePath)); |
|
633 |
|
634 CleanupStack::PopAndDestroy(command); |
|
635 |
|
636 if (iFiles->MdcaCount()) |
|
637 { |
|
638 iFiles->Delete(0); |
|
639 } |
|
640 |
|
641 // Commit every 100 items deleted, message array ownership passed to engine |
|
642 // |
|
643 iDeleteCount++; |
|
644 if( iDeleteCount%KBatchCommit == 0 ) |
|
645 { |
|
646 // Commit Harvester DB |
|
647 TRAP_IGNORE( iHarvester.CloseTransactionL() ); |
|
648 |
|
649 // Commit Collection DB |
|
650 CMPXCommand* cmd = CMPXCommand::NewL(); |
|
651 CleanupStack::PushL( cmd ); |
|
652 cmd->SetTObjectValueL(KMPXCommandGeneralId,KMPXCommandIdCollectionCompleteDelete); |
|
653 cmd->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue); |
|
654 cmd->SetTObjectValueL(KMPXCommandCollectionDeleteCompactDb, ETrue); |
|
655 cmd->SetCObjectValueL(KMPXCommandCollectionDeleteMsgArray, iMessageArray); |
|
656 iCollectionUtil.Collection().CommandL(*cmd); |
|
657 |
|
658 delete iMessageArray; |
|
659 iMessageArray = NULL; |
|
660 iMessageArray = CMPXMessageArray::NewL(); |
|
661 CleanupStack::PopAndDestroy( cmd ); |
|
662 } |
|
663 } |
|
664 // |
|
665 // File not deleted from the file system, skip to the next |
|
666 // |
|
667 else |
|
668 { |
|
669 TArray<TInt> selectionIndices = iDeletePath->Selection(); |
|
670 if (selectionIndices.Count()) |
|
671 { |
|
672 iDeletePath->Deselect(selectionIndices[0]); |
|
673 } |
|
674 |
|
675 iFiles->Delete(0); |
|
676 } |
|
677 |
|
678 if (iFiles->MdcaCount() == 0) |
|
679 { |
|
680 if (iRetrievedItemsCount >= iItemsCount) |
|
681 { |
|
682 iMoreToDo = EFalse; |
|
683 iRetrievedItemsCount = 0; |
|
684 } |
|
685 else |
|
686 { |
|
687 iState = EMPXPreparation; |
|
688 } |
|
689 } |
|
690 |
|
691 // Send delete status when necessary. |
|
692 TInt deleteThreshold = ((iDeletePercent+iDeleteIncFactor)*iItemsCount)/100; |
|
693 if ( deleteThreshold > iItemsCount ) |
|
694 { |
|
695 deleteThreshold = iItemsCount; |
|
696 } |
|
697 if ( iDeleteCount >= deleteThreshold ) |
|
698 { |
|
699 iDeletePercent += iDeleteIncFactor; |
|
700 if ( (iDeletePercent > 100) || (iDeleteCount == iItemsCount) ) |
|
701 { |
|
702 iDeletePercent = 100; |
|
703 } |
|
704 CMPXMedia* media = CMPXMedia::NewL(); |
|
705 CleanupStack::PushL( media ); |
|
706 media->SetTObjectValueL( KMPXMediaGeneralCount, iDeletePercent ); |
|
707 iObserver.HandleOperationCompleteL( EDeleteStatusOp, KErrNone, media ); |
|
708 CleanupStack::Pop( media ); |
|
709 } |
|
710 } |
|
711 |
|
712 // --------------------------------------------------------------------------- |
|
713 // Deletes the file from the file system and harvester's database |
|
714 // --------------------------------------------------------------------------- |
|
715 // |
|
716 TBool CMPXDeleteHelper::DeleteFileL() |
|
717 { |
|
718 TBool deleted(ETrue); |
|
719 |
|
720 if (iFiles->MdcaCount() > 0) |
|
721 { |
|
722 TPtrC uri = iFiles->MdcaPoint(0); |
|
723 |
|
724 if( uri.Length() > 0 ) |
|
725 { |
|
726 // For playlist files, it's possible that we are deleting the file which |
|
727 // is not where the playlist is originated from. e.g. Playlist has been |
|
728 // renamed to Playlist(01) in the collection, after deleting Playlist(01) |
|
729 // from the collection, we are now attempting to delete Playlist(01).m3u |
|
730 // which is not the originating file. This is a known risk. |
|
731 CDesCArrayFlat* files = new (ELeave)CDesCArrayFlat(1); |
|
732 CleanupStack::PushL(files); |
|
733 files->AppendL(uri); |
|
734 |
|
735 MPX_PERF_START( MPX_PERF_DELHELPER_HARVESTER_DELETE ); |
|
736 TRAPD(err, iHarvester.DeleteFilesL(*files, EFalse)); // to-do: create a sync DeleteFileL in harvester |
|
737 MPX_PERF_END( MPX_PERF_DELHELPER_HARVESTER_DELETE ); |
|
738 |
|
739 // if the file cannot be found or is currently in use, skip to the next |
|
740 // media removal, but inform the client at the end that one of the files |
|
741 // is in use should that be the case |
|
742 if (err == KErrInUse) |
|
743 { |
|
744 iHadInUse = ETrue; |
|
745 deleted = EFalse; |
|
746 } |
|
747 else if ( err == KErrNotFound || |
|
748 err == KErrPathNotFound ) |
|
749 { |
|
750 // Cleanup harvester for broken links |
|
751 // Have to trap ignore because .vir virtual playlists |
|
752 // do not exist and we do not know the file is a playlist |
|
753 // Since it is already KErrNotFound or KErrPathNotFound, |
|
754 // |
|
755 TRAP_IGNORE(iHarvester.RemoveFilesL(*files)); |
|
756 } |
|
757 else |
|
758 { |
|
759 User::LeaveIfError(err); |
|
760 } |
|
761 |
|
762 CleanupStack::PopAndDestroy(files); //lint !e961 |
|
763 #ifdef RD_MPX_TNM_INTEGRATION |
|
764 const TDesC& file = iFiles->MdcaPoint(0); |
|
765 // remove from thumbnail manager |
|
766 CThumbnailObjectSource* source = CThumbnailObjectSource::NewLC( |
|
767 file, KImageFileType ); |
|
768 iTNManager->DeleteThumbnails( *source ); |
|
769 CleanupStack::PopAndDestroy( source ); |
|
770 // remove from local drive |
|
771 #endif //RD_MPX_TNM_INTEGRATION |
|
772 } |
|
773 } |
|
774 return deleted; |
|
775 } |
|
776 |
|
777 // --------------------------------------------------------------------------- |
|
778 // Stop deleting |
|
779 // --------------------------------------------------------------------------- |
|
780 // |
|
781 void CMPXDeleteHelper::Stop() |
|
782 { |
|
783 if ( iState != EMPXIdle ) |
|
784 { |
|
785 iMoreToDo = EFalse; |
|
786 } |
|
787 } |
|
788 |
|
789 // --------------------------------------------------------------------------- |
|
790 // Callback but not used here |
|
791 // --------------------------------------------------------------------------- |
|
792 void CMPXDeleteHelper::ThumbnailPreviewReady( |
|
793 MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ ) |
|
794 { |
|
795 } |
|
796 |
|
797 |
|
798 // --------------------------------------------------------------------------- |
|
799 // Callback but not used here |
|
800 // --------------------------------------------------------------------------- |
|
801 void CMPXDeleteHelper::ThumbnailReady( TInt /*aError*/, |
|
802 MThumbnailData& /*aThumbnail*/, TThumbnailRequestId /*aId*/ ) |
|
803 { |
|
804 } |
|
805 |
|
806 // --------------------------------------------------------------------------- |
|
807 // CMPXDeleteHelper::ConnectUsbMan |
|
808 // --------------------------------------------------------------------------- |
|
809 void CMPXDeleteHelper::ConnectUsbMan() |
|
810 { |
|
811 MPX_FUNC("CMPXDeleteHelper::ConnectUsbMan()"); |
|
812 if ( iUsbMan.Connect() == KErrNone ) |
|
813 { |
|
814 iUsbManConnected = ETrue; |
|
815 } |
|
816 } |
|
817 |
|
818 // END OF FILE |