diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/plugins/alftranseffect/alftranseffectplugin/src/alfpolicyrequesthandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/plugins/alftranseffect/alftranseffectplugin/src/alfpolicyrequesthandler.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,678 @@ +/* +* Copyright (c) 2006 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: Contains a class that is responsible for sending policy updates +* to connected clients +* +*/ + + + +#include +#include + +//======== USER INCLUDES ======== +#include "alfpolicyrequesthandler.h" +#include "alfpolicyhandler.h" +//#include "tfxserverdef.h" +#include + + +// ======== HELPER CLASS FUNCTIONS ======== + +CPolicyEventReq::CPolicyEventReq() + { + } + +// --------------------------------------------------------------------------- +// Destructor for CPolicyEventReq +// --------------------------------------------------------------------------- +// +CPolicyEventReq::~CPolicyEventReq() + { + iOriginalControlPolicies.ResetAndDestroy(); + iAddedPolicies.ResetAndDestroy(); + iRemovedPolicies.ResetAndDestroy(); + + if(!iMessage.IsNull() && iMessage.Handle() != 0) // We should release a a stored message. + { + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, Disconnected"); + iMessage.Complete( KErrDisconnected ); + } + } + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// +TUint CPolicyEventReq::TotalPolicyCount() const + { + TUint count = 0; + for ( TInt i = iOriginalControlPolicies.Count() - 1; i >= 0; --i ) + { + count += iOriginalControlPolicies[i]->iControlPolicies.Count(); + } + count += iAddedPolicies.Count(); + count += iRemovedPolicies.Count(); + return count; + } + +// --------------------------------------------------------------------------- +// Constructor for CClientControlPolicy +// --------------------------------------------------------------------------- +// +CClientControlPolicy::CClientControlPolicy() + { + } + + +// --------------------------------------------------------------------------- +// Destructor for CClientControlPolicy +// --------------------------------------------------------------------------- +// +CClientControlPolicy::~CClientControlPolicy() + { + + for( TInt i = iControlPolicies.Count() - 1; i >= 0; i--) + { + iControlPolicies.Remove(i); + } + + iControlPolicies.Close(); + iResourceDir.Close(); + iFilename.Close(); + } + + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CPolicyClientRequestHandler::CPolicyClientRequestHandler(CPolicyHandler* aParent) : + iParent(aParent) + { + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CPolicyClientRequestHandler::~CPolicyClientRequestHandler() + { + RemoveDeadClients(); + iControlPolicyClients.ResetAndDestroy(); + } + + +// --------------------------------------------------------------------------- +// Iterates over all connected clients and appends a policy to each if necessary. +// --------------------------------------------------------------------------- +// +void CPolicyClientRequestHandler::RegisterControlAction(const TUid aUid, TUint aAction) + { + CPolicyEventReq* pPolReq = NULL; + + // Look for existing clients. If none found, all is OK. + TInt contrCount = iControlPolicyClients.Count(); + // We have some connected clients. Update the new policies for all of these. + for(TInt i = 0; i < contrCount; i++) + { + pPolReq = iControlPolicyClients[i]; + // Checking if we already have stored the policy. Since we only have a copy of the pointer + // to the original object we need not update it. It has already been done in the policyhandler. + if(KErrNone == CheckStoredControlPolicy(pPolReq->iOriginalControlPolicies, aUid, aAction)) + { + return; + } + // If it's not in the original list, see if we have it somewhere else. If so, complete + // the stored away message if possible. + if(KErrNone == AddControlPolicyAction(pPolReq->iAddedPolicies, pPolReq->iRemovedPolicies, aUid, aAction)) + { + if(!pPolReq->iMessage.IsNull()) + { + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, Register control action"); + pPolReq->iMessage.Complete(KErrNone); + pPolReq->iMessage = RMessagePtr2(); + } + } + } + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::RemoveControlPolicy(const TUid aUid, TUint aAction ) + { + + TInt clientCount = iControlPolicyClients.Count(); + TInt err = KErrNone; + // Lint will complain because the tPol pointer is not deleted here. + // The pointer is stored into a pointerarray and deleted when the array is destroyed. + // This is the reason why this warning/error is disabled. + /*lint -e429 -e830 */ + + for(TInt i = 0; i < clientCount; i++) + { + if( KErrNotFound == RemovePolicyUid(iControlPolicyClients[i]->iOriginalControlPolicies, + aAction, aUid) && + KErrNotFound == RemovePolicyUid(iControlPolicyClients[i]->iAddedPolicies, aAction, aUid)) + { + TControlPolicy* tPol = new TControlPolicy; + if(NULL == tPol) + { + return KErrNoMemory; + } + tPol->iAction = aAction; + tPol->iId = aUid; + tPol->iPolicy = ENotSupported; + + err = iControlPolicyClients[i]->iRemovedPolicies.Append(tPol); //Takes ownership + if( KErrNone != err) + { + delete tPol; + tPol = NULL; + return err; + } + + if(!iControlPolicyClients[i]->iMessage.IsNull()) + { + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, Remove control policy"); + iControlPolicyClients[i]->iMessage.Complete(KErrNone); + iControlPolicyClients[i]->iMessage = RMessagePtr2(); + } + } + } + /*lint +e429 +e830 */ + return KErrNone; + } + + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::RequestPolicy( const RMessage2& aMessage ) + { + TInt err = KErrNone; + CPolicyEventReq* req = NULL; + + RThread client; + err = aMessage.Client( client ); + if( err != KErrNone ) + { + client.Close(); + return err; + } + + TThreadId currClient = client.Id(); + client.Close(); + + TInt clientCount = iControlPolicyClients.Count(); + for( TInt i = 0; i < clientCount; i++ ) + { + req = iControlPolicyClients[i]; + if(req->iClientId == currClient) + { + if( req->iAddedPolicies.Count() == 0 && req->iOriginalControlPolicies.Count() == 0 + && req->iRemovedPolicies.Count() == 0) + { + // Check if it's OK to add this request to the list. + // This is done by just storing the message. + if( req->iMessage.IsNull() ) + { + req->iMessage = aMessage; + return KErrNone; + } + // If message is not null, something is wrong. + return KErrGeneral; + } + // If we have a stored message, complete it. Should not happen! + if( !req->iMessage.IsNull() ) + { + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, stored message, should not happen"); + req->iMessage.Complete( KErrNone ); + // NULLify the message pointer after it has been completed. + // If not done, we can't check if the message is valid or not. + req->iMessage = RMessagePtr2(); + return KErrNone; + } + // Otherwise complete this message. + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, return policy count"); + aMessage.Complete( req->TotalPolicyCount() ); + return KErrNone; + } + } + // Client not found. Insert it! + err = InsertClient( aMessage ); + if( err != KErrNotFound ) + { + // If failed to insert the client, complete the message so it may try again. + // Also, if there are control policies, we report the number of them + // If error is KErrNotFound, we have stored the message, and it will be completed + // later (as soon as there are policies) + __ALFFXLOGSTRING1("CPolicyEventReq:: insert client returned %d", err); + aMessage.Complete( err ); + } + return KErrNone; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::GetPolicyL( TThreadId aClientId, TInt aPolicyCount, TPtr8& aOutBuf ) + { + CPolicyEventReq* req = NULL; + TControlPolicy* tAddPol = NULL; + CActionPolicy* tPol = NULL; + CClientControlPolicy* tOUid = NULL; + TControlPolicy* tRemPol = NULL; + + TThreadId id = aClientId; + TInt count = 0; + RDesWriteStream outstream( aOutBuf ); + CleanupClosePushL( outstream ); + + for( TInt i = iControlPolicyClients.Count() - 1; i >= 0; --i ) + { + req = iControlPolicyClients[i]; + + if ( req->iClientId == id ) + { + int added = 0; + + count = req->TotalPolicyCount(); + if ( count > aPolicyCount ) + { + count = aPolicyCount; + } + outstream.WriteUint32L( count ); + + TInt addedPolicyCount = req->iAddedPolicies.Count(); + TInt origPolicyCount = req->iOriginalControlPolicies.Count(); + TInt removedPoliciesCount = req->iRemovedPolicies.Count(); + + for ( TInt q = origPolicyCount - 1; q >= 0 && added < count; --q ) + { + tOUid = req->iOriginalControlPolicies[q]; + TInt origPolicyInfoCount = tOUid->iControlPolicies.Count(); + for ( TInt qi = origPolicyInfoCount - 1; qi >= 0 && added < count; --qi ) + { + tPol = tOUid->iControlPolicies[qi]; + outstream.WriteInt32L( tOUid->iUid.iUid ); + outstream.WriteInt32L( tPol->iAction ); + outstream.WriteUint8L( tPol->iPolicy ); + added++; + + // Here we only remove the policy from the local list of original policies. + // we don't delete it since it's a copy of the pointer to the + // original object and we don't want to remove it permanently! + tOUid->iControlPolicies.Remove( qi ); + } + if ( tOUid->iControlPolicies.Count() == 0 ) + { + // It's OK to delete tOUid. It doesn't destroy anything except itself! + req->iOriginalControlPolicies.Remove(q); + delete tOUid; + } + } + + for ( TInt z = addedPolicyCount - 1; z >= 0 && added < count; --z ) + { + tAddPol = req->iAddedPolicies[z]; + outstream.WriteInt32L( tAddPol->iId.iUid ); + outstream.WriteInt32L( tAddPol->iAction ); + outstream.WriteUint8L( tAddPol->iPolicy ); + added++; + + // Here we delete the actual object. This is possible since + // it has been created specifically for this client. + delete tAddPol; + req->iAddedPolicies.Remove( z ); + } + for(TInt s = removedPoliciesCount - 1; s >= 0 && added < count; s--) + { + tRemPol = req->iRemovedPolicies[s]; + outstream.WriteInt32L( tRemPol->iId.iUid ); + outstream.WriteInt32L( tRemPol->iAction ); + outstream.WriteUint8L( tRemPol->iPolicy ); + added++; + // Here we delete the actual object. This is possible since + // it has been created specifically for this client. + delete tRemPol; + req->iRemovedPolicies.Remove(s); + } + outstream.CommitL(); + CleanupStack::PopAndDestroy(); // outstream + + return KErrNone; + } + } + + outstream.WriteUint32L( 0 ); + outstream.CommitL(); + CleanupStack::PopAndDestroy(); // outstream + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CPolicyClientRequestHandler::RemoveClient( TThreadId aClientId ) + { + for( TInt i = iControlPolicyClients.Count() - 1; i >= 0; i--) + { + if( iControlPolicyClients[i]->iClientId == aClientId ) + { + if(!iControlPolicyClients[i]->iMessage.IsNull()) + { + __ALFFXLOGSTRING("CPolicyEventReq:: Message complete, remove client"); + iControlPolicyClients[i]->iMessage.Complete( KErrCancel ); + iControlPolicyClients[i]->iMessage = RMessage2(); //Null message so destructor wont try to complete. + } + delete iControlPolicyClients[i]; + iControlPolicyClients.Remove(i); + } + } + } + +// --------------------------------------------------------------------------- +// Removes all requests belonging to a terminated client. +// --------------------------------------------------------------------------- +// +void CPolicyClientRequestHandler::RemoveDeadClients() + { + // Lint seems to have some trouble identifying the TThreadId class. + // Due to this, Lint will report several errors here that are incorrect. + // These errors are disabled. + /*lint -e10 -e1013 -e1055 -e746 -e747 */ + RThread client; + for( TInt i = iControlPolicyClients.Count() - 1; i >= 0; i--) + { + TInt err = client.Open(iControlPolicyClients[i]->iClientId.Id()); + if(err == KErrNone) + { + if(client.ExitType() != EExitPending) + { + //Client is dead, remove from list. + iControlPolicyClients[i]->iMessage = RMessage2(); //Null message so destructor wont try to complete. + delete iControlPolicyClients[i]; + iControlPolicyClients.Remove(i); + } + client.Close(); + } + else + { + //Could not open client, client handle was invalid. + //So clean it up from list too. + iControlPolicyClients[i]->iMessage = RMessage2(); //Null message so destructor wont try to complete. + delete iControlPolicyClients[i]; + iControlPolicyClients.Remove(i); + } + } + /*lint +e10 +e1013 +e1055 +e746 +e747 */ + } + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// +void CPolicyClientRequestHandler::DumpClientsL(RFileWriteStream& aFile) + { + // Lint seems to have some trouble identifying the TThreadId class. + // Due to this, Lint will report several errors here that are incorrect. + // These errors are disabled. + /*lint -e10 -e1013 -e1055 -e746 -e747 */ + for(TInt i = iControlPolicyClients.Count() - 1; i >= 0; i--) + { + TPckgC clientid(iControlPolicyClients[i]->iClientId.Id()); + aFile.WriteL(clientid); + } + /*lint +e10 +e1013 +e1055 +e746 +e747 */ + } + + +// =================== PRIVATE METHODS ============== + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::InsertClient(const RMessage2& aMessage) + { + + TInt err = KErrNone; + + CPolicyEventReq* req = new CPolicyEventReq(); + if (!req) + { + return KErrNoMemory; + } + + // Getting the client ID and storing it. + RThread client; + err = aMessage.Client(client); + if( err != KErrNone ) + { + delete req; + return err; + } + req->iClientId = client.Id(); + client.Close(); + + err = iControlPolicyClients.Append(req); + if( err == KErrNone ) + { + // Requesting all policies from the policy handler. + err = iParent->GetAllControlPolicies( req->iOriginalControlPolicies ); + if( err == KErrNotFound ) + { + // If no polices found, store message for later. + req->iMessage = aMessage; + return err; + } + err = req->TotalPolicyCount(); + } + else + { + delete req; + } + return err; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::AddControlPolicyAction( RPointerArray& aAddedPolicies, + RPointerArray& aRemovedPolicies, + const TUid aUid, TUint aAction) + { + + + // Lint will complain because the tPol pointer is not deleted here. + // The pointer is stored into a pointerarray and deleted when the array is destroyed. + // This is the reason why this warning/error is disabled. + /*lint -e429 -e830 */ + + TControlPolicy* tPol = NULL; + TInt err = KErrNone; + + // Checking if we have any newly added policies. + TInt polUidCount = aAddedPolicies.Count(); + for(TInt i = 0; i < polUidCount; i++) + { + tPol = aAddedPolicies[i]; + if(tPol->iId == aUid && tPol->iAction == aAction) + { + return KErrNone; + } + } + // Checking if this policy has been set to be removed. + polUidCount = aRemovedPolicies.Count(); + for(TInt i = 0; i < polUidCount; i++) + { + tPol = aRemovedPolicies[i]; + if(tPol->iId == aUid && tPol->iAction == aAction) + { + aRemovedPolicies.Remove(i); + delete tPol; + tPol = NULL; + return KErrNone; + } + } + + // No policy found. Adding a new one. + // For some reason Lint doesn't like this if() clause. Perhaps Lint doesn't + // understand that new can return NULL. Disabling the "if always evaluates to False" + // error message. + /*lint -e774 -e831 */ + tPol = NULL; + tPol = new TControlPolicy; + if(NULL == tPol) + { + return KErrNoMemory; + } + /*lint +e774 +e831 */ + + tPol->iAction = aAction; + tPol->iId = aUid; + tPol->iPolicy = ESupported; + + err = aAddedPolicies.Append(tPol); + if(KErrNone == err) + { + return err; + } + + // Clenup on failure + delete tPol; + tPol = NULL; + return err; + + /*lint +e429 +e830 */ + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::CheckStoredControlPolicy( RPointerArray& aPtr, + TUid aUid, TUint aAction) + { + + TInt polUidCount = aPtr.Count(); + for(TInt i = 0; i < polUidCount; i++) + { + if(aPtr[i]->iUid == aUid) + { + TInt actionCount = aPtr[i]->iControlPolicies.Count(); + for(TInt j = 0; j < actionCount; j++) + { + if(aPtr[i]->iControlPolicies[j]->iAction == aAction) + { + return KErrNone; + } + } + } + } + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// + +TInt CPolicyClientRequestHandler::RemovePolicyUid(RPointerArray& aAddedPolicies, TUint aAction, const TUid aUid) + { + TControlPolicy* tUid = NULL; + + TInt policyCount = aAddedPolicies.Count(); + for(TInt i = 0; i < policyCount; i++) + { + tUid = aAddedPolicies[i]; + if(tUid->iId == aUid && tUid->iAction == aAction) + { + delete tUid; + tUid = NULL; + aAddedPolicies.Remove(i); + return KErrNone; + } + } + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::RemovePolicyUid(RPointerArray& aPolUid, TUint aAction, const TUid aUid) + { + CClientControlPolicy* tUid = NULL; + + TInt policyCount = aPolUid.Count(); + for(TInt i = 0; i < policyCount; i++) + { + tUid = aPolUid[i]; + if(tUid->iUid == aUid) + { + TInt err = RemovePolicyInfo(tUid->iControlPolicies, aAction, EFalse); + if ( err == KErrNone) + { + if(tUid->iControlPolicies.Count() == 0) + { + delete tUid; + tUid = NULL; + aPolUid.Remove(i); + } + return err; + } + } + } + return KErrNotFound; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TInt CPolicyClientRequestHandler::RemovePolicyInfo(RPointerArray& aPolInfo, TUint aAction, TBool aDelete) + { + CActionPolicy* tPol = NULL; + TInt polInfoCount = aPolInfo.Count(); + + for(TInt i = 0; i < polInfoCount; i++) + { + tPol = aPolInfo[i]; + if(tPol->iAction == aAction) + { + if(aDelete) + { + delete tPol; + tPol = NULL; + } + aPolInfo.Remove(i); + return KErrNone; + } + } + return KErrNotFound; + } + + + +// --- EOF --- + +