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