applicationmanagement/server/src/amstorage.cpp
changeset 0 3ce708148e4d
child 57 6757f1e2efd2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applicationmanagement/server/src/amstorage.cpp	Thu Dec 17 08:40:12 2009 +0200
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) 2000 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: Implementation of applicationmanagement components
+ *
+ */
+
+#include "amstorage.h"
+#include <centralrepository.h>
+#include "AMDeploymentComponent.h"
+#include "debug.h"
+#include <s32mem.h>
+#include "amprivateCRKeys.h"
+#include <s32file.h>
+#include <e32des8.h>
+#ifndef __SERIES60_30__
+#include "AMAppHideUtil.h"
+#endif
+
+using namespace NApplicationManagement;
+
+// CONSTANTS
+
+
+/***************************************************
+ // RComponentIdArray
+ ***************************************************/
+
+void RComponentIdArray::SetListL(const TDesC8& aChilds)
+    {
+#ifdef _DEBUG
+    HBufC *b = HBufC::NewLC(aChilds.Length() );
+    TPtr p(b->Des() );
+    p.Copy(aChilds);
+    RDEBUG_2( "RComponentIdArray::SetListL: Setting list from: '%S'", &p);
+    CleanupStack::PopAndDestroy(b);
+#endif
+
+    RDesReadStream buf(aChilds);
+    //TInt size( buf.Source()->TellL( MStreamBuf::ERead ).SizeL() );
+    TInt left(aChilds.Length() );
+    const TInt KSize(sizeof(TUint32));
+    while (left > 0)
+        {
+        TUint32 val(buf.ReadUint32L() );
+#ifdef _DEBUG
+        RDEBUG_2( "RComponentIdArray::SetListL: Appending id: '%d'", val);
+#endif
+        Append(val);
+        left -= KSize;
+        }
+    buf.Close();
+    }
+
+void RComponentIdArray::RemoveByValue(TUint32 aValue)
+    {
+    TInt ind(Find(aValue) );
+    Remove(ind);
+    }
+
+void RComponentIdArray::GetListLC(HBufC8 *&aChilds, TInt &aLength)
+    {
+    ASSERT( aChilds == NULL );
+    TInt c(Count() );
+    if (c > 0)
+        {
+        aLength = c * sizeof(TUint32);
+        aChilds = HBufC8::NewLC(aLength);
+        TPtr8 p(aChilds->Des() );
+        RDesWriteStream stream(p);
+        CleanupClosePushL(stream);
+        TInt i( 0);
+        do
+            {
+            stream.WriteUint32L(operator[](i) );
+            }
+        while ( ++i < c);
+        stream.CommitL();
+        CleanupStack::PopAndDestroy( &stream);
+        }
+    else
+        {
+        aChilds = KNullDesC8().AllocLC();
+        aLength = 0;
+        }
+    }
+
+/*	
+ void TCertInfoPckg::ExternalizeL(RWriteStream& aStream) const
+ {
+ aStream << iId;
+ TPckgBuf<TCertInfo>::ExternalizeL( aStream );
+ }
+
+ void TCertInfoPckg::InternalizeL(RReadStream& aStream)
+ {
+ 
+ }
+ */
+
+void RCertArray::ExternalizeL(RWriteStream& aStream) const
+    {
+    TInt c(Count() );
+    aStream.WriteInt32L(c);
+    for (TInt i( 0); i < c; i++)
+        {
+        aStream.WriteInt32L(i);
+        aStream << (*(operator[](i)));
+        }
+    }
+
+void RCertArray::InternalizeL(RReadStream& aStream)
+    {
+    TInt c(aStream.ReadInt32L() );
+    for (TInt i( 0); i < c; i++)
+        {
+        TCertInfoPckg *pkg = new ( ELeave ) TCertInfoPckg;
+        RDEBUG_2( "RCertArray::InternalizeL - allocated TCertInfoPckg 0x%X", reinterpret_cast<TUint>( pkg ) );
+        CleanupStack::PushL(pkg);
+        TInt idx(aStream.ReadInt32L() );
+        aStream >> (*pkg);
+        Append(pkg);
+        CleanupStack::Pop(pkg);
+        }
+    }
+
+TInt RCertArray::FindByValue(const TCertInfoPckg &aPckg)
+    {
+    TInt c(Count() );
+    for (TInt i( 0); i < c; i++)
+        {
+        if (operator[](i)->Compare(aPckg) == 0)
+            {
+            return i;
+            }
+        }
+    return KErrNotFound;
+    }
+
+/***************************************************
+ // CDeliveryComponentStorage
+ ***************************************************/
+
+CDeliveryComponentStorage::CDeliveryComponentStorage()
+    {
+
+    }
+
+void CDeliveryComponentStorage::ConstructL()
+    {
+#ifndef __SERIES60_30__
+    iHidder = CAMAppHideUtil::NewL();
+#endif
+    LoadCertsL();
+    TRAPD( erx, iRepository = CRepository::NewL ( KCRUidPrivateApplicationManagementKeys ) )
+    ;
+    if (erx != KErrNone)
+        {
+        RDEBUG_2( "CDeliveryComponentStorage::ConstructL() ERROR CentRep not initialized: Check deployment! %d", erx );
+        User::Leave(erx);
+        }
+    TInt err(iRepository->Get(KNextIdKey, iNextId) );
+    if (err == KErrNotFound)
+        {
+        iNextId = KMinIdValue;
+        User::LeaveIfError(iRepository->Create(KNextIdKey, iNextId) );
+        }
+    else
+        {
+        User::LeaveIfError(err);
+        }
+    LoadComponentsL();
+    }
+
+void CDeliveryComponentStorage::LoadCertsL()
+    {
+    RFs fs;
+    User::LeaveIfError(fs.Connect() );
+    CleanupClosePushL(fs);
+    TInt e(fs.CreatePrivatePath(KDefaultDrive) );
+
+    User::LeaveIfError(e);
+    TBuf<64> privatePath;
+    User::LeaveIfError(fs.PrivatePath(privatePath) );
+
+    TInt privPathLength(privatePath.Length() );
+    _LIT( KCertFile, "amcerts.dat");
+    HBufC *afile = HBufC::NewLC(privPathLength + KCertFile().Length());
+    *afile = privatePath;
+    afile->Des().Append(KCertFile);
+    RFileReadStream certFile;
+    TInt err(certFile.Open(fs, *afile, EFileRead) );
+    if (err == KErrNone)
+        {
+        CleanupClosePushL(certFile);
+        iCertificates.InternalizeL(certFile);
+        CleanupStack::PopAndDestroy( &certFile);
+        }
+    else
+        if (err == KErrNotFound)
+            {
+
+            }
+        else
+            {
+            User::Leave(err);
+            }
+    CleanupStack::PopAndDestroy(afile);
+    CleanupStack::PopAndDestroy( &fs);
+    }
+
+CDeliveryComponentStorage* CDeliveryComponentStorage::NewLC()
+    {
+    CDeliveryComponentStorage *self = new ( ELeave ) CDeliveryComponentStorage( );
+    CleanupStack::PushL(self) ;
+    self->ConstructL() ;
+    return self;
+    }
+
+CDeliveryComponentStorage* CDeliveryComponentStorage::NewL()
+    {
+    CDeliveryComponentStorage *self = NewLC();
+    CleanupStack::Pop(self) ;
+    return self;
+    }
+
+TInt CDeliveryComponentStorage::NextKey()
+    {
+    TInt oldNext(iNextId++);
+    iRepository->Set(KNextIdKey, iNextId);
+    return oldNext;
+    }
+
+CDeliveryComponentStorage::~CDeliveryComponentStorage()
+    {
+    RDEBUG_3( "CDeliveryComponentStorage::~CDeliveryComponentStorage 0x%X - 0x%X", reinterpret_cast<TUint>(this),
+            reinterpret_cast<TUint>(this)+sizeof( CDeliveryComponentStorage ) );
+    delete iRepository;
+    iRepository = NULL;
+    iComponents.ResetAndDestroy();
+    iComponentIds.Close();
+    TRAPD( err,CloseCertificatesL() )
+    ;
+    if (err != KErrNone)
+        {
+        RDEBUG_2( "CDeliveryComponentStorage::~CDeliveryComponentStorage: ERROR Failed to close certificate storage properly: %d", err);
+        }
+#ifndef __SERIES60_30__
+    delete iHidder;
+    iHidder = NULL;
+#endif
+    }
+
+void CDeliveryComponentStorage::CloseCertificatesL()
+    {
+    RFs fs;
+    User::LeaveIfError(fs.Connect() );
+    CleanupClosePushL(fs);
+    TInt e(fs.CreatePrivatePath(KDefaultDrive) );
+
+    User::LeaveIfError(e);
+    TBuf<64> privatePath;
+    User::LeaveIfError(fs.PrivatePath(privatePath) );
+
+    TInt privPathLength(privatePath.Length() );
+    _LIT( KCertFile, "amcerts.dat");
+    HBufC *afile = HBufC::NewLC(privPathLength + KCertFile().Length());
+    *afile = privatePath;
+    afile->Des().Append(KCertFile);
+    RFileWriteStream certFile;
+
+    TInt err(certFile.Replace(fs, *afile, EFileWrite) );
+    if (err == KErrNone)
+        {
+        CleanupClosePushL(certFile);
+        iCertificates.ExternalizeL(certFile);
+        CleanupStack::PopAndDestroy( &certFile);
+        }
+    else
+        if (err == KErrNotFound)
+            {
+
+            }
+        else
+            {
+            User::Leave(err);
+            }
+    CleanupStack::PopAndDestroy(afile);
+    CleanupStack::PopAndDestroy( &fs);
+    iCertificates.ResetAndDestroy();
+    }
+
+const RComponentIdArray &CDeliveryComponentStorage::GetComponentIds() const
+    {
+    return iComponentIds;
+    }
+
+void CDeliveryComponentStorage::GetStateChangeComponentIdsL(
+        RComponentIdArray &aArray)
+    {
+    RDEBUG_2( "CDeliveryComponentStorage::GetStateChangeComponentIdsL %d dcs", iComponentIds.Count());
+    aArray.Reset();
+    TInt c(iComponentIds.Count() );
+    for (TInt i( 0); i < c; i++)
+        {
+        CDeploymentComponent &compo = ComponentL(iComponentIds[i]);
+        if (compo.OldState() != EDCSNone)
+            {
+            aArray.Append(iComponentIds[i]);
+            }
+        }
+    RDEBUG( "CDeliveryComponentStorage::GetStateChangeComponentIdsL end");
+    }
+
+void CDeliveryComponentStorage::StateChangedL(TUint32 aInternalId)
+    {
+    RDEBUG_2( "CDeliveryComponentStorage::StateChangedL id %d", aInternalId);
+    CDeploymentComponent &compo = ComponentL(aInternalId);
+    compo.StateChangeComplete();
+    UpdateL(compo);
+    }
+
+void CDeliveryComponentStorage::LoadComponentsL()
+    {
+    TInt length( 0);
+    TInt err(iRepository->Get(KIdListLengthKey, length) );
+    if (err == KErrNotFound)
+        {
+        length = 0;
+        User::LeaveIfError(iRepository->Create(KIdListLengthKey, length) );
+        }
+    else
+        {
+        User::LeaveIfError(err);
+        }
+    HBufC8 *listbuf = HBufC8::NewLC(length) ;
+    TPtr8 ptr(listbuf->Des() );
+    err = iRepository->Get(KIdListKey, ptr) ;
+    if (err == KErrNotFound)
+        {
+        err = iRepository->Create(KIdListKey, KNullDesC8);
+        }
+    else
+        {
+
+        }
+    User::LeaveIfError(err);
+    TRAPD(code, iComponentIds.SetListL( ptr ))
+    ;
+    if (code != KErrEof)
+        {
+        User::LeaveIfError(code);
+        }
+
+    CleanupStack::PopAndDestroy(listbuf);
+#ifndef __SERIES60_30__
+    TInt i(iComponentIds.Count() );
+    //iHidder->Reset();
+    while ( --i >= 0)
+        {
+        CDeploymentComponent &comp = ComponentL(iComponentIds[i]);
+        if (comp.State() == EDCSInactive)
+            {
+            iHidder->AddUidL(comp.Uid());
+            }
+        else
+            if (comp.State() == EDCSActive)
+                {
+                iHidder->RemoveUidL(comp.Uid() );
+                }
+        }
+    iHidder->PersistUidsL();
+#endif
+
+    }
+
+CDeploymentComponent *CDeliveryComponentStorage::NewComponentL(
+        const TDeploymentComponentState &aState, const TDCUserId &aUserId,
+        const TCertInfo *aCertInfo/* = NULL */)
+    {
+    CDeploymentComponent *newc = CDeploymentComponent::NewLC(NextKey(),
+            aUserId);
+    if (aCertInfo != NULL)
+        {
+        TCertInfoPckg *p = new( ELeave ) TCertInfoPckg(*aCertInfo);
+        RDEBUG_2( "CDeliveryComponentStorage::NewComponentL - allocated TCertInfoPckg 0x%X", reinterpret_cast<TUint>( p ) );
+
+        TInt idx(iCertificates.FindByValue(*p) );
+        if (idx == KErrNotFound)
+            {
+            RDEBUG_2( "CDeliveryComponentStorage::NewComponentL - TCertInfoPckg NOT found 0x%X", reinterpret_cast<TUint>( p ) );
+            iCertificates.Append(p);
+            idx = iCertificates.Count() - 1;
+            }
+        else
+            {
+            RDEBUG_2( "CDeliveryComponentStorage::NewComponentL - TCertInfoPckg found at %d, deleting temporary", idx );
+            delete p;
+            p = NULL;
+            }
+        if (idx >= 0)
+            {
+            RDEBUG_2( "CDeliveryComponentStorage::NewComponentL - TCertInfoPckg found 0x%X", reinterpret_cast<TUint>( p ) );
+            newc->SetOwner(idx);
+            }
+        else
+            {
+            RDEBUG_3( "CDeliveryComponentStorage::NewComponentL - WARNING Could not add certificate 0x%X: %d", reinterpret_cast<TUint>( p ), idx );
+
+            }
+        }
+    newc->SetState(aState);
+    newc->SetStatusNode(EIdle);
+    UpdateL( *newc);
+    iComponents.Append(newc);
+    iComponentIds.Append(newc->InternalId() );
+RDEBUG_2( "CDeliveryComponentStorage::NewComponentL -Internal ID is  %d, ", newc->InternalId() );
+    PersistStateL();
+    CleanupStack::Pop(newc);
+    return newc;
+    }
+
+void CDeliveryComponentStorage::UpdateL(
+        const CDeploymentComponent &aComponent)
+    {
+    aComponent.PersistL( *iRepository) ;
+
+#ifndef __SERIES60_30__
+    if (aComponent.State() == EDCSInactive)
+        {
+        iHidder->AddUidL(aComponent.Uid(), ETrue);
+        }
+    else
+        {
+        iHidder->RemoveUidL(aComponent.Uid(), ETrue);
+        }
+#endif
+    }
+
+void CDeliveryComponentStorage::PersistStateL()
+    {
+    TInt length( 0);
+    HBufC8 *buf= NULL;
+    iComponentIds.GetListLC(buf, length);
+    User::LeaveIfError(iRepository->Set(KIdListLengthKey, length) );
+    User::LeaveIfError(iRepository->Set(KIdListKey, *buf) );
+    CleanupStack::PopAndDestroy(buf);
+    }
+
+void CDeliveryComponentStorage::RemoveL(TUint32 aInternalId)
+    {
+    RDEBUG_2("CDeliveryComponentStorage::RemoveL - Remove id: (%d)", aInternalId );
+    TInt count(iComponents.Count() );
+    for (TInt i( 0); i < count; i++)
+        {
+        CDeploymentComponent *el = iComponents[i];
+        if (aInternalId == el->iInternalId)
+            {
+#ifndef __SERIES60_30__
+            iHidder->RemoveUidL(el->Uid(), ETrue);
+#endif
+            iComponents.Remove(i);
+            iComponentIds.RemoveByValue(aInternalId);
+            el->DestroyL( *iRepository);
+            delete el;
+            RDEBUG_2("CDeliveryComponentStorage::RemoveL - Removed id: (%d)", aInternalId );
+            PersistStateL();
+            break;
+            }
+        }
+    }
+
+CDeploymentComponent &CDeliveryComponentStorage::ComponentL(
+        TUint32 aInternalId)
+    {
+    CDeploymentComponent *resp= NULL;
+    TInt count(iComponents.Count() );
+    for (TInt i( 0); i < count; i++)
+        {
+        CDeploymentComponent *el = iComponents[i];
+        if (aInternalId == el->iInternalId)
+            {
+            resp = el;
+            break;
+            }
+        }
+    if (resp == NULL)
+        {
+        TBuf8< NCentralRepositoryConstants::KMaxBinaryLength> buf;
+        TInt err(iRepository->Get(aInternalId, buf) );
+        User::LeaveIfError(err) ;
+        resp = LoadComponentL(aInternalId, buf) ;
+        iComponents.Append(resp);
+        }
+    if (resp == NULL)
+        {
+        User::Leave(KErrNotFound);
+        }
+    return *resp;
+    }
+
+CDeploymentComponent *CDeliveryComponentStorage::LoadComponentL(
+        TInt aInternalId, const TDesC8 &aBuffer) const
+    {
+    CDeploymentComponent *res = CDeploymentComponent::LoadL(aInternalId,
+            aBuffer);
+#ifdef _DEBUG
+    if (res)
+        {
+        RDEBUG8_4( "CDeliveryComponentStorage::LoadComponentL - loaded component state %d, internalid %d, and userid: %S", res->State(), res->InternalId(),&res->UserId() );
+        }
+    else
+        {
+        RDEBUG( "CDeliveryComponentStorage::LoadComponentL - WARNING failed to load component" );
+        }
+#endif
+    return res;
+    }
+void CDeliveryComponentStorage::CheckForDuplicateNodesInDeployedL(
+        CDeploymentComponent &aComponent)
+    {
+    TInt CompIdsCount(iComponentIds.Count() );
+    RDEBUG8_2("CheckForDuplicateNodesInDeployedL: CompIdsCount-> (%d)", CompIdsCount );
+    RDEBUG8_2("CheckForDuplicateNodesInDeployedL: aComponent UserID is %S", &(aComponent.UserId()));
+    for (TInt i( 0); i < CompIdsCount; i++)
+        {
+        CDeploymentComponent &compo = ComponentL(iComponentIds[i]);
+        RDEBUG8_2("CheckForDuplicateNodesInDeployedL: compo UserID is %S", &(compo.UserId()));
+        if (&aComponent != &compo)
+        {
+        if (((compo.State()== EDCSActive) || (compo.State()== EDCSInactive))
+                &&(compo.UserId() == aComponent.UserId()))
+            {
+            (aComponent.iUserId).Append(*IntToDes8LC(aComponent.iInternalId));
+            CleanupStack::PopAndDestroy();
+            break;
+            }
+          }
+        }
+    }
+
+HBufC8* CDeliveryComponentStorage::IntToDes8LC(const TInt aLuid)
+    {
+    HBufC8* buf = HBufC8::NewLC( 10); //10 = max length of 32bit integer
+    TPtr8 ptrBuf = buf->Des();
+    ptrBuf.Num(aLuid);
+    return buf;
+    }
+
+void CDeliveryComponentStorage::InstalledL(CDeploymentComponent &aComponent)
+    {
+    CheckForDuplicateNodesInDeployedL(aComponent);
+    aComponent.SetState(EDCSActive);
+    // set state to IDLE 
+    aComponent.SetStatusNode(EIdle);
+    UpdateL(aComponent);
+    }
+
+void CDeliveryComponentStorage::DeactivateL(CDeploymentComponent &aComponent)
+    {
+    /* :
+     * set state to InActivate in progress
+     * use TRAP instead of leaving.
+     */
+    aComponent.SetStatusNode(EDeployed_DeactivateProgress);
+    //User::LeaveIfError(aComponent.SetState(EDCSInactive) );
+    TInt err = aComponent.SetState(EDCSInactive);
+    if (err == KErrNone)
+        {
+        TRAP(err,UpdateL(aComponent));
+        }
+    //UpdateL(aComponent);
+    /*:
+     * if error set state to InActivate failed or else set to Idle
+     * call userleaveiferror()
+     */
+    if (err == KErrNone)
+        {
+        aComponent.SetStatusNode(EIdle);
+        }
+    else
+        {
+        aComponent.SetStatusNode(EDeployed_DeactivateFailed);
+        }
+    User::LeaveIfError(err);
+    }
+
+void CDeliveryComponentStorage::SetDeploymentComponentState(CDeploymentComponent &aComponent,TDeploymentComponentState aState)
+    {
+    aComponent.SetState( aState );
+    TRAP_IGNORE(UpdateL( aComponent ));    
+    }
+
+void CDeliveryComponentStorage::ActivateL(CDeploymentComponent &aComponent)
+    {
+    /* :
+     * set state to Activate in progress
+     * use TRAP instead of leaving.
+     */
+    aComponent.SetStatusNode(EDeployed_ActivateProgress);
+    TInt err = aComponent.SetState(EDCSActive);
+    //UpdateL( aComponent );
+    if (err == KErrNone)
+        {
+        TRAP(err,UpdateL(aComponent));
+        }
+    /*:
+     * if error set state to InActivate failed or else set to Idle
+     * call userleaveiferror()
+     */
+    if (err == KErrNone)
+        {
+        aComponent.SetStatusNode(EIdle);
+        }
+    else
+        {
+        aComponent.SetStatusNode(EDeployed_ActivateFailed);
+        }
+    User::LeaveIfError(err);
+    }
+
+/*void CDeliveryComponentStorage::UninstalledL( CDeploymentComponent &aComponent )
+ {
+ aComponent.SetState( EDCSInactive );
+ UpdateL( aComponent );
+ }
+ 
+ void CDeliveryComponentStorage::ResetL()
+ {
+ }
+ */
+//  End of File