--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/profilesservices/ProfileEngine/EngSrc/CProfileEngineImplDynamicProfiles.cpp Thu Dec 17 08:52:52 2009 +0200
@@ -0,0 +1,626 @@
+/*
+* Copyright (c) 2002 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 the CProfileEngineImpl.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "CProfileEngineImpl.h"
+#include <bautils.h>
+#include <barsc.h>
+#include <featmgr.h>
+#include <settingsinternalcrkeys.h>
+#include <sysutil.h>
+#include <accessoriescrkeys.h>
+
+#include <ProfileEng.rsg>
+#include <TProfileToneSettings.h>
+#include <MProfileTones.h>
+#include "CProfilesNamesArrayImpl.h"
+#include "CProfileImpl.h"
+#include "CProfileNameImpl.h"
+#include "ProfileEngUtils.h"
+#include "MProfileSetName.h"
+#include "ProfileEng.hrh"
+#include "ProfileEngPanic.h"
+#include "ProfileEngineConstants.h"
+#include "ProfileEnginePrivateCRKeys.h"
+
+namespace
+ {
+ const TInt KProfileGeneratedNameTailLength( 4 );
+ _LIT( KFirstParenthesis, "(" );
+ }
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+void GenerateProfileName( TDes& aProfileName, const MProfilesNamesArray& aProfileNames )
+ {
+ _LIT( KEndParenthesis, ")" );
+ _LIT( KZero, "0" );
+ TInt counter( 1 );
+ TBuf<KProfileMaxNameLength> rootName( aProfileName );
+ while( aProfileNames.FindByName( aProfileName ) != KErrNotFound &&
+ counter <= KProfilesMaxNumberOfDynamicProfiles )
+ {
+ aProfileName.Copy( rootName );
+ aProfileName.Append( KFirstParenthesis );
+ if( counter < 10 )
+ {
+ aProfileName.Append( KZero );
+ }
+ TBuf<KProfilesMaxTIntLength> number;
+ number.Num( counter );
+ aProfileName.Append( number );
+ aProfileName.Append( KEndParenthesis );
+ ++counter;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// HandleProfileRemoved
+//
+// Updates the given central repository value from the given file, when a
+// profile is removed. This is used for those central repository keys that
+// contain a profile id as a value, and if a deleted profile is
+// currently assigned to the central repository value, it is resetted to the
+// given default value.
+// -----------------------------------------------------------------------------
+//
+void HandleProfileRemoved( const TInt aRemovedProfileId,
+ const TInt aValuePlusDelta,
+ CRepository& aCenRep,
+ const TUint aKey,
+ const TInt aDefaultValue )
+ {
+ if ( ( aValuePlusDelta ) == aRemovedProfileId )
+ {
+ aCenRep.Set( aKey, aDefaultValue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CreateIntSettingForNewProfileL
+//
+// Creates a new integer Central Repository key for the new profile and
+// initialises it by copying the default value to it.
+//
+// -----------------------------------------------------------------------------
+//
+void CreateIntSettingForNewProfileL( CRepository& aRepository, TInt aSettingId,
+ TInt aProfileId )
+ {
+ TInt val;
+ User::LeaveIfError(
+ aRepository.Get(
+ ProfileEngUtils::ResolveKey( aSettingId,
+ KProEngDefaultProfileId ), val ) );
+ TInt err(
+ aRepository.Create(
+ ProfileEngUtils::ResolveKey( aSettingId, aProfileId ),
+ val ) );
+ if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) )
+ {
+ User::Leave( err );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CreateStringSettingForNewProfileL
+//
+// Creates a new string Central Repository key for the new profile and
+// initialises it by copying the default value to it.
+//
+// -----------------------------------------------------------------------------
+//
+void CreateStringSettingForNewProfileL( CRepository& aRepository,
+ TInt aSettingId, TInt aProfileId,
+ const TDesC& aNewProfileName,
+ TPtr& aStringPtr )
+ {
+ if( aSettingId != KProEngProfileName )
+ {
+ User::LeaveIfError(
+ aRepository.Get(
+ ProfileEngUtils::ResolveKey( aSettingId,
+ KProEngDefaultProfileId ), aStringPtr ) );
+ }
+ else
+ {
+ aStringPtr = aNewProfileName;
+ }
+ TInt err(
+ aRepository.Create(
+ ProfileEngUtils::ResolveKey( aSettingId, aProfileId ),
+ aStringPtr ) );
+ if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) )
+ {
+ User::Leave( err );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CreateBinSettingForNewProfileL
+//
+// Creates a new binary Central Repository key for the new profile and
+// initialises it by copying the default value to it.
+//
+// -----------------------------------------------------------------------------
+//
+void CreateBinSettingForNewProfileL( CRepository& aRepository, TInt aSettingId,
+ TInt aProfileId, TPtr8& aBinPtr )
+ {
+ User::LeaveIfError(
+ aRepository.Get(
+ ProfileEngUtils::ResolveKey( aSettingId,
+ KProEngDefaultProfileId ), aBinPtr ) );
+ TInt err(
+ aRepository.Create(
+ ProfileEngUtils::ResolveKey( aSettingId, aProfileId ),
+ aBinPtr ) );
+ if( ( err != KErrNone ) && ( err != KErrAlreadyExists ) )
+ {
+ User::Leave( err );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// GetSettingsForProfile
+//
+// Gets all the settings of the profile with given id from Central Repository.
+// -----------------------------------------------------------------------------
+//
+TInt GetSettingsForProfile( CRepository& aRepository,
+ RArray<TUint32>& aSettings,
+ TInt aId )
+ {
+ const TUint32 KId( aId << 24 );
+ const TUint32 KMask( 0xFF000000 );
+ TInt error( 0 );
+ TRAP( error, error = aRepository.FindL( KId, KMask, aSettings ) );
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// DeleteSettingsForProfile
+//
+// Deletes all the settings of the profile with given id from Central Repository
+// Tries to delete all without checking if a deletion fails.
+// -----------------------------------------------------------------------------
+//
+void DeleteSettingsForProfile( CRepository& aRepository,
+ RArray<TUint32>& aSettings )
+ {
+ for( TInt i( aSettings.Count() - 1 ); i >= 0; --i )
+ {
+ aRepository.Delete( aSettings[i] ); // ignore errors
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CreateSettingsForNewProfileL
+//
+// Creates new Central Repository keys for the new profile and initialises them
+// by copying the default values to them.
+//
+// -----------------------------------------------------------------------------
+//
+void CreateSettingsForNewProfileL( CRepository& aRepository, TInt aProfileId,
+ const TDesC& aNewProfileName,
+ TResourceReader& aReader )
+ {
+ User::LeaveIfError( aRepository.StartTransaction(
+ CRepository::EReadWriteTransaction ) );
+
+ // This only be used after normal RFS(restore factory settings), If there was
+ // user created profile before normal RFS, and the normal RFS only restore
+ // KProEngUsedIds, the settings of user created profile are in CenRep still.
+ // So we should delete the remain settings and create new one.
+ RArray<TUint32> settings;
+ if ( !GetSettingsForProfile( aRepository, settings, aProfileId ) )
+ {
+ DeleteSettingsForProfile( aRepository, settings );
+ }
+ settings.Close();
+
+ HBufC* stringVal = HBufC::NewL(
+ NCentralRepositoryConstants::KMaxUnicodeStringLength );
+ CleanupStack::PushL( stringVal );
+ TPtr stringValPtr = stringVal->Des();
+ HBufC8* binVal = HBufC8::NewL(
+ NCentralRepositoryConstants::KMaxBinaryLength );
+ CleanupStack::PushL( binVal );
+ TPtr8 binValPtr = binVal->Des();
+
+ TInt numOfElements( aReader.ReadInt16() );
+
+ for( TInt i( 0 ) ; i < numOfElements ; ++i )
+ {
+ TInt settingId( aReader.ReadInt32() );
+ TInt keyType( aReader.ReadInt32() );
+ switch( keyType )
+ {
+ case EProfileSettingKeyTypeInt:
+ {
+ CreateIntSettingForNewProfileL( aRepository, settingId,
+ aProfileId );
+ break;
+ }
+ case EProfileSettingKeyTypeString:
+ {
+ CreateStringSettingForNewProfileL( aRepository, settingId,
+ aProfileId,
+ aNewProfileName,
+ stringValPtr );
+ break;
+ }
+ case EProfileSettingKeyTypeBin:
+ {
+ CreateBinSettingForNewProfileL( aRepository, settingId,
+ aProfileId, binValPtr );
+
+ break;
+ }
+ case EProfileSettingKeyTypeReal: // no settings of this type
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); // stringVal, binVal
+
+ // Update the used ids value (this is done last so that we can get the
+ // repository back in a legal state (by deleting the settings just
+ // created)).
+ TBuf8< KProfilesMaxNumberOfDynamicProfiles > idBuf;
+ ProfileEngUtils::GetBinarySettingL( aRepository, KProEngUsedIds, idBuf );
+ idBuf.Append( aProfileId );
+ User::LeaveIfError( aRepository.Set( KProEngUsedIds, idBuf ) );
+
+ TUint32 ignore( 0 );
+ User::LeaveIfError( aRepository.CommitTransaction( ignore ) );
+ }
+
+// -----------------------------------------------------------------------------
+// DeleteProfileIdFromList
+//
+// -----------------------------------------------------------------------------
+//
+void DeleteProfileIdFromList( CRepository& aRepository, TInt aId, TDes8& aIdBuf )
+ {
+ TInt numOfIds = aIdBuf.Length();
+ for( TInt idx( 0 ); idx < numOfIds; ++idx )
+ {
+ if( aIdBuf[ idx ] == aId )
+ {
+ aIdBuf.Delete( idx, 1 );
+ aRepository.Set( KProEngUsedIds, aIdBuf );
+ break;
+ }
+ }
+ }
+
+void DoDeleteProfileL( CRepository& aCenRep, TInt aId )
+ {
+ RArray<TUint32> settings;
+ User::LeaveIfError( GetSettingsForProfile( aCenRep, settings, aId ) );
+
+ TBuf8< 4 * KProfilesMaxNumberOfDynamicProfiles > idBuf; // One id is 4-bytes long
+ ProfileEngUtils::GetBinarySettingL( aCenRep, KProEngUsedIds, idBuf );
+
+ User::LeaveIfError( aCenRep.StartTransaction(
+ CRepository::EReadWriteTransaction ) );
+ DeleteSettingsForProfile( aCenRep, settings );
+ settings.Reset();
+ DeleteProfileIdFromList( aCenRep, aId, idBuf );
+
+ TInt headsetVal( 0 );
+ TInt loopsetVal( 0 );
+ TInt ttyVal( 0 );
+ TInt btVal( 0 );
+ TUint32 ignore( 0 );
+ TRAPD( error,
+ CRepository* cr = CRepository::NewL( KCRUidProfileSettings );
+ CleanupStack::PushL( cr );
+ User::LeaveIfError( cr->Get( KSettingsHeadsetDefaultProfile, headsetVal ) );
+ User::LeaveIfError( cr->Get( KSettingsLoopsetDefaultProfile, loopsetVal ) );
+ User::LeaveIfError( cr->Get( KSettingsTTYDefaultProfile, ttyVal ) );
+ User::LeaveIfError( cr->Get( KSettingsBTDefaultProfile, btVal ) );
+ User::LeaveIfError( cr->StartTransaction(
+ CRepository::EReadWriteTransaction ) );
+ // -1 is a mystery, consult general settings team:
+ // 0 ( = general profile ) is the default profile used with all the
+ // accessories:
+ HandleProfileRemoved( aId, headsetVal-1, *cr,
+ KSettingsHeadsetDefaultProfile, 0 );
+ HandleProfileRemoved( aId, loopsetVal-1, *cr,
+ KSettingsLoopsetDefaultProfile, 0 );
+ HandleProfileRemoved( aId, ttyVal-1, *cr,
+ KSettingsTTYDefaultProfile, 0 );
+ HandleProfileRemoved( aId, btVal-1, *cr,
+ KSettingsBTDefaultProfile, 0 );
+ User::LeaveIfError( cr->CommitTransaction( ignore ) );
+
+ CleanupStack::PopAndDestroy(); // delete cr:
+ );
+
+ if( error )
+ {
+ aCenRep.RollbackTransaction(); // ignore error
+ User::Leave( error );
+ }
+
+ User::LeaveIfError( aCenRep.CommitTransaction( ignore ) );
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::DeleteProfileL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CProfileEngineImpl::DeleteProfileL( TInt aId )
+ {
+ iMutex.Wait();
+ TInt activeProfileId( ActiveProfileId() );
+
+ if( activeProfileId < 0 )
+ {
+ iMutex.Signal();
+ User::Leave( activeProfileId );
+ }
+
+ // Do not allow delete active profile
+ if( aId == activeProfileId )
+ {
+ iMutex.Signal();
+ return KErrAbort;
+ }
+ // Do not allow delete default profile
+ if( IsDefaultProfile( aId ) )
+ {
+ iMutex.Signal();
+ return KErrAbort;
+ }
+
+ TRAPD( error, DoDeleteProfileL( *iCenRep, aId ) );
+ iMutex.Signal();
+ User::LeaveIfError( error );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::CreateProfileL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+MProfileExtended* CProfileEngineImpl::CreateProfileL()
+ {
+ if( SysUtil::FFSSpaceBelowCriticalLevelL( iFs ) )
+ {
+ User::Leave( KErrDiskFull );
+ }
+
+ // Create profile ID
+ CProfilesNamesArrayImpl* profileNameArray = CProfilesNamesArrayImpl::NewLC();
+
+ iMutex.Wait();
+ TRAPD( error, ReadProfilesNamesL( profileNameArray ) );
+ if( error )
+ {
+ iMutex.Signal();
+ User::Leave( error );
+ }
+
+ if( profileNameArray->MdcaCount() - // current profile count
+ iProfileLocalisedNames->MdcaCount() >= // default profile count
+ KProfilesMaxNumberOfDynamicProfiles ) // max dynamic profiles
+ {
+ // Max number of dynamic profiles
+ CleanupStack::PopAndDestroy(); // profileNameArray
+ iMutex.Signal();
+ return NULL;
+ }
+
+ TInt profileId( KErrNotFound );
+ // Find first free id
+ TInt lastDynamicProfileId( KProfileBaseDynamicProfileId +
+ KProfilesMaxNumberOfDynamicProfiles );
+
+ for( TInt i( KProfileBaseDynamicProfileId ); i < lastDynamicProfileId; ++i )
+ {
+ TInt index( profileNameArray->FindById( i ) );
+ if( index == KErrNotFound )
+ {
+ profileId = i;
+ break;
+ }
+ }
+
+ if( profileId == KErrNotFound )
+ {
+ CleanupStack::PopAndDestroy(); // profileNameArray
+ iMutex.Signal();
+ return NULL;
+ }
+
+ TBuf<KProfileMaxNameLength> profileName;
+ TRAP( error,
+ ReadNewProfileNameFromResourceL( R_NEW_PROFILE, profileName ) );
+ if( error )
+ {
+ iMutex.Signal();
+ User::Leave( error );
+ }
+
+ GenerateProfileName( profileName, *profileNameArray );
+ CleanupStack::PopAndDestroy(); // profileNameArray
+
+ TResourceReader rsReader;
+ CProfileImpl* newProfile = NULL;
+ TRAP( error,
+ ReadResourceInBufferLC( R_PROFILE_SETTINGS, rsReader );
+ CreateSettingsForNewProfileL( *iCenRep, profileId,
+ profileName, rsReader );
+ CleanupStack::PopAndDestroy(); // ReadResourceInBufferLC
+
+ // Create and store new profile
+ newProfile = CProfileImpl::NewLC( *iFs );
+ newProfile->InternalizeL( *iCenRep, profileId );
+
+ CleanupStack::Pop(); // newProfile
+ );
+
+ iMutex.Signal();
+ User::LeaveIfError( error );
+
+ return newProfile;
+ }
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::ReadNewProfileNameFromResourceL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CProfileEngineImpl::ReadNewProfileNameFromResourceL( TInt aResourceId,
+ TDes& aProfileName )
+ {
+ TResourceReader rsReader;
+ ReadResourceInBufferLC( aResourceId, rsReader );
+
+ TPtrC profileName( rsReader.ReadTPtrC() );
+ aProfileName.Copy( profileName );
+
+ CleanupStack::PopAndDestroy(); // ReadResourceInBufferLC
+ }
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::ReadNewProfileNameFromResourceL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CProfileNameImpl* CProfileEngineImpl::ReadNewProfileNameFromResourceLC()
+ {
+ TBuf<KProfileMaxNameLength> profileName;
+ ReadNewProfileNameFromResourceL( R_NEW_PROFILE, profileName );
+
+ TBuf<KProfileMaxNameLength> shortName;
+ ReadNewProfileNameFromResourceL( R_NEW_PROFILE_SHORT, shortName );
+
+ TBuf<KProfileMaxNameLength> naviName;
+ ReadNewProfileNameFromResourceL( R_NEW_PROFILE_NAVI, naviName );
+
+ TBuf<KProfileMaxNameLength> titleName;
+ ReadNewProfileNameFromResourceL( R_NEW_PROFILE_TITLE, titleName );
+
+ CProfileNameImpl* localizedName =
+ CProfileNameImpl::NewLC( 0, profileName, shortName,
+ naviName, titleName );
+
+ return localizedName;
+ }
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::ReadDynamicProfilesNamesL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CProfileEngineImpl::ReadDynamicProfilesNamesL(
+ CProfilesNamesArrayImpl* aProfilesNames,
+ CProfileNameImpl& aNameTemplate )
+ {
+ TBuf8< NCentralRepositoryConstants::KMaxBinaryLength > idBuf;
+ ProfileEngUtils::GetBinarySettingL( *iCenRep, KProEngUsedIds, idBuf );
+ TInt len = idBuf.Length();
+
+ if( len == 0 )
+ {
+ return; // No user-created profiles, just return
+ }
+
+ CProfileNameImpl* localizedName = ReadNewProfileNameFromResourceLC();
+
+ for( TInt i( 0 ); i < len; ++i )
+ {
+ aNameTemplate.InternalizeL( *iCenRep, idBuf[i] );
+ if( !aNameTemplate.IsProfileNameChanged() )
+ {
+ TInt idxOfParenthesis(
+ aNameTemplate.Name().Find( KFirstParenthesis ) );
+ if( idxOfParenthesis != KErrNotFound )
+ {
+ TBuf<KProfileGeneratedNameTailLength> uniquePart =
+ aNameTemplate.Name().Mid( idxOfParenthesis,
+ KProfileGeneratedNameTailLength );
+ aNameTemplate.SetLocalizedProfileNameL( *localizedName,
+ uniquePart );
+ }
+ else
+ {
+ aNameTemplate.SetLocalizedProfileNameL( *localizedName,
+ KNullDesC() );
+ }
+ }
+
+ CProfileNameImpl* nameImpl =
+ CProfileNameImpl::NewLC( aNameTemplate );
+
+ User::LeaveIfError( aProfilesNames->InsertInOrder( nameImpl ) );
+ CleanupStack::Pop(); // nameImpl
+ }
+
+ CleanupStack::PopAndDestroy( localizedName );
+ }
+
+// -----------------------------------------------------------------------------
+// CProfileEngineImpl::SetLocalizedNameForDynamicProfileL
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CProfileEngineImpl::SetLocalizedNameForDynamicProfileL(
+ CProfileImpl& aProfile )
+ {
+ CProfileNameImpl* localizedName = ReadNewProfileNameFromResourceLC();
+
+ TInt idxOfParenthesis(
+ aProfile.ProfileName().Name().Find( KFirstParenthesis ) );
+ if( idxOfParenthesis != KErrNotFound )
+ {
+ TBuf<KProfileGeneratedNameTailLength> uniquePart =
+ aProfile.ProfileName().Name().Mid( idxOfParenthesis,
+ KProfileGeneratedNameTailLength );
+ aProfile.SetLocalizedProfileNameL( *localizedName, uniquePart );
+ }
+ else
+ {
+ aProfile.SetLocalizedProfileNameL( *localizedName,
+ KNullDesC() );
+ }
+
+ CleanupStack::PopAndDestroy( localizedName );
+ }
+
+// End of File
+