ac_app_context_epoc.cpp

Go to the documentation of this file.
00001 // Not a standalone file. It exists as a separate file only to avoid
00002 // platform-specific clutter in the primary implementation file.
00003 
00004 #include "epoc-s60-version.hpp"
00005 #include "sa_sensor_list_log_db.h"
00006 #include "ut_telephony_epoc.h"
00007 #include "utils_cl2.h" // DEF_SESSION
00008 
00009 #include <f32file.h> // RFs
00010 
00011 #include <etel3rdparty.h> // CTelephony
00012 
00013 #if __NEED_CONTACT_DATABASE__
00014 #include <cntdb.h> // CContactDatabase
00015 #endif
00016 
00017 // --------------------------------------------------
00018 // battery status observing
00019 // --------------------------------------------------
00020 
00021 /*
00022 The primary function of this AO is to exit the process if battery is running low. We do not want to be the ones to consume the last bit of battery.
00023 
00024 As a secondary task, the battery level is also logged, if the required resources have been initialized.
00025 
00026 It is worth noting that there also is the hwrmpowerstatesdkpskeys.h API, which it seems we might likewise use. Do not know if one is "better" than the other.
00027 http://www.forum.nokia.com/document/Cpp_Developers_Library/GUID-759FBC7F-5384-4487-8457-A8D4B76F6AA6/html/hwrmpowerstatesdkpskeys_8h.html
00028 */
00029 
00030 /***koog 
00031 (require codegen/symbian-cxx)
00032 (ctor-defines/spec
00033  "CBatteryObserver" ;; name
00034  "CTelephony& tel, MGetterObs_BatteryInfo& obs" ;; args
00035  "iObserver(obs)" ;; inits
00036  "" ;; ctor
00037  #t ;; ConstructL
00038  '(args-to-constructl)
00039 )
00040  ***/
00041 #define CTOR_DECL_CBatteryObserver  \
00042 public: static CBatteryObserver* NewLC(CTelephony& tel, MGetterObs_BatteryInfo& obs); \
00043 public: static CBatteryObserver* NewL(CTelephony& tel, MGetterObs_BatteryInfo& obs); \
00044 private: CBatteryObserver(CTelephony& tel, MGetterObs_BatteryInfo& obs); \
00045 private: void ConstructL(CTelephony& tel, MGetterObs_BatteryInfo& obs);
00046 
00047 #define CTOR_IMPL_CBatteryObserver  \
00048 CBatteryObserver* CBatteryObserver::NewLC(CTelephony& tel, MGetterObs_BatteryInfo& obs) \
00049 { \
00050   CBatteryObserver* obj = new (ELeave) CBatteryObserver(tel, obs); \
00051   CleanupStack::PushL(obj); \
00052   obj->ConstructL(tel, obs); \
00053   return obj; \
00054 } \
00055  \
00056 CBatteryObserver* CBatteryObserver::NewL(CTelephony& tel, MGetterObs_BatteryInfo& obs) \
00057 { \
00058   CBatteryObserver* obj = CBatteryObserver::NewLC(tel, obs); \
00059   CleanupStack::Pop(obj); \
00060   return obj; \
00061 } \
00062  \
00063 CBatteryObserver::CBatteryObserver(CTelephony& tel, MGetterObs_BatteryInfo& obs) : iObserver(obs) \
00064 {}
00065 /***end***/
00066 NONSHARABLE_CLASS(CBatteryObserver) : 
00067   public CBase, 
00068   public MGetterObs_BatteryInfo,
00069   public MNotifyObs_BatteryInfo
00070 {
00071   CTOR_DECL_CBatteryObserver;
00072 
00073  public:
00074   ~CBatteryObserver();
00075 
00076  private:
00077   virtual void GotData_BatteryInfo(TInt aError);
00078   virtual void ChangedData_BatteryInfo(TInt aError);
00079   void HandleBattery(TInt aError, CTelephony::TBatteryInfoV1 const & aData);
00080 
00081  private:
00082   CGetterAo_BatteryInfo* iBatteryInfoGetter;
00083   CNotifyAo_BatteryInfo* iBatteryInfoNotifier;
00084 
00085  private:
00086   MGetterObs_BatteryInfo& iObserver;
00087 };
00088 
00089 CTOR_IMPL_CBatteryObserver;
00090 
00091 void CBatteryObserver::ConstructL(CTelephony& tel, MGetterObs_BatteryInfo& obs)
00092 {
00093   iBatteryInfoGetter = new (ELeave) CGetterAo_BatteryInfo(tel, *this);
00094   iBatteryInfoNotifier = new (ELeave) CNotifyAo_BatteryInfo(tel, *this);
00095 
00096   iBatteryInfoGetter->MakeRequest();
00097 }
00098 
00099 CBatteryObserver::~CBatteryObserver()
00100 {
00101   delete iBatteryInfoGetter;
00102   delete iBatteryInfoNotifier;
00103 }
00104 
00105 void CBatteryObserver::GotData_BatteryInfo(TInt aError)
00106 {
00107   HandleBattery(aError, iBatteryInfoGetter->Data());
00108   iObserver.GotData_BatteryInfo(aError); // forward
00109 }
00110 
00111 void CBatteryObserver::ChangedData_BatteryInfo(TInt aError)
00112 {
00113   HandleBattery(aError, iBatteryInfoNotifier->Data());
00114 }
00115 
00116 void CBatteryObserver::HandleBattery(TInt aError, 
00117              CTelephony::TBatteryInfoV1 const & aData)
00118 {
00119   if (aError) {
00120     // This is unexpected, but if we cannot query it, then we shall
00121     // live without this feature for the rest of the runtime.
00122     er_log_symbian(0, aError, "battery info status query failure");
00123   } else {
00124     int status = aData.iStatus;
00125     int level = aData.iChargeLevel;
00126     logg("battery status: %d (%d%%)", status, level);
00127 
00128     LogDb* logDb = ac_global_LogDb;
00129     if (logDb) {
00130       log_db_log_battery(logDb, status, level, NULL);
00131     }
00132 
00133 #if __QUIT_ON_LOW_BATTERY__
00134     // If no external power and battery low.
00135     if ((aData.iStatus != CTelephony::EBatteryConnectedButExternallyPowered) &&
00136   (aData.iStatus != CTelephony::ENoBatteryConnected) &&
00137   (aData.iChargeLevel < 20))
00138       {
00139   er_log_none(0, "battery running low (at %d%%): exiting", level);
00140   if (logDb) {
00141     er_fatal_battery_low;
00142   } else {
00143     // This is to avoid repeated error dialogs when the logger
00144     // does not get as far as properly running due to low battery.
00145     er_fatal_quiet();
00146   }
00147       } 
00148     else 
00149 #endif
00150       {
00151   iBatteryInfoNotifier->MakeRequest();
00152       }
00153   }
00154 }
00155 
00156 // --------------------------------------------------
00157 // flightmode observing
00158 // --------------------------------------------------
00159 
00160 /***koog 
00161 (require codegen/symbian-cxx)
00162 (ctor-defines/spec
00163  "CFlightModeObserver" ;; name
00164  "CTelephony& tel, MGetterObs_FlightMode& obs" ;; args
00165  "iObserver(obs)" ;; inits
00166  "" ;; ctor
00167  #t ;; ConstructL
00168  '(args-to-constructl)
00169 )
00170  ***/
00171 #define CTOR_DECL_CFlightModeObserver  \
00172 public: static CFlightModeObserver* NewLC(CTelephony& tel, MGetterObs_FlightMode& obs); \
00173 public: static CFlightModeObserver* NewL(CTelephony& tel, MGetterObs_FlightMode& obs); \
00174 private: CFlightModeObserver(CTelephony& tel, MGetterObs_FlightMode& obs); \
00175 private: void ConstructL(CTelephony& tel, MGetterObs_FlightMode& obs);
00176 
00177 #define CTOR_IMPL_CFlightModeObserver  \
00178 CFlightModeObserver* CFlightModeObserver::NewLC(CTelephony& tel, MGetterObs_FlightMode& obs) \
00179 { \
00180   CFlightModeObserver* obj = new (ELeave) CFlightModeObserver(tel, obs); \
00181   CleanupStack::PushL(obj); \
00182   obj->ConstructL(tel, obs); \
00183   return obj; \
00184 } \
00185  \
00186 CFlightModeObserver* CFlightModeObserver::NewL(CTelephony& tel, MGetterObs_FlightMode& obs) \
00187 { \
00188   CFlightModeObserver* obj = CFlightModeObserver::NewLC(tel, obs); \
00189   CleanupStack::Pop(obj); \
00190   return obj; \
00191 } \
00192  \
00193 CFlightModeObserver::CFlightModeObserver(CTelephony& tel, MGetterObs_FlightMode& obs) : iObserver(obs) \
00194 {}
00195 /***end***/
00196 NONSHARABLE_CLASS(CFlightModeObserver) : 
00197   public CBase, 
00198   public MGetterObs_FlightMode,
00199   public MNotifyObs_FlightMode
00200 {
00201   CTOR_DECL_CFlightModeObserver;
00202 
00203  public:
00204   ~CFlightModeObserver();
00205 
00206  private: // MGetterObs_FlightMode
00207   virtual void GotData_FlightMode(TInt aError);
00208  private: // MNotifyObs_FlightMode
00209   virtual void ChangedData_FlightMode(TInt aError);
00210  private:
00211   void HandleFlightMode(TInt aError, CTelephony::TFlightModeV1 const & aData);
00212 
00213  private:
00214   CGetterAo_FlightMode* iGetter;
00215   CNotifyAo_FlightMode* iNotifier;
00216 
00217  private:
00218   MGetterObs_FlightMode& iObserver;
00219 };
00220 
00221 CTOR_IMPL_CFlightModeObserver;
00222 
00223 void CFlightModeObserver::ConstructL(CTelephony& tel, MGetterObs_FlightMode& obs)
00224 {
00225   iGetter = new (ELeave) CGetterAo_FlightMode(tel, *this);
00226   iNotifier = new (ELeave) CNotifyAo_FlightMode(tel, *this);
00227 
00228   iGetter->MakeRequest();
00229 }
00230 
00231 CFlightModeObserver::~CFlightModeObserver()
00232 {
00233   delete iGetter;
00234   delete iNotifier;
00235 }
00236 
00237 void CFlightModeObserver::GotData_FlightMode(TInt aError)
00238 {
00239   HandleFlightMode(aError, iGetter->Data());
00240   iObserver.GotData_FlightMode(aError); // forward
00241 }
00242 
00243 void CFlightModeObserver::ChangedData_FlightMode(TInt aError)
00244 {
00245   HandleFlightMode(aError, iNotifier->Data());
00246 }
00247 
00248 static gboolean TFlightModeV1ToBoolean(const CTelephony::TFlightModeV1& data)
00249 {
00250   if (data.iFlightModeStatus == CTelephony::EFlightModeOn)
00251     return ETrue;
00252   else if (data.iFlightModeStatus == CTelephony::EFlightModeOff)
00253     return EFalse;
00254   else
00255     assert(0 && "unexpected TFlightModeStatus value");
00256   return EFalse;
00257 }
00258 
00259 void CFlightModeObserver::HandleFlightMode(TInt aError, 
00260              CTelephony::TFlightModeV1 const & aData)
00261 {
00262   if (aError) {
00263     // This is unexpected. No matter the network state, surely we
00264     // should at least be able to determine whether the network is
00265     // unavailable.
00266     er_log_symbian(er_FATAL, aError, "flightmode info status query failure");
00267   } else {
00268     gboolean on = TFlightModeV1ToBoolean(aData);
00269 
00270     logg("flightmode: %s", boolstr_on(on));
00271 
00272 #if __FLIGHTMODE_ENABLED__
00273     LogDb* logDb = ac_global_LogDb;
00274     if (logDb) {
00275       log_db_log_flightmode(logDb, on, NULL);
00276     }
00277 #endif
00278 
00279     // Post to blackboard if changed (compare against blackboard).
00280     {
00281       bb_Blackboard* bb = ac_global_Blackboard;
00282       bb_Board* bd = bb_Blackboard_board(bb);
00283       if (bd->flightmode != on) {
00284   bd->flightmode = on;
00285   bb_Blackboard_notify(bb, bb_dt_flightmode,
00286            (gpointer)&(bd->flightmode), 0);
00287       }
00288     }
00289 
00290     iNotifier->MakeRequest();
00291   }
00292 }
00293 
00294 // --------------------------------------------------
00295 // plat app context implementation
00296 // --------------------------------------------------
00297 
00298 /***koog 
00299 (require codegen/symbian-cxx)
00300 (ctor-defines/spec
00301  "CAppContextImpl" ;; name
00302  "ac_AppContext* ac, MAppContextInitObserver& obs" ;; args
00303  "iCtx(ac), iObs(obs)" ;; inits
00304  "" ;; ctor
00305  #t ;; ConstructL
00306 )
00307  ***/
00308 #define CTOR_DECL_CAppContextImpl  \
00309 public: static CAppContextImpl* NewLC(ac_AppContext* ac, MAppContextInitObserver& obs); \
00310 public: static CAppContextImpl* NewL(ac_AppContext* ac, MAppContextInitObserver& obs); \
00311 private: CAppContextImpl(ac_AppContext* ac, MAppContextInitObserver& obs); \
00312 private: void ConstructL();
00313 
00314 #define CTOR_IMPL_CAppContextImpl  \
00315 CAppContextImpl* CAppContextImpl::NewLC(ac_AppContext* ac, MAppContextInitObserver& obs) \
00316 { \
00317   CAppContextImpl* obj = new (ELeave) CAppContextImpl(ac, obs); \
00318   CleanupStack::PushL(obj); \
00319   obj->ConstructL(); \
00320   return obj; \
00321 } \
00322  \
00323 CAppContextImpl* CAppContextImpl::NewL(ac_AppContext* ac, MAppContextInitObserver& obs) \
00324 { \
00325   CAppContextImpl* obj = CAppContextImpl::NewLC(ac, obs); \
00326   CleanupStack::Pop(obj); \
00327   return obj; \
00328 } \
00329  \
00330 CAppContextImpl::CAppContextImpl(ac_AppContext* ac, MAppContextInitObserver& obs) : iCtx(ac), iObs(obs) \
00331 {}
00332 /***end***/
00333 
00334 NONSHARABLE_CLASS(CAppContextImpl) : 
00335   public CBase,
00336   public MGetterObs_BatteryInfo,
00337   public MGetterObs_FlightMode
00338 {
00339   CTOR_DECL_CAppContextImpl;
00340 
00341  public:
00342   ~CAppContextImpl();
00343 
00344  public:
00345   ac_AppContext* iCtx;
00346 
00347   // The observer is notified of the completion of any asynchronous
00348   // initialization.
00349   MAppContextInitObserver& iObs;
00350 
00351  public: // internally public
00352   DEF_SESSION(RFs, iFs);
00353 
00354   CTelephony* iTelephony;
00355 
00356 #if __NEED_CONTACT_DATABASE__
00357   CContactDatabase* iContactDatabase;
00358 #endif
00359 
00360   TPlatformVersion iPlatformVersion;
00361 
00362  private:
00363   CBatteryObserver* iBatteryObserver;
00364   CFlightModeObserver* iFlightModeObserver;
00365 
00366  private: // MGetterObs_BatteryInfo
00367   virtual void GotData_BatteryInfo(TInt aError);
00368  private: // MGetterObs_FlightMode
00369   virtual void GotData_FlightMode(TInt aError);
00370 
00371  private:
00372   TBool iHaveBattery;
00373   TBool iHaveFlightMode;
00374   void GotMoreInfo();
00375 };
00376 
00377 CTOR_IMPL_CAppContextImpl;
00378 
00379 void CAppContextImpl::GotMoreInfo()
00380 {
00381   if (iHaveBattery && iHaveFlightMode) {
00382     // We need no bookkeeping for as long as we are only waiting for
00383     // this one reading before we are ready.
00384     iObs.AppContextReady(0);
00385   }
00386 }
00387 
00388 void CAppContextImpl::GotData_BatteryInfo(TInt aError)
00389 {
00390   (void)aError; // do not care
00391   iHaveBattery = ETrue;
00392   GotMoreInfo();
00393 }
00394 
00395 void CAppContextImpl::GotData_FlightMode(TInt aError)
00396 {
00397   (void)aError; // no error, would have exited
00398   iHaveFlightMode = ETrue;
00399   GotMoreInfo();
00400 }
00401 
00402 void CAppContextImpl::ConstructL()
00403 {
00404   iTelephony = CTelephony::NewL();
00405 
00406   iBatteryObserver = CBatteryObserver::NewL(*iTelephony, *this);
00407 
00408   iFlightModeObserver = CFlightModeObserver::NewL(*iTelephony, *this);
00409 
00410   LEAVE_IF_ERROR_OR_SET_SESSION_OPEN(iFs, iFs.Connect());
00411 
00412   GetS60PlatformVersionL(iFs, iPlatformVersion);
00413 
00414 #if __NEED_CONTACT_DATABASE__
00415   iContactDatabase = CContactDatabase::OpenL();
00416 #endif
00417 }
00418 
00419 CAppContextImpl::~CAppContextImpl()
00420 {
00421   delete iFlightModeObserver;
00422   delete iBatteryObserver;
00423 #if __NEED_CONTACT_DATABASE__
00424   delete iContactDatabase;
00425 #endif
00426   delete iTelephony;
00427   SESSION_CLOSE_IF_OPEN(iFs);
00428 }
00429 
00430 // --------------------------------------------------
00431 // interface
00432 // --------------------------------------------------
00433 
00434 CAppContext* CAppContext::NewL(ac_AppContext* ac,
00435              MAppContextInitObserver& obs)
00436 {
00437   CAppContextImpl* impl = CAppContextImpl::NewL(ac, obs);
00438   CleanupStack::PushL(impl);
00439   CAppContext* obj = new (ELeave) CAppContext;
00440   obj->iImpl = impl;
00441   CleanupStack::Pop();
00442   return obj;
00443 }
00444 
00445 CAppContext::~CAppContext()
00446 {
00447   delete iImpl;
00448 }
00449 
00450 /**
00451 
00452 Copyright 2010 Helsinki Institute for Information Technology (HIIT)
00453 and the authors. All rights reserved.
00454 
00455 Authors: Tero Hasu <tero.hasu@hut.fi>
00456 
00457 Permission is hereby granted, free of charge, to any person
00458 obtaining a copy of this software and associated documentation files
00459 (the "Software"), to deal in the Software without restriction,
00460 including without limitation the rights to use, copy, modify, merge,
00461 publish, distribute, sublicense, and/or sell copies of the Software,
00462 and to permit persons to whom the Software is furnished to do so,
00463 subject to the following conditions:
00464 
00465 The above copyright notice and this permission notice shall be
00466 included in all copies or substantial portions of the Software.
00467 
00468 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00469 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00470 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00471 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00472 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00473 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00474 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00475 SOFTWARE.
00476 
00477  **/

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:51 2011 by Doxygen 1.6.1