// Copyright (c) 2007-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:
//
#include "ssmclayer.h"
#include "ssmdebug.h"
#include <e32cmn.h>
#include <ssm/ssmstatemanager.h>
#include <ssm/ssmstateawaresession.h>
#include <ssm/ssmdomaindefs.h>
#include <ssm/ssmsubstates.hrh>
#include <ssm/ssmadaptationcli.h>
#include <ssm/starterclient.h>
#include <ssm/startupdomainpskeys.h>
#include <ssm/ssmuiproviderdll.h>
#include <ssm/startupadaptationcommands.h>
#include <ssm/clayerswp.hrh>
#include <ssm/ssmsystemwideproperty.h>
#include <ssm/ssmstates.hrh>
#include <ssm/ssmpatchableconstants.h>
// The following assert ensures that it's ok to just copy the handle from the
// RSsmStateManager class as there are no other data members if RSsmStateManage
// is the same size as RSessionBase.
//
// This assert will fail if extra data members are added to RSsmStateManager
// This ensures that the code in RStarterSession is correct.
__ASSERT_COMPILE(sizeof(RSessionBase) == sizeof(RSsmStateManager)); //lint -e752 Suppress local declarator not referenced
EXPORT_C TInt RStarterSession::Connect()
{
RSsmStateManager session;
TInt err = session.Connect();
if (err == KErrNone)
{
// Connection successful, copy handle from session to this handle
SetHandle(session.Handle());
}
// session is not closed before returning as this now owns the handle
return err;
}
/*
* Helper Function that reads KRFStatusPropertyKey SWP using RSsmSystemWideProperty and returns.
* @return KErrNone on Success
* Returns an error code from RSsmSystemWideProperty API - Connect & GetValue.
* On resulting error return, aRFSwpStatus contains ESsmRfOff
*
* @internalComponent
*/
static TInt GetRFSwpStatus ( TInt& aRFSwpStatus )
{
TUint rfStatusPropertyKey = CSsmUiSpecific::RFStatusPropertyKey ();
RSsmSystemWideProperty swp;
TInt err = swp.Connect ( rfStatusPropertyKey );
DEBUGPRINT2A ( "RF SWP connect error = %d ",err );
TInt rfStatus ( ESsmRfOff );
if ( err == KErrNone )
{
err = swp.GetValue ( rfStatus );
DEBUGPRINT3A ( "RF SWP status = %d ( err %d )", rfStatus, err );
}
aRFSwpStatus = rfStatus;
swp.Close ();
return err;
}
/**
* This adjustment specifies how to convert start-up sub-states
* to the states defined in StartupAdaptation::TGlobalState
*
* It is calculated using the same method specified in CSaaStateAdaptation::MapToStartupAdaptationState(),
* see that method for further details.
*
* @internalComponent
*/
const TInt KStartupSubStateAdjustment = static_cast<TInt>(StartupAdaptation::ESWStateStartingUiServices)
- static_cast<TInt>(ESsmStartupSubStateNonCritical);
/**
* Helper Function that is used for performing transition to startup substates .
* @return KErrNone on Success and returns an error if RequestStateTransition fails or transition is not supported
*
* @internalComponent
*/
static TInt TransitionToStartupSubState(TSsmState &aCurrentState, RSsmStateManager& aSession)
{
TInt err = KErrNone;
TInt reason = KSsmCLayerNullReason;
TUint16 mainstate = aCurrentState.MainState();
TUint16 substate = 0;
DEBUGPRINT2A( "RStarterSession::SetState, mainstate = %d", mainstate );
if( mainstate == ESsmStartup)
{
switch(aCurrentState.SubState())
{
case StartupAdaptation::ESWStateCharging - KStartupSubStateAdjustment:
{
substate = StartupAdaptation::ESWStateChargingToNormal - KStartupSubStateAdjustment;
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request for state transition
err = aSession.RequestStateTransition(stateinfo);
break;
}
case StartupAdaptation::ESWStateAlarm - KStartupSubStateAdjustment:
{
substate = StartupAdaptation::ESWStateAlarmToNormal - KStartupSubStateAdjustment;
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request for state transition
err = aSession.RequestStateTransition(stateinfo);
break;
}
default:
{
err = KErrArgument;
}
}
}
else
{
err = KErrArgument;
}
return err;
}
/**
* Helper Function that is used for obtaining the currentstate.
* @return KErrNone on Success and returns an error if RSsmStateAwareSession fails to connect to domainId KSM2UiServicesDomain3
* @internalComponent
*/
static TInt GetCurrentState( TSsmState &aCurrentState )
{
RSsmStateAwareSession sas;
const TInt err = sas.Connect(KSM2UiServicesDomain3);
if (KErrNone == err)
{
aCurrentState = sas.State();
sas.Close();
}
return err;
}
EXPORT_C TInt RStarterSession::SetState( const TGlobalState aState )
{
RSsmStateManager session;
// Set session to use the handle stored in this
session.SetHandle(Handle());
DEBUGPRINT2A( "RStarterSession::SetState( %d )", aState );
TInt err = KErrNone;
//Initialising main state with an invalid main state (i.e ESsmMainSystemStateMax)
TUint16 mainstate = ESsmMainSystemStateMax;
TUint16 substate = 0;
TSsmState currentState;
TUint rfStatusPropertyKey = CSsmUiSpecific::RFStatusPropertyKey();
switch (aState)
{
case ENormal:
{
//Switch depending on the patchable constant KSsmGracefulOffline is enabled
if (IsSsmGracefulOffline())
{
err = GetCurrentState(currentState);
if ( err == KErrNone )
{
TInt globalSystemState;
err =RProperty::Get(KPSUidStartup, KPSGlobalSystemState, globalSystemState);
if( err == KErrNone )
{
mainstate = currentState.MainState();
//Allow state transition to normal RF ON if global state is not ESwStateNormalRfOn
if ((mainstate == ESsmNormal) && (globalSystemState != ESwStateNormalRfOn))
{
substate = ESsmNormalRfOnSubState;
TInt reason = KSsmCLayerNullReason;
TSsmStateTransition stateinfo(ESsmNormal,substate, reason);
err = session.RequestStateTransition(stateinfo);
}
else
{
//Transition to startup substate
err = TransitionToStartupSubState(currentState, session);
}
}
}
}
else
{
TInt rfSwpValue;
err = GetRFSwpStatus ( rfSwpValue );
// Change value of RF Swp (to ESsmRfOn) only if it is not ESsmRfOn.
if (err == KErrNone && rfSwpValue != ESsmRfOn)
{
TSsmSwp swpRFStatus ( rfStatusPropertyKey, ESsmRfOn );
err = session.RequestSwpChange ( swpRFStatus );
}
else
{
err = GetCurrentState(currentState);
if(err == KErrNone)
{
//Transition to startup substate
err = TransitionToStartupSubState(currentState, session);
}
}
}
break;
}
case EAlarm:
{
// Charging to alarm
mainstate = ESsmStartup;
substate = StartupAdaptation::ESWStateChargingToAlarm - KStartupSubStateAdjustment;
TInt reason = KSsmCLayerNullReason;
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request and return success.
err = session.RequestStateTransition(stateinfo);
break;
}
case ECharging:
{
// Alarm to charging
mainstate = ESsmStartup;
substate = StartupAdaptation::ESWStateAlarmToCharging - KStartupSubStateAdjustment;
TInt reason = KSsmCLayerNullReason;
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request and return success.
err = session.RequestStateTransition(stateinfo);
break;
}
case EOffline:
{
if (IsSsmGracefulOffline())
{
TInt globalSystemState;
err =RProperty::Get(KPSUidStartup, KPSGlobalSystemState, globalSystemState);
if( err == KErrNone )
{
//Allow state transition if global state is not ESwStateNormalRfOff
if (globalSystemState != ESwStateNormalRfOff)
{
const TInt reason = KSsmCLayerNullReason;
substate = ESsmNormalRfOffSubState;
TSsmStateTransition stateinfo(ESsmNormal, substate, reason);
// Make request for substate transition to offline
err = session.RequestStateTransition(stateinfo);
}
}
}
else
{
TInt rfSwpValue;
err = GetRFSwpStatus ( rfSwpValue );
// Change value of RF SwP (to ESsmRfOff) only if it is not ESsmRfOff.
if ( err == KErrNone && rfSwpValue != ESsmRfOff )
{
TSsmSwp swpRFStatus ( rfStatusPropertyKey, ESsmRfOff );
err = session.RequestSwpChange ( swpRFStatus );
}
}
break;
}
case EBTSap:
{
TInt rfSwpValue;
err = GetRFSwpStatus ( rfSwpValue );
// Change value of RF Swp (to ESsmBtSap) only if it is notESsmBtSap.
if ( err == KErrNone && rfSwpValue != ESsmBtSap )
{
TSsmSwp swpRFStatus ( rfStatusPropertyKey, ESsmBtSap );
err = session.RequestSwpChange ( swpRFStatus );
}
break;
}
default:
{
err = KErrArgument;
}
}
// Session is not closed before returning as this owns the handle
return err;
}
EXPORT_C void RStarterSession::Reset( const TResetReason aReason )
{
RSsmStateManager session;
// Set session to use the handle stored in this
session.SetHandle(Handle());
// Package up the state transition
TUint16 mainstate = ESsmShutdown;
TUint16 substate = KSsmAnySubState;
TInt reason = aReason;
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request and ignore return value
session.RequestStateTransition(stateinfo);
// Session is not closed before returning as this owns the handle
}
EXPORT_C void RStarterSession::Shutdown()
{
RSsmStateManager session;
// Set session to use the handle stored in this
session.SetHandle(Handle());
// Package up the state transition
TUint16 mainstate = ESsmShutdown;
TUint16 substate = KSsmAnySubState;
TInt reason = KSsmCLayerPowerOffReason; // A null reason on shutdown will lead to a poweroff
TSsmStateTransition stateinfo(mainstate, substate, reason);
// Make request and ignore return value
session.RequestStateTransition(stateinfo);
// Session is not closed before returning as this owns the handle
}
EXPORT_C TInt RStarterSession::ResetNetwork()
{
RSsmStateManager session;
// Set session to use the handle stored in this
session.SetHandle(Handle());
// Make request and return success.
TUint rfStatusPropertyKey = CSsmUiSpecific::RFStatusPropertyKey();
TSsmSwp swpRFStatus(rfStatusPropertyKey, ESsmRfOff);
RSsmSystemWideProperty swp;
swp.Connect(rfStatusPropertyKey);
TRequestStatus status;
//Subscribe for SwP changes
swp.Subscribe(status);
TInt requestResult= session.RequestSwpChange(swpRFStatus);
if(KErrNone == requestResult)
{
// Wait for SwP Change
User::WaitForRequest(status);
swpRFStatus.Set(rfStatusPropertyKey, ESsmRfOn);
requestResult = session.RequestSwpChange(swpRFStatus);
}
swp.Close();
// Session is not closed before returning as this owns the handle
return requestResult;
}
EXPORT_C TBool RStarterSession::IsRTCTimeValid()
{
TBool isRTCValid = EFalse;
//Ignoring return code for compatability reasons
RProperty::Get(CSsmUiSpecific::ValidateRTCPropertyCategory(),
CSsmUiSpecific::ValidateRTCPropertyKey(), isRTCValid);
return isRTCValid;
}
EXPORT_C TInt RStarterSession::ActivateRfForEmergencyCall()
{
RSsmEmergencyCallRfAdaptation ecradaptation;
TInt err = ecradaptation.Connect();
if (err != KErrNone)
{
return err;
}
TRequestStatus status;
// Request activation
ecradaptation.ActivateRfForEmergencyCall(status);
// Wait for completion
User::WaitForRequest(status);
ecradaptation.Close();
// Return the completion value of status
return status.Int();
}
EXPORT_C TInt RStarterSession::DeactivateRfAfterEmergencyCall()
{
RSsmEmergencyCallRfAdaptation ecradaptation;
TInt err = ecradaptation.Connect();
if (err != KErrNone)
{
return err;
}
TRequestStatus status;
// Request activation
ecradaptation.DeactivateRfForEmergencyCall(status);
// Wait for completion
User::WaitForRequest(status);
ecradaptation.Close();
// Return the completion value of status
return status.Int();
}
EXPORT_C TInt RStarterSession::EndSplashScreen()
{
RProperty splashscreen;
TInt err = splashscreen.Attach(KPSUidStartup, KPSSplashShutdown, EOwnerThread);
if (err != KErrNone)
{
return err;
}
err = splashscreen.Set(ESplashShutdown);
splashscreen.Close();
return err;
}