mtpdataproviders/mtpimagedp/src/cmtpimagedpdeleteobject.cpp
author hgs
Thu, 04 Nov 2010 15:31:42 +0800
changeset 60 841f70763fbe
parent 49 c20dd21d1eb4
permissions -rw-r--r--
201044_04

// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
/**
 @file
 @internalTechnology
 */
#include <bautils.h>
#include <mtp/cmtptypearray.h>
#include <mtp/cmtpobjectmetadata.h>
#include <mtp/mmtpdataproviderframework.h>
#include <mtp/mmtpobjectmgr.h>
#include <mtp/mtpprotocolconstants.h>
#include <mtp/mmtpstoragemgr.h>
#include <mtp/tmtptyperequest.h>
#include "cmtpimagedpdeleteobject.h"
#include "mtpimagedpconst.h"
#include "mtpimagedppanic.h"
#include "cmtpimagedpobjectpropertymgr.h"
#include "mtpimagedputilits.h"
#include "cmtpimagedp.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "cmtpimagedpdeleteobjectTraces.h"
#endif


/**
 Standard c++ constructor
 */
CMTPImageDpDeleteObject::CMTPImageDpDeleteObject(
        MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,
        CMTPImageDataProvider& aDataProvider) :
    CMTPRequestProcessor(aFramework, aConnection, 0, NULL),
    iDataProvider(aDataProvider),
    iResponseCode( EMTPRespCodeOK )
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_CMTPIMAGEDPDELETEOBJECT_CONS_ENTRY );
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_CMTPIMAGEDPDELETEOBJECT_CONS_EXIT );
    }

/**
 Two-phase construction method
 @param aFramework	The data provider framework
 @param aConnection	The connection from which the request comes
 @return a pointer to the created request processor object
 */
MMTPRequestProcessor* CMTPImageDpDeleteObject::NewL(
        MMTPDataProviderFramework& aFramework, MMTPConnection& aConnection,
        CMTPImageDataProvider& aDataProvider)
    {
    CMTPImageDpDeleteObject* self = new (ELeave) CMTPImageDpDeleteObject(
            aFramework, aConnection, aDataProvider);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
    }

void CMTPImageDpDeleteObject::ConstructL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_CONSTRUCTL_ENTRY );
    iObjectMeta = CMTPObjectMetaData::NewL();
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_CONSTRUCTL_EXIT );
    }
/**
 Destructor
 */
CMTPImageDpDeleteObject::~CMTPImageDpDeleteObject()
    {
    OstTraceFunctionEntry0( DUP1_CMTPIMAGEDPDELETEOBJECT_CMTPIMAGEDPDELETEOBJECT_DES_ENTRY );
    Cancel();
    delete iObjectMeta;
    iObjectsToDelete.Close();
    OstTraceFunctionExit0( DUP1_CMTPIMAGEDPDELETEOBJECT_CMTPIMAGEDPDELETEOBJECT_DES_EXIT );
    }

/**
 Verify the request
 @return EMTPRespCodeOK if request is verified, otherwise one of the error response codes
 */

TMTPResponseCode CMTPImageDpDeleteObject::CheckRequestL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_CHECKREQUESTL_ENTRY );
    TMTPResponseCode result = EMTPRespCodeOK;
    TUint32 handle(Request().Uint32(TMTPTypeRequest::ERequestParameter1));
    if ( handle != KMTPHandleAll )
        {
        result = CheckStorageL( handle );
        }
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_CHECKREQUESTL_EXIT );
    return result;
    }

/**
 DeleteObject request handler
 */
void CMTPImageDpDeleteObject::ServiceL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_SERVICEL_ENTRY );
    
    //begin to find object
    iObjectsToDelete.Reset();
    iResponseCode = EMTPRespCodeOK;
    iObjectsNotDelete = 0;
    TUint32 objectHandle( Request().Uint32( TMTPTypeRequest::ERequestParameter1 ));
    TUint32 formatCode( Request().Uint32( TMTPTypeRequest::ERequestParameter2 ));
    
    // Check to see whether the request is to delete all images or a specific image
    if ( objectHandle == KMTPHandleAll )
        {
        //add for test
        OstTrace0( TRACE_FLOW, CMTPIMAGEDPDELETEOBJECT_SERVICEL, "delete all objects" );
        GetObjectHandlesL( KMTPStorageAll, formatCode, KMTPHandleNone );
        iObjectsNotDelete = iObjectsToDelete.Count();
        Start();
        }
    else
        {
        //add for test
        OstTrace0( TRACE_FLOW, DUP1_CMTPIMAGEDPDELETEOBJECT_SERVICEL, "delete only one object" );
        iObjectsNotDelete = 1;
        DeleteObjectL( objectHandle );
        
        SendResponseL();
        }
    
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_SERVICEL_EXIT );
    }

