resourcemgmt/powerandmemorynotificationservice/src/savenotf.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resourcemgmt/powerandmemorynotificationservice/src/savenotf.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,340 @@
+// Copyright (c) 1997-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 <savenotf.h>
+#include <e32std.h>
+#include <e32math.h>
+#include <savepriv.h>
+#include <e32svr.h>
+
+const TInt KNumConnectRetries	=10;
+
+const TUid KServerUid3={0x10004902};
+
+#ifdef TEST_SHUTDOWN_SERVER 
+_LIT(KTestShutdownServerName,"testshutdownsrvs");
+#else
+_LIT(KShutdownSrvName,"shutdownsrvs");
+#endif	//TEST_SHUTDOWN_SERVER 
+
+//
+// class RSaveSession
+//
+/**
+This method will establish the connection with the shutdown server. If the shutdown server
+is not started yet, it will be started.
+@return KErrNone The connection was established successfully.
+@return Some other system-wide error codes
+*/
+TInt RSaveSession::ConnectL()
+	{
+	TInt err=KErrNone;
+	TInt retry=KNumConnectRetries;
+	FOREVER
+		{
+		#ifdef TEST_SHUTDOWN_SERVER 
+		err = CreateSession(__TEST_SHUTDOWN_SERVER_NAME, TVersion(0,0,0));
+		#else
+		err = CreateSession(__SHUTDOWN_SERVER_NAME, TVersion(KShutdownMajorVN,KShutdownMinorVN,KShutdownBuildVN), KShutdownMessageSlots);
+		#endif
+		if ((--retry>0) && ((err==KErrNotFound) || (err==KErrServerTerminated)))
+			{
+			err = StartServerL();
+			if ((err!=KErrNone) && (err!=KErrAlreadyExists))
+				{
+				break;
+				}
+			}
+		else
+			{
+			break;
+			}
+		}
+	return err;
+	}
+
+/**
+This method starts the shutdown server.
+@return KErrNone The server was startedsuccessfully.
+@return KErrAlreadyExists The server is started already.
+@return Some other system-wide error codes
+*/
+TInt RSaveSession::StartServerL()
+	{
+	TInt error=KErrNone;
+	const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
+
+	RProcess server;
+	#ifdef TEST_SHUTDOWN_SERVER 
+	error = server.Create(KTestShutdownServerName,KNullDesC,serverUid);
+	#else
+	error = server.Create(KShutdownSrvName,KNullDesC,serverUid);
+	#endif
+	if(error!=KErrNone)
+		return error;
+ 	TRequestStatus stat;
+	server.Rendezvous(stat);
+ 	if (stat!=KRequestPending)
+ 		server.Kill(0);		// abort startup
+ 	else
+ 		server.Resume();	// logon OK - start the server
+ 	User::WaitForRequest(stat);		// wait for start or death
+ 	// we can't use the 'exit reason' if the server panicked as this
+ 	// is the panic 'reason' and may be '0' which cannot be distinguished
+ 	// from KErrNone
+ 	error=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
+	server.Close();
+	return error;
+	}
+
+/**
+This method sends client's registration request to the shutdown server.
+This is an asynchronous request. It will be completed by the server later,
+at the moment of power down/low memory event.
+@param aStatus An output parameter - the request status.
+*/
+void RSaveSession::NotifySave(TRequestStatus& aStatus)
+	{
+	aStatus=KRequestPending;
+	SendReceive(TSaveOpCodeNotify,aStatus);
+	}
+
+/**
+This method sends client's cancel registration request to the shutdown server.
+This is a synchronous request.
+*/
+void RSaveSession::NotifySaveCancel()
+	{
+	SendReceive(TSaveOpCodeNotifyCancel);
+	}
+
+/**
+With SYSLIBS_TEST macro defined, this method initiates a powerdown sequence. 
+Otherwise, it returns with KErrNotSupported.
+@param aAction The action, which will be given to the clients, when calling their 
+               MSaveObserver::SaveL() implementations.
+@param aPowerOff Non-zero if you want to switch the power off.
+@return KErrNone, if it sends the powerdown request to the server successfully. KErrServerTerminated, 
+if the server no longer present; KErrServerBusy, if there are no message slots available; 
+KErrNoMemory, if there is insufficient memory available.
+*/
+#ifdef SYSLIBS_TEST 
+TInt RSaveSession::SwitchOff(MSaveObserver::TSaveType aAction, TBool aPowerOff)
+    {
+	return SendReceive(TSaveOpCodePowerOff, TIpcArgs(aAction, aPowerOff));
+    }
+#else
+TInt RSaveSession::SwitchOff(MSaveObserver::TSaveType /*aAction*/, TBool /*aPowerOff*/)
+    {
+	return KErrNotSupported;
+    }
+#endif    
+
+/**
+With SYSLIBS_TEST macro defined, this method sends a request to query the power state of the server. 
+Otherwise, it returns with KErrNotSupported.
+@param aPowerOff The result of the query. Non-zero if the power state of the server is off.
+@return KErrNone, if it gets the power state from the server successfully. KErrServerTerminated, 
+if the server no longer present; KErrServerBusy, if there are no message slots available; 
+KErrNoMemory, if there is insufficient memory available.
+*/
+#ifdef SYSLIBS_TEST 
+TInt RSaveSession::ServerPowerState(TBool& aPowerOff)
+	{
+	TPckg<TBool> powerOffPckg(aPowerOff);
+	return SendReceive(TSaveOpCodeQueryPowerState, TIpcArgs(&powerOffPckg));
+	}
+#else
+TInt RSaveSession::ServerPowerState(TBool& /*aPowerOff*/)
+	{
+	return KErrNotSupported;
+	}
+#endif
+//
+// class CSaveNotifier : public CActive
+//
+
+enum TFlags
+	{
+	EDelayRequeue	=0x03,
+	};
+
+/**
+@param aObserver A reference to the client's object, which implements MSaveObserver::SaveL() method.
+@see MSaveObserver class.
+*/
+inline CSaveNotifier::CSaveNotifier(MSaveObserver& aObserver): 
+	CActive(CActive::EPriorityStandard),
+	iSaveObserver(aObserver)
+	{
+    }
+
+/**
+Standard phase one factory method for creating CSaveNotifier instances.
+The caller of this method will be automatically registered to receive powerdown/low memory
+notifications from the shutdown server.
+@param aObserver A reference to the client's object, which implements MSaveObserver::SaveL() method.
+@return A pointer to the created CSaveNotifier instance.
+@see MSaveObserver class.
+*/
+EXPORT_C CSaveNotifier* CSaveNotifier::NewL(MSaveObserver& aObserver)
+	{ // static
+	CSaveNotifier* self=new(ELeave) CSaveNotifier(aObserver);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	self->Start();
+	CleanupStack::Pop();
+	return self;
+	}
+
+/**
+*/
+EXPORT_C CSaveNotifier::~CSaveNotifier()
+	{
+	Cancel();
+	iSaveSession.Close();
+	}
+
+/**
+This method can delay/stop the powerdown sequence, if called after the client got the
+powerdown notification (inside MSaveObserver::SaveL() implementation).
+@see CSaveNotifier::Queue()
+*/
+EXPORT_C void CSaveNotifier::DelayRequeue()
+	{
+	iFlags|=EDelayRequeue;
+	}
+
+/**
+This method re-register the client to receive powerdown/low memory notifications from the
+shutdown server. It clears the effect of CSaveNotifier::DelayRequeue() call.
+@see CSaveNotifier::DelayRequeue()
+*/
+EXPORT_C void CSaveNotifier::Queue()
+	{
+	iFlags&=~EDelayRequeue;
+	Start();
+	}
+
+/**
+The client will call this method if an error occurred during the powerdown processing.
+But it ignores the error code supplied and re-queues for further events.
+@param aError The error code.
+@deprecated The server will not handle the error message from the client.
+*/
+EXPORT_C void CSaveNotifier::HandleError(TInt /*aError*/)
+	{
+  	if (!IsActive())
+  		{
+  		Queue();		
+		}
+	}
+
+/**
+Standard phase-two construction method for creating CSaveNotifier instances.
+It creates a session with the shutdown server.
+*/
+void CSaveNotifier::ConstructL()
+	{
+	User::LeaveIfError(iSaveSession.ConnectL());
+	CActiveScheduler::Add(this);
+	}
+
+/**
+The method notifies the shutdown server tha the client wants to be notified when there is an
+event like powerdown/low memory (client registration).
+*/
+void CSaveNotifier::Start()
+	{
+	if (!(iFlags&EDelayRequeue))
+		{
+		iStatus=KRequestPending;
+		SetActive();
+		iSaveSession.NotifySave(iStatus);
+		}
+	}
+
+/**
+The method cancels the client's registration.
+*/
+void CSaveNotifier::DoCancel()
+	{
+	iSaveSession.NotifySaveCancel();
+	}
+
+/**
+This method gets called when the shutdown server completes the client request for notification,
+registered when NotifySave() was called.
+It calls the implementation of MSaveObserver::SaveL().
+*/
+void CSaveNotifier::RunL()
+	{
+	const TInt status=iStatus.Int();
+	if (status<0)
+		{
+		User::Leave(status);
+		}
+	else
+		{
+		MSaveObserver::TSaveType saveType=(MSaveObserver::TSaveType)status;
+		TRAPD(err,iSaveObserver.SaveL(saveType));
+		Start();
+		User::LeaveIfError(err);
+		}
+	}
+
+/**
+With SYSLIBS_TEST macro defined, this method initiates a powerdown sequence. 
+Otherwise, it returns with KErrNotSupported.
+@param aAction The action, which will be given to the clients, when calling their 
+               MSaveObserver::SaveL() implementations.
+@param aPowerOff Non-zero if you want to switch the power off.
+@return KErrNone, if it sends the powerdown request to the server successfully. KErrServerTerminated, 
+if the server no longer present; KErrServerBusy, if there are no message slots available; 
+KErrNoMemory, if there is insufficient memory available.
+@internalComponent
+*/
+#ifdef SYSLIBS_TEST 
+EXPORT_C TInt CSaveNotifier::SwitchOff(MSaveObserver::TSaveType aAction, TBool aPowerOff)
+    {
+    return iSaveSession.SwitchOff(aAction, aPowerOff);
+    }
+#else
+EXPORT_C TInt CSaveNotifier::SwitchOff(MSaveObserver::TSaveType /*aAction*/, TBool /*aPowerOff*/)
+    {
+    return KErrNotSupported;
+    }
+#endif
+
+/**
+With SYSLIBS_TEST macro defined, this method sends a request to query the power state of the server. 
+Otherwise, it returns with KErrNotSupported.
+@param aPowerOff The result of the query. Non-zero if the power state of the server is off.
+@return KErrNone, if it gets the power state from the server successfully. KErrServerTerminated, 
+if the server no longer present; KErrServerBusy, if there are no message slots available; 
+KErrNoMemory, if there is insufficient memory available.
+@internalComponent
+*/
+#ifdef SYSLIBS_TEST 
+EXPORT_C TInt CSaveNotifier::ServerPowerState(TBool& aPowerOff)
+	{
+	return iSaveSession.ServerPowerState(aPowerOff);
+	}
+#else
+EXPORT_C TInt CSaveNotifier::ServerPowerState(TBool& /*aPowerOff*/)
+	{
+    return KErrNotSupported;
+    }
+#endif