resourcemgmt/powerandmemorynotificationservice/src/savenotf.cpp
changeset 0 4e1aa6a622a0
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <savenotf.h>
       
    17 #include <e32std.h>
       
    18 #include <e32math.h>
       
    19 #include <savepriv.h>
       
    20 #include <e32svr.h>
       
    21 
       
    22 const TInt KNumConnectRetries	=10;
       
    23 
       
    24 const TUid KServerUid3={0x10004902};
       
    25 
       
    26 #ifdef TEST_SHUTDOWN_SERVER 
       
    27 _LIT(KTestShutdownServerName,"testshutdownsrvs");
       
    28 #else
       
    29 _LIT(KShutdownSrvName,"shutdownsrvs");
       
    30 #endif	//TEST_SHUTDOWN_SERVER 
       
    31 
       
    32 //
       
    33 // class RSaveSession
       
    34 //
       
    35 /**
       
    36 This method will establish the connection with the shutdown server. If the shutdown server
       
    37 is not started yet, it will be started.
       
    38 @return KErrNone The connection was established successfully.
       
    39 @return Some other system-wide error codes
       
    40 */
       
    41 TInt RSaveSession::ConnectL()
       
    42 	{
       
    43 	TInt err=KErrNone;
       
    44 	TInt retry=KNumConnectRetries;
       
    45 	FOREVER
       
    46 		{
       
    47 		#ifdef TEST_SHUTDOWN_SERVER 
       
    48 		err = CreateSession(__TEST_SHUTDOWN_SERVER_NAME, TVersion(0,0,0));
       
    49 		#else
       
    50 		err = CreateSession(__SHUTDOWN_SERVER_NAME, TVersion(KShutdownMajorVN,KShutdownMinorVN,KShutdownBuildVN), KShutdownMessageSlots);
       
    51 		#endif
       
    52 		if ((--retry>0) && ((err==KErrNotFound) || (err==KErrServerTerminated)))
       
    53 			{
       
    54 			err = StartServerL();
       
    55 			if ((err!=KErrNone) && (err!=KErrAlreadyExists))
       
    56 				{
       
    57 				break;
       
    58 				}
       
    59 			}
       
    60 		else
       
    61 			{
       
    62 			break;
       
    63 			}
       
    64 		}
       
    65 	return err;
       
    66 	}
       
    67 
       
    68 /**
       
    69 This method starts the shutdown server.
       
    70 @return KErrNone The server was startedsuccessfully.
       
    71 @return KErrAlreadyExists The server is started already.
       
    72 @return Some other system-wide error codes
       
    73 */
       
    74 TInt RSaveSession::StartServerL()
       
    75 	{
       
    76 	TInt error=KErrNone;
       
    77 	const TUidType serverUid(KNullUid,KNullUid,KServerUid3);
       
    78 
       
    79 	RProcess server;
       
    80 	#ifdef TEST_SHUTDOWN_SERVER 
       
    81 	error = server.Create(KTestShutdownServerName,KNullDesC,serverUid);
       
    82 	#else
       
    83 	error = server.Create(KShutdownSrvName,KNullDesC,serverUid);
       
    84 	#endif
       
    85 	if(error!=KErrNone)
       
    86 		return error;
       
    87  	TRequestStatus stat;
       
    88 	server.Rendezvous(stat);
       
    89  	if (stat!=KRequestPending)
       
    90  		server.Kill(0);		// abort startup
       
    91  	else
       
    92  		server.Resume();	// logon OK - start the server
       
    93  	User::WaitForRequest(stat);		// wait for start or death
       
    94  	// we can't use the 'exit reason' if the server panicked as this
       
    95  	// is the panic 'reason' and may be '0' which cannot be distinguished
       
    96  	// from KErrNone
       
    97  	error=(server.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
       
    98 	server.Close();
       
    99 	return error;
       
   100 	}
       
   101 
       
   102 /**
       
   103 This method sends client's registration request to the shutdown server.
       
   104 This is an asynchronous request. It will be completed by the server later,
       
   105 at the moment of power down/low memory event.
       
   106 @param aStatus An output parameter - the request status.
       
   107 */
       
   108 void RSaveSession::NotifySave(TRequestStatus& aStatus)
       
   109 	{
       
   110 	aStatus=KRequestPending;
       
   111 	SendReceive(TSaveOpCodeNotify,aStatus);
       
   112 	}
       
   113 
       
   114 /**
       
   115 This method sends client's cancel registration request to the shutdown server.
       
   116 This is a synchronous request.
       
   117 */
       
   118 void RSaveSession::NotifySaveCancel()
       
   119 	{
       
   120 	SendReceive(TSaveOpCodeNotifyCancel);
       
   121 	}
       
   122 
       
   123 /**
       
   124 With SYSLIBS_TEST macro defined, this method initiates a powerdown sequence. 
       
   125 Otherwise, it returns with KErrNotSupported.
       
   126 @param aAction The action, which will be given to the clients, when calling their 
       
   127                MSaveObserver::SaveL() implementations.
       
   128 @param aPowerOff Non-zero if you want to switch the power off.
       
   129 @return KErrNone, if it sends the powerdown request to the server successfully. KErrServerTerminated, 
       
   130 if the server no longer present; KErrServerBusy, if there are no message slots available; 
       
   131 KErrNoMemory, if there is insufficient memory available.
       
   132 */
       
   133 #ifdef SYSLIBS_TEST 
       
   134 TInt RSaveSession::SwitchOff(MSaveObserver::TSaveType aAction, TBool aPowerOff)
       
   135     {
       
   136 	return SendReceive(TSaveOpCodePowerOff, TIpcArgs(aAction, aPowerOff));
       
   137     }
       
   138 #else
       
   139 TInt RSaveSession::SwitchOff(MSaveObserver::TSaveType /*aAction*/, TBool /*aPowerOff*/)
       
   140     {
       
   141 	return KErrNotSupported;
       
   142     }
       
   143 #endif    
       
   144 
       
   145 /**
       
   146 With SYSLIBS_TEST macro defined, this method sends a request to query the power state of the server. 
       
   147 Otherwise, it returns with KErrNotSupported.
       
   148 @param aPowerOff The result of the query. Non-zero if the power state of the server is off.
       
   149 @return KErrNone, if it gets the power state from the server successfully. KErrServerTerminated, 
       
   150 if the server no longer present; KErrServerBusy, if there are no message slots available; 
       
   151 KErrNoMemory, if there is insufficient memory available.
       
   152 */
       
   153 #ifdef SYSLIBS_TEST 
       
   154 TInt RSaveSession::ServerPowerState(TBool& aPowerOff)
       
   155 	{
       
   156 	TPckg<TBool> powerOffPckg(aPowerOff);
       
   157 	return SendReceive(TSaveOpCodeQueryPowerState, TIpcArgs(&powerOffPckg));
       
   158 	}
       
   159 #else
       
   160 TInt RSaveSession::ServerPowerState(TBool& /*aPowerOff*/)
       
   161 	{
       
   162 	return KErrNotSupported;
       
   163 	}
       
   164 #endif
       
   165 //
       
   166 // class CSaveNotifier : public CActive
       
   167 //
       
   168 
       
   169 enum TFlags
       
   170 	{
       
   171 	EDelayRequeue	=0x03,
       
   172 	};
       
   173 
       
   174 /**
       
   175 @param aObserver A reference to the client's object, which implements MSaveObserver::SaveL() method.
       
   176 @see MSaveObserver class.
       
   177 */
       
   178 inline CSaveNotifier::CSaveNotifier(MSaveObserver& aObserver): 
       
   179 	CActive(CActive::EPriorityStandard),
       
   180 	iSaveObserver(aObserver)
       
   181 	{
       
   182     }
       
   183 
       
   184 /**
       
   185 Standard phase one factory method for creating CSaveNotifier instances.
       
   186 The caller of this method will be automatically registered to receive powerdown/low memory
       
   187 notifications from the shutdown server.
       
   188 @param aObserver A reference to the client's object, which implements MSaveObserver::SaveL() method.
       
   189 @return A pointer to the created CSaveNotifier instance.
       
   190 @see MSaveObserver class.
       
   191 */
       
   192 EXPORT_C CSaveNotifier* CSaveNotifier::NewL(MSaveObserver& aObserver)
       
   193 	{ // static
       
   194 	CSaveNotifier* self=new(ELeave) CSaveNotifier(aObserver);
       
   195 	CleanupStack::PushL(self);
       
   196 	self->ConstructL();
       
   197 	self->Start();
       
   198 	CleanupStack::Pop();
       
   199 	return self;
       
   200 	}
       
   201 
       
   202 /**
       
   203 */
       
   204 EXPORT_C CSaveNotifier::~CSaveNotifier()
       
   205 	{
       
   206 	Cancel();
       
   207 	iSaveSession.Close();
       
   208 	}
       
   209 
       
   210 /**
       
   211 This method can delay/stop the powerdown sequence, if called after the client got the
       
   212 powerdown notification (inside MSaveObserver::SaveL() implementation).
       
   213 @see CSaveNotifier::Queue()
       
   214 */
       
   215 EXPORT_C void CSaveNotifier::DelayRequeue()
       
   216 	{
       
   217 	iFlags|=EDelayRequeue;
       
   218 	}
       
   219 
       
   220 /**
       
   221 This method re-register the client to receive powerdown/low memory notifications from the
       
   222 shutdown server. It clears the effect of CSaveNotifier::DelayRequeue() call.
       
   223 @see CSaveNotifier::DelayRequeue()
       
   224 */
       
   225 EXPORT_C void CSaveNotifier::Queue()
       
   226 	{
       
   227 	iFlags&=~EDelayRequeue;
       
   228 	Start();
       
   229 	}
       
   230 
       
   231 /**
       
   232 The client will call this method if an error occurred during the powerdown processing.
       
   233 But it ignores the error code supplied and re-queues for further events.
       
   234 @param aError The error code.
       
   235 @deprecated The server will not handle the error message from the client.
       
   236 */
       
   237 EXPORT_C void CSaveNotifier::HandleError(TInt /*aError*/)
       
   238 	{
       
   239   	if (!IsActive())
       
   240   		{
       
   241   		Queue();		
       
   242 		}
       
   243 	}
       
   244 
       
   245 /**
       
   246 Standard phase-two construction method for creating CSaveNotifier instances.
       
   247 It creates a session with the shutdown server.
       
   248 */
       
   249 void CSaveNotifier::ConstructL()
       
   250 	{
       
   251 	User::LeaveIfError(iSaveSession.ConnectL());
       
   252 	CActiveScheduler::Add(this);
       
   253 	}
       
   254 
       
   255 /**
       
   256 The method notifies the shutdown server tha the client wants to be notified when there is an
       
   257 event like powerdown/low memory (client registration).
       
   258 */
       
   259 void CSaveNotifier::Start()
       
   260 	{
       
   261 	if (!(iFlags&EDelayRequeue))
       
   262 		{
       
   263 		iStatus=KRequestPending;
       
   264 		SetActive();
       
   265 		iSaveSession.NotifySave(iStatus);
       
   266 		}
       
   267 	}
       
   268 
       
   269 /**
       
   270 The method cancels the client's registration.
       
   271 */
       
   272 void CSaveNotifier::DoCancel()
       
   273 	{
       
   274 	iSaveSession.NotifySaveCancel();
       
   275 	}
       
   276 
       
   277 /**
       
   278 This method gets called when the shutdown server completes the client request for notification,
       
   279 registered when NotifySave() was called.
       
   280 It calls the implementation of MSaveObserver::SaveL().
       
   281 */
       
   282 void CSaveNotifier::RunL()
       
   283 	{
       
   284 	const TInt status=iStatus.Int();
       
   285 	if (status<0)
       
   286 		{
       
   287 		User::Leave(status);
       
   288 		}
       
   289 	else
       
   290 		{
       
   291 		MSaveObserver::TSaveType saveType=(MSaveObserver::TSaveType)status;
       
   292 		TRAPD(err,iSaveObserver.SaveL(saveType));
       
   293 		Start();
       
   294 		User::LeaveIfError(err);
       
   295 		}
       
   296 	}
       
   297 
       
   298 /**
       
   299 With SYSLIBS_TEST macro defined, this method initiates a powerdown sequence. 
       
   300 Otherwise, it returns with KErrNotSupported.
       
   301 @param aAction The action, which will be given to the clients, when calling their 
       
   302                MSaveObserver::SaveL() implementations.
       
   303 @param aPowerOff Non-zero if you want to switch the power off.
       
   304 @return KErrNone, if it sends the powerdown request to the server successfully. KErrServerTerminated, 
       
   305 if the server no longer present; KErrServerBusy, if there are no message slots available; 
       
   306 KErrNoMemory, if there is insufficient memory available.
       
   307 @internalComponent
       
   308 */
       
   309 #ifdef SYSLIBS_TEST 
       
   310 EXPORT_C TInt CSaveNotifier::SwitchOff(MSaveObserver::TSaveType aAction, TBool aPowerOff)
       
   311     {
       
   312     return iSaveSession.SwitchOff(aAction, aPowerOff);
       
   313     }
       
   314 #else
       
   315 EXPORT_C TInt CSaveNotifier::SwitchOff(MSaveObserver::TSaveType /*aAction*/, TBool /*aPowerOff*/)
       
   316     {
       
   317     return KErrNotSupported;
       
   318     }
       
   319 #endif
       
   320 
       
   321 /**
       
   322 With SYSLIBS_TEST macro defined, this method sends a request to query the power state of the server. 
       
   323 Otherwise, it returns with KErrNotSupported.
       
   324 @param aPowerOff The result of the query. Non-zero if the power state of the server is off.
       
   325 @return KErrNone, if it gets the power state from the server successfully. KErrServerTerminated, 
       
   326 if the server no longer present; KErrServerBusy, if there are no message slots available; 
       
   327 KErrNoMemory, if there is insufficient memory available.
       
   328 @internalComponent
       
   329 */
       
   330 #ifdef SYSLIBS_TEST 
       
   331 EXPORT_C TInt CSaveNotifier::ServerPowerState(TBool& aPowerOff)
       
   332 	{
       
   333 	return iSaveSession.ServerPowerState(aPowerOff);
       
   334 	}
       
   335 #else
       
   336 EXPORT_C TInt CSaveNotifier::ServerPowerState(TBool& /*aPowerOff*/)
       
   337 	{
       
   338     return KErrNotSupported;
       
   339     }
       
   340 #endif