void CMTPImageDpDeleteObject::RunL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_RUNL_ENTRY );
    
    TInt numObjectsToDelete = iObjectsToDelete.Count();
    
    if ( numObjectsToDelete > 0 )
        {
        DeleteObjectL( iObjectsToDelete[0] );
        iObjectsToDelete.Remove( 0 );
        }
    
    // Start the process again to read the next row...
    Start();

    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_RUNL_EXIT );
    }

void CMTPImageDpDeleteObject::DoCancel()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_DOCANCEL_ENTRY );
    
    TRAP_IGNORE( SendResponseL());

    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_DOCANCEL_EXIT );
    }

#ifdef OST_TRACE_COMPILER_IN_USE
TInt CMTPImageDpDeleteObject::RunError(TInt aErr)
#else
TInt CMTPImageDpDeleteObject::RunError(TInt /*aErr*/)
#endif
    {
    OstTrace1(TRACE_ERROR, CMTPIMAGEDPDELETEOBJECT_RUNERROR,"CMTPImageDpDeleteObject::RunError is %d", aErr );
	TRAP_IGNORE(CMTPRequestProcessor::SendResponseL(EMTPRespCodeGeneralError));
    return KErrNone;
    }

/**
 Check whether the store on which the object resides is read only.
 @return ETrue if the store is read only, EFalse if read-write
 */
TMTPResponseCode CMTPImageDpDeleteObject::CheckStorageL(TUint32 aObjectHandle)
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_CHECKSTORAGEL_ENTRY );
    TMTPResponseCode result = MTPImageDpUtilits::VerifyObjectHandleL(
            iFramework, aObjectHandle, *iObjectMeta);
    if (EMTPRespCodeOK == result)
        {
        TDriveNumber drive= static_cast<TDriveNumber>(iFramework.StorageMgr().DriveNumber(
                                                      iObjectMeta->Uint(CMTPObjectMetaData::EStorageId)));
        LEAVEIFERROR(drive,
                OstTraceExt2( TRACE_ERROR, CMTPIMAGEDPDELETEOBJECT_CHECKSTORAGEL, 
                        "No driver number for %d! error code %d",iObjectMeta->Uint(CMTPObjectMetaData::EStorageId), munged_err));        
        TVolumeInfo volumeInfo;
        LEAVEIFERROR(iFramework.Fs().Volume(volumeInfo, drive),
                OstTraceExt2( TRACE_ERROR, DUP1_CMTPIMAGEDPDELETEOBJECT_CHECKSTORAGEL, 
                        "Gets volume information for driver %d failed! error code %d", drive, munged_err ));
        if (volumeInfo.iDrive.iMediaAtt == KMediaAttWriteProtected)
            {
            result = EMTPRespCodeStoreReadOnly;
            }
        }
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_CHECKSTORAGEL_EXIT );
    return result;
    }

void CMTPImageDpDeleteObject::GetObjectHandlesL( TUint32 aStorageId, TUint32 aFormatCode, TUint32 aParentHandle )
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_GETOBJECTHANDLESL_ENTRY );

    RMTPObjectMgrQueryContext context;
    RArray<TUint> handles;
    TMTPObjectMgrQueryParams params( aStorageId, aFormatCode, aParentHandle, iFramework.DataProviderId());
    CleanupClosePushL( context ); // + context
    CleanupClosePushL( handles ); // + handles
    
    do
        {
        iFramework.ObjectMgr().GetObjectHandlesL( params, context, handles );
        for ( TInt i = 0; i < handles.Count(); i++)
            {
            iObjectsToDelete.AppendL( handles[i] );
            }
        }
    while ( !context.QueryComplete() );
    
    CleanupStack::PopAndDestroy( &handles ); // - handles
    CleanupStack::PopAndDestroy( &context ); // - context

    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_GETOBJECTHANDLESL_EXIT );
    }

