sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * RUpsSubsession implementation. See class and function definitions sl@0: * for more detail. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include sl@0: #include "upsclientconfig.h" sl@0: #include "upscommon.h" sl@0: #include sl@0: sl@0: namespace UserPromptService sl@0: { sl@0: sl@0: sl@0: EXPORT_C RUpsSubsession::RUpsSubsession() sl@0: /** sl@0: This constructor provides a single point of definition from sl@0: which the superclass constructor is called. sl@0: */ sl@0: : RScsClientSubsessionBase(), sl@0: iDecPtr(NULL, 0), sl@0: iSubsessionCreated(EFalse), iClientTid(), iClientSid(TUid::Null()), iClientPid(0), iUpsSession(0) sl@0: { sl@0: // empty. sl@0: } sl@0: sl@0: EXPORT_C TInt RUpsSubsession::Initialise(RUpsSession& aSession, const RThread& aClient) sl@0: /** sl@0: Saves the details required to create a subsession specific to the client thread. sl@0: sl@0: The actual subsession creation is defered until the subsession is required (which sl@0: may be never if the policy says server checks are sufficient). sl@0: sl@0: Several RUpsSubsession objects can share a single RUpsSession. sl@0: sl@0: If any of the RUpsSubsession objects are to be used in a different thread to the RUpsSession, then sl@0: ShareAuto() must be called on the RUpsSession. sl@0: sl@0: @see RSubSessionBase::CreateSubsession sl@0: sl@0: @param aSession Connected session to the UPS server. sl@0: @param aClient SS client for whom this session is set up. sl@0: @return Symbian OS error code where KErrNone indicates success sl@0: and any other value indicates failure. sl@0: */ sl@0: { sl@0: iClientTid = aClient.Id(); sl@0: iClientSid = aClient.SecureId(); sl@0: sl@0: // Need to obtain the drive letter for the exe sl@0: RProcess clientProcess; sl@0: TInt r = aClient.Process(clientProcess); sl@0: if(r != KErrNone) sl@0: { sl@0: return r; // Presumably it exited... sl@0: } sl@0: iClientPid = clientProcess.Id(); sl@0: clientProcess.Close(); sl@0: sl@0: iUpsSession = &aSession; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt RUpsSubsession::CreateSubsession() sl@0: /** sl@0: Create a subsession for a specific SS client over the supplied session. sl@0: sl@0: @param aSession Connected session to the UPS server. sl@0: @param aClient SS client for whom this session is set up. sl@0: @return Symbian OS error code where KErrNone indicates success sl@0: and any other value indicates failure. sl@0: @capability ProtServ sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised)); sl@0: TPckgBuf tidBuf = iClientTid; sl@0: TPckgBuf pidBuf = iClientPid; sl@0: TIpcArgs args(&tidBuf, &pidBuf); sl@0: return RScsClientSubsessionBase::CreateSubsession(*iUpsSession, ESessSubsessFromThreadId, args); sl@0: } sl@0: sl@0: EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk, sl@0: const TServiceId& aServiceId, const TDesC& aDestination, sl@0: TUpsDecision& aDecision, TRequestStatus& aStatus) sl@0: /** sl@0: Determines whether the system server should perform the service requested sl@0: by the client application. Depending on licensee configuration this function sl@0: will either complete immediately if the client passed the system servers sl@0: security policy check. Alternatively, every request may require additional sl@0: authorisation by the User Prompt Service. sl@0: sl@0: @see RUpsSubsession::AuthoriseInternal sl@0: sl@0: @param aServerCheckOk Whether the client request passed the security check sl@0: implemented by the system server e.g. does the client sl@0: have the correct capabilities for the requested service. sl@0: @param aServiceId Service which the client wants to use. sl@0: @param aDestination More information about the service, e.g. this sl@0: could be a telephone number is the client wanted sl@0: to make a call. sl@0: @param aDecision When the request completes successfully, the verdict sl@0: is written to this variable. sl@0: @param aStatus The server completes this request object when it sl@0: has finished handling the request. sl@0: @capability ProtServ sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised)); sl@0: sl@0: AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, KNullDesC8, aDecision, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk, sl@0: const TServiceId& aServiceId, const TDesC& aDestination, sl@0: const TDesC8& aOpaqueData, sl@0: TUpsDecision& aDecision, TRequestStatus& aStatus) sl@0: /** sl@0: Determines whether the system server should perform the service requested sl@0: by the client application. Depending on licensee configuration this function sl@0: will either complete immediately if the client passed the system servers sl@0: security policy check. Alternatively, every request may require additional sl@0: authorisation by the User Prompt Service. sl@0: sl@0: @see RUpsSubsession::AuthoriseInternal sl@0: sl@0: @param aServerCheckOk Whether the client request passed the security check sl@0: implemented by the system server e.g. does the client sl@0: have the correct capabilities for the requested service. sl@0: @param aServiceId Service which the client wants to use. sl@0: @param aDestination More information about the service, e.g. this sl@0: could be a telephone number is the client wanted sl@0: to make a call. sl@0: @param aOpaqueData Additional information to describe the request. sl@0: @param aDecision When the request completes successfully, the verdict sl@0: is written to this variable. sl@0: @param aStatus The server completes this request object when it sl@0: has finished handling the request. sl@0: @capability ProtServ sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised)); sl@0: sl@0: AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, aOpaqueData, aDecision, aStatus); sl@0: } sl@0: sl@0: sl@0: void RUpsSubsession::AuthoriseInternal( sl@0: TBool aServerCheckOk, sl@0: const TServiceId& aServiceId, sl@0: const TDesC& aDestination, sl@0: const TDesC8& aOpaqueData, sl@0: TUpsDecision& aDecision, sl@0: TRequestStatus& aStatus) sl@0: /** sl@0: This helper function is called by the exported overloads of Authorise. sl@0: It sends the data supplied by the SS to the UPS server. sl@0: sl@0: @param aServerCheckOk Did the system server checks pass? sl@0: @param aServiceId Service which the client wants to use. sl@0: @param aDestination More information about the service, e.g. this sl@0: could be a telephone number is the client wanted sl@0: to make a call. sl@0: @param aOpaqueData Additional information to describe the request. sl@0: This is KNullDesC8 if the SS used the Authorise overload sl@0: which did not take opaque data. sl@0: @param aDecision When the request completes successfully, the verdict sl@0: is written to this variable. sl@0: @param aStatus The server completes this request object when it sl@0: has finished handling the request. sl@0: @capability ProtServ sl@0: */ sl@0: { sl@0: TBool decided = EFalse; sl@0: TInt err = KErrNone; sl@0: sl@0: __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised)); sl@0: CUpsClientConfig::TQueryUpsResult result = iUpsSession->iClientConfig->QueryUps(aServerCheckOk, aServiceId, iClientSid, iClientPid); sl@0: switch(result) sl@0: { sl@0: case CUpsClientConfig::EAllow: sl@0: decided = ETrue; sl@0: aDecision = EUpsDecYes; sl@0: break; sl@0: sl@0: case CUpsClientConfig::EQueryUps: sl@0: break; sl@0: sl@0: case CUpsClientConfig::EReject: sl@0: decided = ETrue; sl@0: aDecision = EUpsDecNo; sl@0: break; sl@0: BULLSEYE_OFF sl@0: default: sl@0: break; sl@0: } sl@0: BULLSEYE_RESTORE sl@0: sl@0: if(!decided && !iSubsessionCreated) sl@0: { sl@0: // We need to query the UPS, but have not created the subsession yet. sl@0: err = CreateSubsession(); sl@0: if(err != KErrNone) sl@0: { sl@0: aDecision = EUpsDecNo; sl@0: decided = ETrue; sl@0: } sl@0: else sl@0: { sl@0: iSubsessionCreated = ETrue; sl@0: // aDecision will be set when we query the UPS sl@0: } sl@0: } sl@0: sl@0: if(decided) sl@0: { sl@0: // Either do not need to query UPS, or an error occured, so complete client sl@0: // and return sl@0: aStatus = KRequestPending; sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, err); sl@0: return; // Either do not need to query UPS, or an error occured, so return sl@0: } sl@0: sl@0: // sl@0: // Query UPS sl@0: // sl@0: // only three arguments can be sent to a subsession, so split sl@0: // this operation into two stages. sl@0: sl@0: TInt r = PreparePrompt(aServiceId, aDestination, aOpaqueData); sl@0: if (r != KErrNone) sl@0: { sl@0: TRequestStatus* prs = &aStatus; sl@0: User::RequestComplete(prs, r); sl@0: return; sl@0: } sl@0: sl@0: ExecutePrompt(aServerCheckOk, aDecision, aStatus); sl@0: } sl@0: sl@0: TInt RUpsSubsession::PreparePrompt(const TServiceId& aServiceId, const TDesC& aDestination, const TDesC8& aOpaqueData) sl@0: /** sl@0: Ask the UPS server to prepare to make a decision. This will be followed sl@0: by a call to ExecutePrompt. sl@0: sl@0: @param aServiceId Service which the client wants to use. sl@0: @param aDestination More information about the service, e.g. this sl@0: could be a telephone number is the client wanted sl@0: to make a call. sl@0: @param aOpaqueData Additional information to describe the request. sl@0: This is KNullDesC8 if the SS used the Authorise overload sl@0: which did not take opaque data. sl@0: @return Error code with which the server completed the request. sl@0: @capability ProtServ sl@0: @see ExecutePrompt sl@0: */ sl@0: { sl@0: TIpcArgs args(aServiceId.iUid, &aDestination, &aOpaqueData); sl@0: return CallSubsessionFunction(ESubsessPreparePrompt, args); sl@0: } sl@0: sl@0: void RUpsSubsession::ExecutePrompt(TBool aServerCheckOk, TUpsDecision& aDecision, TRequestStatus& aStatus) sl@0: /** sl@0: Ask the UPS to execute the request which was set up with PreparePrompt. sl@0: sl@0: @param aDecision When the request completes successfully, this argument sl@0: is updated with the verdict. sl@0: @param aStatus The server completes this request object when it sl@0: has finished handling the request. sl@0: @capability ProtServ sl@0: @see PreparePrompt sl@0: */ sl@0: { sl@0: TUint8* decPtr = reinterpret_cast(&aDecision); sl@0: iDecPtr.Set(decPtr, sizeof(TUpsDecision), sizeof(TUpsDecision)); sl@0: sl@0: TIpcArgs args(&iDecPtr, aServerCheckOk); sl@0: CallSubsessionFunction(ESubsessExecutePrompt, args, aStatus); sl@0: } sl@0: sl@0: EXPORT_C void RUpsSubsession::CancelPrompt() sl@0: /** sl@0: Cancel the prompt request which was launched by calling Authorise. sl@0: sl@0: This function has no effect if there is no outstanding request. sl@0: @capability ProtServ sl@0: */ sl@0: { sl@0: if(iSubsessionCreated) sl@0: { sl@0: CancelSubsessionFunction(ESubsessExecutePrompt); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void RUpsSubsession::Close() sl@0: /** sl@0: Close and clean up this subsession object. sl@0: */ sl@0: { sl@0: if(iSubsessionCreated) sl@0: { sl@0: RScsClientSubsessionBase::Close(); sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: } // End of namespace UserPromptService sl@0: sl@0: // End of file