startup/ssmstartuppolicy.cpp
branchsystem_startup
changeset 30 292fee808849
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/startup/ssmstartuppolicy.cpp	Wed Oct 13 12:07:40 2010 +0100
@@ -0,0 +1,400 @@
+/*
+* 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: Implementation of CSsmStartupPolicy class.
+*
+*/
+
+#include <centralrepository.h>
+#include <e32property.h>
+#include <e32uid.h>
+#include <featmgr.h>
+#include <ssm/ssmdomaindefs.h>
+#include <ssm/ssmcmd.hrh>
+#include <ssm/ssmcommandlistresourcereader.h>
+#include <ssm/ssmstate.h>
+#include <ssm/ssmstateawaresession.h>
+#include <ssm/ssmstatetransition.h>
+#include <ssm/startupdomainpskeys.h>
+
+#include "ssmsubstateext.hrh"
+#include "ssmmapperutility.h"
+#include "ssmmapperutilitystatic.h"
+#include "ssmstartuppolicy.h"
+#include "ssmpolicypluginsprivatecrkeys.h"
+#include "trace.h"
+
+/**
+* Start-up state policy resource file path format :
+* "\private\<SID of SSM>\startup\<Value of KSystemStartupModeKey>\"
+*/
+_LIT( KCommandListPath, "Z:\\private\\2000D75B\\startup\\%d\\" );
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// GetStartupMode
+// ---------------------------------------------------------------------------
+//
+static TInt GetStartupMode()
+    {
+    FUNC_LOG;
+
+    TInt startupMode( EStartupModeNormal );
+    TInt errorCode = RProperty::Get(
+        SsmMapperUtility::PsUid( KPSUidStartup ), KPSGlobalStartupMode, startupMode );
+    ERROR( errorCode, "Failed to read startup mode from P&S" );
+    INFO_1( "Startup mode is %d", startupMode );
+    return startupMode;
+    }
+
+
+// ---------------------------------------------------------------------------
+// DecideStateByStartupMode
+// ---------------------------------------------------------------------------
+//
+static TSsmStartupSubStateExt DecideStateByStartupMode()
+    {
+    FUNC_LOG;
+
+    TInt startupMode( GetStartupMode() );
+    TSsmStartupSubStateExt nextState( ESsmStateSecurityCheck );
+    switch ( startupMode )
+        {
+        case EStartupModeTest:
+            nextState = ESsmStateTest;
+            break;
+        case EStartupModeAlarm:
+            nextState = ESsmStateAlarm;
+            break;
+        case EStartupModeCharging:
+            nextState = ESsmStateCharging;
+            break;
+        default:
+            break;
+        }
+
+    return nextState;
+    }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C MSsmStatePolicy* CSsmStartupPolicy::NewL()
+    {
+    CSsmStartupPolicy* self = new( ELeave ) CSsmStartupPolicy;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::~CSsmStartupPolicy
+// ---------------------------------------------------------------------------
+//
+CSsmStartupPolicy::~CSsmStartupPolicy()
+    {
+    FUNC_LOG;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::GetNextState
+// ---------------------------------------------------------------------------
+//
+// TomP - We've simplified this: we now only have 3 sub-states: PreUIServices StartingUIServices and StartingCriticalApps
+// After that we'll drop into the Normal state which with it's 1 sub-state: NonCritcalApps
+TBool CSsmStartupPolicy::GetNextState(
+    TSsmState aCurrentTransition,
+    TInt /*aReason*/,
+    TInt aError,
+    TInt aSeverity,
+    TSsmState& aNextState )
+    {
+    FUNC_LOG;
+    INFO_2( "Current state %04x.%04x",
+        aCurrentTransition.MainState(), aCurrentTransition.SubState() );
+    ERROR_1( aError, "State transition resulted in an error, severity %d", aSeverity );
+	ASSERT_TRACE( aCurrentTransition.MainState() == ESsmStartup );
+
+	TBool moreToCome = EFalse;
+	if ( aError == KErrNone || aSeverity < ECmdHighSeverity )
+		{
+		switch( aCurrentTransition.SubState() )
+			{
+			case KSsmAnySubState:
+			case ESsmStatePreUiServices:
+				aNextState = TSsmState( ESsmStartup, ESsmStateStartingUiServices );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateStartingUiServices:
+				aNextState = TSsmState( ESsmStartup, ESsmStateStartingCriticalApps );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateStartingCriticalApps:
+				//TomP aNextState = TSsmState( ESsmStartup, ESsmStateSelfTestOK );
+				moreToCome = EFalse;
+				break;
+/*TomP		
+			case ESsmStateSelfTestOK:
+				aNextState = TSsmState( ESsmStartup, DecideStateByStartupMode() );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateChargingToNormal:
+			case ESsmStateAlarmToNormal:
+				aNextState = TSsmState( ESsmStartup, ESsmStateSecurityCheck );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateSecurityCheck:
+				aNextState = TSsmState( ESsmStartup, SelectStateAfterSecurityCheck() );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateChargingToAlarm:
+				aNextState = TSsmState( ESsmStartup, ESsmStateAlarm );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateAlarmToCharging:
+				aNextState = TSsmState( ESsmStartup, ESsmStateCharging );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateNonCritical:
+			    ClearResetCounter(); // start-up is successful
+				aNextState = TSsmState( ESsmNormal, KSsmAnySubState );
+				moreToCome = ETrue;
+				break;
+			case ESsmStateAlarm:
+			case ESsmStateCharging:
+			case ESsmStateTest:
+				moreToCome = EFalse;
+				break;
+			case ESsmStateEmergencyCallsOnly:
+			    ClearResetCounter(); // start-up is successful
+				moreToCome = EFalse;
+				break;
+*/
+			default:
+        		ASSERT_ALWAYS_TRACE;
+				moreToCome = EFalse;
+				break;
+			}
+		}
+	else
+		{
+        if ( ResetLimitReached() ) // Updates the reset count
+            {
+            aNextState = TSsmState( ESsmFail, KSsmAnySubState );
+	    	moreToCome = ETrue;
+    	    }
+    	else
+    	    {
+            aNextState = TSsmState( ESsmShutdown, ESsmErrorShutdown );
+            moreToCome = ETrue;
+    	    }
+		}
+
+	return moreToCome;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::GetCommandListPathL
+// ---------------------------------------------------------------------------
+//
+void CSsmStartupPolicy::GetCommandListPathL( TDes& aCmdListPath )
+    {
+    FUNC_LOG;
+
+	aCmdListPath.Format( KCommandListPath, iHardwareReason );
+	iUtil->GetCommandListPath( aCmdListPath );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::IsAllowedTargetState
+// ---------------------------------------------------------------------------
+//
+TBool CSsmStartupPolicy::IsAllowedTargetState(
+    const TSsmStateTransition& aRequest ) const
+    {
+    FUNC_LOG;
+
+    TSsmState currentState;
+    TInt errorCode = GetCurrentState( currentState );
+    ERROR( errorCode, "Failed to get current state" );
+
+    if ( errorCode == KErrNone )
+        {
+        TUint16 reqMainState( aRequest.State().MainState() );
+        TUint16 reqSubState( aRequest.State().SubState() );
+        INFO_2( "Requested target state = %04x.%04x", reqMainState, reqSubState );
+        TUint16 curMainState( currentState.MainState() );
+        TUint16 curSubState( currentState.SubState() );
+        INFO_2( "Current state = %04x.%04x", curMainState, curSubState );
+
+		// TomP - We'll allow any state transition as long as there was no error
+		return ETrue;
+        if ( reqMainState == ESsmStartup )
+            {
+            if ( ( curSubState == ESsmStateCharging &&
+                   ( reqSubState == ESsmStateChargingToAlarm ||
+                     reqSubState == ESsmStateChargingToNormal ) ) ||
+                 ( curSubState == ESsmStateAlarm &&
+                   ( reqSubState == ESsmStateAlarmToCharging ||
+                     reqSubState == ESsmStateAlarmToNormal ) ) )
+                {
+                return ETrue;
+                }
+            }
+        else if ( reqMainState == ESsmNormal )
+            {
+            if ( ( curMainState == ESsmStartup &&
+                   curSubState == ESsmStateNonCritical ) )
+                {
+                return ETrue;
+                }
+            }
+        else if ( reqMainState == ESsmFail ||
+                  reqMainState == ESsmShutdown )
+            {
+            return ETrue;
+            }
+        }
+
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::TargetSubState
+// ---------------------------------------------------------------------------
+//
+TUint16 CSsmStartupPolicy::TargetSubState( const TUint16 aRequestedSubState )
+    {
+    FUNC_LOG;
+    INFO_1( "Requested sub state %04x", aRequestedSubState );
+
+	return ( aRequestedSubState == KSsmAnySubState ) ?
+        ESsmStatePreUiServices : aRequestedSubState;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::CSsmStartupPolicy
+// ---------------------------------------------------------------------------
+//
+CSsmStartupPolicy::CSsmStartupPolicy()
+    {
+    FUNC_LOG;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSsmStartupPolicy::ConstructL()
+    {
+    FUNC_LOG;
+
+	// Read the hardware reason
+	User::LeaveIfError( RProperty::Get(
+	    KUidSystemCategory, KSystemStartupModeKey, iHardwareReason ) );
+
+    BaseConstructL();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::IsSimlessOfflineSupported
+// ---------------------------------------------------------------------------
+//
+TBool CSsmStartupPolicy::IsSimlessOfflineSupported()
+    {
+    FUNC_LOG;
+/*	
+    TBool ret( EFalse );
+
+    ret = ( iUtil->FeatureStatus( TUid::Uid( KFeatureIdOfflineMode ) ) ||
+            iUtil->FeatureStatus( TUid::Uid( KFeatureIdFlightMode ) ) ) &&
+            iUtil->FeatureStatus( TUid::Uid( KFeatureIdFfSimlessOfflineSupport ) );
+
+    INFO_1( "Simless offline supported = %d", ret );
+*/	
+	//TomP - SIMless Offline is always supported
+    return ETrue;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::SelectStateAfterSecurityCheck
+// ---------------------------------------------------------------------------
+//
+TUint16 CSsmStartupPolicy::SelectStateAfterSecurityCheck()
+    {
+    FUNC_LOG;
+/*
+    TInt value( ESimStatusUninitialized );
+    TInt errorCode = RProperty::Get( iUtil->PsUid( KPSUidStartup ), KPSSimStatus, value );
+    ERROR( errorCode, "Failed to read KPSUidStartup::KPSSimStatus P&S key" );
+    INFO_1( "Current SIM status = %d", value );
+    TUint16 retVal( ESsmStateEmergencyCallsOnly );
+    if ( errorCode == KErrNone )
+        {
+        if ( value == ESimUsable || value == ESimNotSupported )
+            {
+            retVal = ESsmStateNonCritical;
+            }
+        else if ( value == ESimNotPresent && IsSimlessOfflineSupported() )
+            {
+            retVal = ESsmStateNonCritical;
+            }
+        }
+
+    INFO_1( "State selected after security check = %04x", retVal );
+*/	
+	// TomP - Always jump straight into Non Critical State next
+    return ESsmStateNonCritical;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmStartupPolicy::ClearResetCounter
+// ---------------------------------------------------------------------------
+//
+void CSsmStartupPolicy::ClearResetCounter()
+    {
+    FUNC_LOG;
+
+    TRAPD_ERR( errorCode, ClearResetCounterL() );
+    ERROR( errorCode, "Failed to clear reset counter" );
+    }
+
+
+// ---------------------------------------------------------------------------
+// ClearResetCounterL
+// ---------------------------------------------------------------------------
+//
+void CSsmStartupPolicy::ClearResetCounterL()
+    {
+    FUNC_LOG;
+
+    CRepository* repository = CRepository::NewLC( iUtil->CrUid( KCRUidSsmStartupPolicy ) );
+    User::LeaveIfError( repository->Set( KSsmStartupErrorResetCounter, 0 ) );
+    CleanupStack::PopAndDestroy( repository );
+    }