void CMTPImageDpDeleteObject::DeleteObjectL( TUint32 aHandle )
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL_ENTRY );
    
    iFramework.ObjectMgr().ObjectL( aHandle, *iObjectMeta);
    iDataProvider.PropertyMgr().SetCurrentObjectL(*iObjectMeta, EFalse);
    TUint16 protectionStatus = EMTPProtectionNoProtection;
    iDataProvider.PropertyMgr().GetPropertyL(EMTPObjectPropCodeProtectionStatus, protectionStatus);
    if(EMTPProtectionNoProtection == protectionStatus)
        {
        TInt err = iFramework.Fs().Delete(iObjectMeta->DesC(CMTPObjectMetaData::ESuid));
        OstTrace1( TRACE_FLOW, CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL, "delete file error is %d", err );
        switch ( err )
            {
            case KErrInUse:
                //coverity[fallthrough]
            case KErrAccessDenied:
                //add for test 
                OstTrace1( TRACE_FLOW, DUP1_CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL, "err:%d", err );
                //add Suid to deleteobjectlist
                iDataProvider.AppendDeleteObjectsArrayL(iObjectMeta->DesC(CMTPObjectMetaData::ESuid));
                //coverity[unterminated_case]
            case KErrPathNotFound:
                //if the file does not exist on device, remove it from objectstore
                //coverity[fallthrough]
            case KErrNone:            
                //add for test   
                OstTrace0( TRACE_NORMAL, DUP2_CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL, "KErrNone" );
                //if the image object is new, we should update new picture count
                if (MTPImageDpUtilits::IsNewPicture(*iObjectMeta))
                    {
                    iDataProvider.DecreaseNewPictures(1);                 
                    }                
                iFramework.ObjectMgr().RemoveObjectL( iObjectMeta->Uint(CMTPObjectMetaData::EHandle ));              
                iObjectsNotDelete--;
                iResponseCode = EMTPRespCodePartialDeletion;
                break;
            default:
                //add for test
                OstTrace0( TRACE_NORMAL, DUP3_CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL, "default" );
                LEAVEIFERROR( err,
                        OstTraceExt2( TRACE_ERROR, DUP4_CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL, 
                                "delete %S failed! error code %d", iObjectMeta->DesC(CMTPObjectMetaData::ESuid), munged_err));
                break;
            }
        }
    else if ( iResponseCode != EMTPRespCodePartialDeletion )
        {
        iResponseCode = EMTPRespCodeObjectWriteProtected;
        }
    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_DELETEOBJECTL_EXIT );
    }

void CMTPImageDpDeleteObject::Start()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_START_ENTRY );
    
    if(iCancelled)
        {
        OstTrace0( TRACE_NORMAL, CMTPIMAGEDPDELETEOBJECT_START, "Cancell the delete" );
        TRAP_IGNORE(CMTPRequestProcessor::SendResponseL(EMTPRespCodeTransactionCancelled));
        iObjectsToDelete.Reset();
        iCancelled = EFalse;
        OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_START_EXIT );
        return;
        }
    
    TInt numObjectsToDelete = iObjectsToDelete.Count();

    if ( numObjectsToDelete > 0 )
        {
        //Set the active object going to delete the file
        TRequestStatus* status = &iStatus;
        User::RequestComplete( status, KErrNone );
        SetActive();
        }
    else
        {
        TRAP_IGNORE(SendResponseL());
        }
    OstTraceFunctionExit0( DUP1_CMTPIMAGEDPDELETEOBJECT_START_EXIT );
    }

void CMTPImageDpDeleteObject::SendResponseL()
    {
    OstTraceFunctionEntry0( CMTPIMAGEDPDELETEOBJECT_SENDRESPONSEL_ENTRY );
    
    if ( iResponseCode == EMTPRespCodePartialDeletion && iObjectsNotDelete == 0 )
        {
        iResponseCode = EMTPRespCodeOK;
        }
    CMTPRequestProcessor::SendResponseL( iResponseCode );

    OstTraceFunctionExit0( CMTPIMAGEDPDELETEOBJECT_SENDRESPONSEL_EXIT );
    }