sa_array.cpp

Go to the documentation of this file.
00001 #include "sa_array_private.h"
00002 
00003 #include "cf_query.h"
00004 #include "kr_controller_private.h" // for runtime config queries
00005 #include "ld_logging.h" // for error handling routines
00006 
00007 #include "common/assertions.h"
00008 #include "common/error_list.h"
00009 #include "common/logging.h"
00010 #include "common/platform_error.h"
00011 #include "common/utilities.h"
00012 
00013 #ifdef __EPOC32__
00014 #include <e32std.h>
00015 #endif
00016 
00017 #include <string.h>
00018 
00019 #define SA_ARRAY_INTEGRATION 1
00020 
00021 #define sa_set_symbian_error(errCode,msg) \
00022     if (error) \
00023       *error = ((errCode == KErrNoMemory) ? gx_error_no_memory : gx_error_new(domain_symbian, errCode, msg ": %s (%d)", plat_error_strerror(errCode), errCode));
00024 
00025 #define sa_trap_symbian_sensor_start(object,msg) {  \
00026   success = TRUE;         \
00027   TRAPD(_errCode, (object)->StartL());        \
00028   if (_errCode) { sa_set_symbian_error(_errCode, msg); success = FALSE; } \
00029 }
00030 
00031 #define sa_typical_symbian_sensor_start(object,msg) { \
00032   success = TRUE; \
00033   TRAPD(_errCode, success = (object)->StartL(error));          \
00034   if (_errCode) { sa_set_symbian_error(_errCode, msg); success = FALSE; } \
00035 }
00036 
00037 #define sa_typical_symbian_sensor_create(expr,msg) { \
00038   TRAPD(_errCode, expr); \
00039   if (_errCode) { sa_set_symbian_error(_errCode, msg); success = FALSE; } \
00040   else { success = TRUE; }                \
00041 }
00042 
00043 #define sa_typical_symbian_sensor_reconfigure(sn) {     \
00044     (self->iSensor_##sn)->Reconfigure(key, value);      \
00045     success = TRUE;             \
00046 }
00047 
00048 #define sa_set_qt_error(ex, msg)          \
00049 {                 \
00050   if (error)                \
00051     *error = gx_error_new(domain_qt, -1, "Qt error: %s", ex.what());  \
00052 }
00053 
00054 #define sa_typical_qt_sensor_create(expr, msg)  \
00055 {           \
00056   try {           \
00057     expr ;          \
00058     success = TRUE;       \
00059   } catch (const std::exception &_ex) {   \
00060     sa_set_qt_error(_ex, msg);      \
00061     success = FALSE;        \
00062   }           \
00063 }
00064     
00065 #define sa_reconfigure_ignore_all_keys { success = TRUE; }
00066 
00067 /* Sensor implementation includes.
00068    There may be variant implementations for different builds.
00069  */
00070 #if __APPFOCUS_ENABLED__
00071 #include "epoc-appfocus.hpp"
00072 #endif
00073 #if __BTPROX_ENABLED__
00074 #include "epoc-btprox.hpp"
00075 #endif
00076 #if __INACTIVITY_ENABLED__
00077 #include "epoc-inactivity.hpp"
00078 #endif
00079 #if __INDICATOR_ENABLED__
00080 #include "epoc-indicator.hpp"
00081 #endif
00082 #if __KEYPRESS_ENABLED__
00083 #if __HAVE_ANIM__
00084 #include "epoc-keypress-anim.hpp"
00085 #else
00086 #include "epoc-keypress.hpp"
00087 #endif
00088 #endif // __KEYPRESS_ENABLED__
00089 #if __PROFILE_ENABLED__
00090 #if __HAVE_PROFILEENGINE_LIB__
00091 #include "epoc-profile-31.hpp"
00092 #else
00093 #include "epoc-profile.hpp"
00094 #endif
00095 #endif // __PROFILE_ENABLED__
00096 #if __TIMER_ENABLED__
00097 #include "sa_sensor_timer.h"
00098 #endif
00099 #if __MARK_ENABLED__
00100 #include "sa_sensor_mark.h"
00101 #endif
00102 
00103 #include "epoc-callstatus.hpp"
00104 #include "epoc-cellid.hpp"
00105 #include "epoc-cellpos.hpp"
00106 #include "epoc-gps.hpp"
00107 #include "epoc-httpurl.hpp"
00108 #include "epoc-music.hpp"
00109 #include "epoc-smsevent.hpp"
00110 #include "epoc-weburl.hpp"
00111 
00112 #include "sa_sensor_light_api.h"
00113 #include "sa_sensor_proximity_api.h"
00114 #include "sa_sensor_tap_api.h"
00115 
00116 // This file is generated, and included only once here. Code for
00117 // creating, destroying, starting, and stopping sensors comes from
00118 // here. The code is designed to mesh well with this file.
00119 // "sa_sensor_list_integration.h" may be #included elsewhere as well.
00120 #include "sa_sensor_list_integration.cpp"
00121 
00122 extern "C" struct _sa_Array
00123 {
00124   ac_AppContext* ac; // not owned
00125   LogDb* logDb; // not owned
00126 
00127 #if __APPFOCUS_ENABLED__
00128   CSensor_appfocus *iSensor_appfocus;
00129 #endif
00130 #if __BTPROX_ENABLED__
00131   CSensor_btprox *iSensor_btprox;
00132 #endif
00133 #if __INACTIVITY_ENABLED__
00134   CSensor_inactivity *iSensor_inactivity;
00135 #endif
00136 #if __INDICATOR_ENABLED__
00137   CSensor_indicator *iSensor_indicator;
00138 #endif
00139 #if __KEYPRESS_ENABLED__
00140   CSensor_keypress *iSensor_keypress;
00141 #endif
00142 #if __PROFILE_ENABLED__
00143   CSensor_profile *iSensor_profile;
00144 #endif
00145 #if __TIMER_ENABLED__
00146   sa_Sensor_timer* iSensor_timer;
00147 #endif
00148 #if __MARK_ENABLED__
00149   sa_Sensor_mark* iSensor_mark;
00150 #endif
00151   DECLARE_SENSOR_callstatus;
00152   DECLARE_SENSOR_cellid;
00153   DECLARE_SENSOR_cellpos;
00154   DECLARE_SENSOR_doubletap;
00155   DECLARE_SENSOR_gps;
00156   DECLARE_SENSOR_httpurl;
00157   DECLARE_SENSOR_light;
00158   DECLARE_SENSOR_music;
00159   DECLARE_SENSOR_proximity;
00160   DECLARE_SENSOR_singletap;
00161   DECLARE_SENSOR_smsevent;
00162   DECLARE_SENSOR_weburl;
00163 };
00164 
00165 /* Sensor starting. (Statement.)
00166    Must set "success" (gboolean) and "error" (GError**) to indicate what happened.
00167  */
00168 #define SENSOR_APPFOCUS_START sa_typical_symbian_sensor_start(self->iSensor_appfocus, "failed to start appfocus scanning")
00169 #define SENSOR_BTPROX_START sa_typical_symbian_sensor_start(self->iSensor_btprox, "failed to start btprox scanning")
00170 #define SENSOR_INACTIVITY_START sa_typical_symbian_sensor_start(self->iSensor_inactivity, "failed to start inactivity scanning")
00171 #define SENSOR_INDICATOR_START sa_typical_symbian_sensor_start(self->iSensor_indicator, "failed to start indicator scanning")
00172 #define SENSOR_KEYPRESS_START sa_typical_symbian_sensor_start(self->iSensor_keypress, "failed to start keypress scanning")
00173 #define SENSOR_PROFILE_START sa_typical_symbian_sensor_start(self->iSensor_profile, "failed to start profile scanning")
00174 #define SENSOR_TIMER_START { success = sa_Sensor_timer_start(self->iSensor_timer, error); }
00175 #define SENSOR_MARK_START { success = sa_Sensor_mark_start(self->iSensor_mark, error); }
00176 
00177 /* Sensor stopping. (Statement.) */
00178 #define SENSOR_APPFOCUS_STOP { self->iSensor_appfocus->Stop(); }
00179 #define SENSOR_BTPROX_STOP { self->iSensor_btprox->Stop(); }
00180 #define SENSOR_INACTIVITY_STOP { self->iSensor_inactivity->Stop(); }
00181 #define SENSOR_INDICATOR_STOP { self->iSensor_indicator->Stop(); }
00182 #define SENSOR_KEYPRESS_STOP { self->iSensor_keypress->Stop(); }
00183 #define SENSOR_PROFILE_STOP { self->iSensor_profile->Stop(); }
00184 #define SENSOR_TIMER_STOP { sa_Sensor_timer_stop(self->iSensor_timer); }
00185 #define SENSOR_MARK_STOP { sa_Sensor_mark_stop(self->iSensor_mark); }
00186 
00187 /* Sensor running querying. (Boolean expression.) */
00188 #define SENSOR_APPFOCUS_IS_RUNNING (self->iSensor_appfocus->IsActive())
00189 #define SENSOR_BTPROX_IS_RUNNING (self->iSensor_btprox->IsActive())
00190 #define SENSOR_INACTIVITY_IS_RUNNING (self->iSensor_inactivity->IsActive())
00191 #define SENSOR_INDICATOR_IS_RUNNING (self->iSensor_indicator->IsActive())
00192 #define SENSOR_KEYPRESS_IS_RUNNING (self->iSensor_keypress->IsActive())
00193 #define SENSOR_PROFILE_IS_RUNNING (self->iSensor_profile->IsActive())
00194 #define SENSOR_TIMER_IS_RUNNING (sa_Sensor_timer_is_active(self->iSensor_timer))
00195 #define SENSOR_MARK_IS_RUNNING (sa_Sensor_mark_is_active(self->iSensor_mark))
00196 
00197 /* Sensor destruction. (Statement.) */
00198 #define SENSOR_APPFOCUS_DESTROY { delete self->iSensor_appfocus; self->iSensor_appfocus = NULL; }
00199 #define SENSOR_BTPROX_DESTROY { delete self->iSensor_btprox; self->iSensor_btprox = NULL; }
00200 #define SENSOR_INACTIVITY_DESTROY { delete self->iSensor_inactivity; self->iSensor_inactivity = NULL; }
00201 #define SENSOR_INDICATOR_DESTROY { delete self->iSensor_indicator; self->iSensor_indicator = NULL; }
00202 #define SENSOR_KEYPRESS_DESTROY { delete self->iSensor_keypress; self->iSensor_keypress = NULL; }
00203 #define SENSOR_PROFILE_DESTROY { delete self->iSensor_profile; self->iSensor_profile = NULL; }
00204 #define SENSOR_TIMER_DESTROY { sa_Sensor_timer_destroy(self->iSensor_timer); }
00205 #define SENSOR_MARK_DESTROY { sa_Sensor_mark_destroy(self->iSensor_mark); }
00206 
00207 /* Sensor creation. (Statement.) 
00208    Must set "success" (gboolean) and "error" (GError**) to indicate what happened.
00209 */
00210 #define SENSOR_PROFILE_CREATE sa_typical_symbian_sensor_create(self->iSensor_profile = CSensor_profile::NewL(self->logDb), "profile sensor initialization")
00211 #define SENSOR_BTPROX_CREATE sa_typical_symbian_sensor_create(self->iSensor_btprox = CSensor_btprox::NewL(self->logDb), "btprox sensor initialization")
00212 #define SENSOR_INACTIVITY_CREATE sa_typical_symbian_sensor_create(self->iSensor_inactivity = CSensor_inactivity::NewL(self->ac), "inactivity sensor initialization")
00213 #define SENSOR_INDICATOR_CREATE sa_typical_symbian_sensor_create(self->iSensor_indicator = CSensor_indicator::NewL(self->ac), "indicator sensor initialization")
00214 #define SENSOR_APPFOCUS_CREATE sa_typical_symbian_sensor_create(self->iSensor_appfocus = CSensor_appfocus::NewL(self->logDb), "appfocus sensor initialization")
00215 #define SENSOR_KEYPRESS_CREATE sa_typical_symbian_sensor_create(self->iSensor_keypress = CSensor_keypress::NewL(self->logDb), "keypress sensor initialization")
00216 #define SENSOR_TIMER_CREATE { self->iSensor_timer = sa_Sensor_timer_new(self->logDb, error); success = (self->iSensor_timer != NULL); }
00217 #define SENSOR_MARK_CREATE { self->iSensor_mark = sa_Sensor_mark_new(self->logDb, error); success = (self->iSensor_mark != NULL); }
00218 
00219 #define reconfigure_not_supported_by_component(key) { \
00220     if (error) \
00221       *error = gx_error_new(domain_cl2app, code_not_supported, "configuration key '%s' not supported by concerned component", key); \
00222     success = FALSE; \
00223   }
00224 
00225 /* Sensor reconfiguring. (Statement.) */
00226 #define SENSOR_APPFOCUS_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00227 #define SENSOR_BTPROX_RECONFIGURE(key,value) sa_typical_symbian_sensor_reconfigure(btprox)
00228 #define SENSOR_INACTIVITY_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00229 #define SENSOR_INDICATOR_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00230 #define SENSOR_KEYPRESS_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00231 #define SENSOR_PROFILE_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00232 #define SENSOR_TIMER_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00233 #define SENSOR_MARK_RECONFIGURE(key,value) sa_reconfigure_ignore_all_keys
00234 
00235 // Defined for sa_sensor_list_integration.h.
00236 // We only consider OOM errors as fatal.
00237 #define handle_any_sensor_start_failure {   \
00238     if ((!success) && error) {        \
00239       if (*error == gx_error_no_memory)     \
00240   gx_dblog_fatal_error_clear(self->logDb, error); \
00241       else            \
00242   gx_dblog_error_clear(self->logDb, error); \
00243     }             \
00244   }
00245 
00246 static gboolean sensor_autostart_is_allowed(const gchar* cfg_key)
00247 {
00248   gboolean dvalue = TRUE; // default value
00249 #if __GPS_ENABLED__ && !__IS_DEMO__
00250   // GPS autostart can cause problems due to phones without integrated
00251   // GPS looking for an external GPS device via Bluetooth, so we do
00252   // not generally have this on by default.
00253   if (strcmp(cfg_key, "sensor.gps.autostart") == 0)
00254     dvalue = FALSE;
00255 #endif
00256   return force_get_ConfigDb_bool(cfg_key, dvalue);
00257 }
00258 
00259 #define SENSOR_AUTOSTART_IS_ALLOWED(_name) \
00260   sensor_autostart_is_allowed("sensor." #_name ".autostart")
00261 
00262 /** Instantiates a sensor array consisting of all supported sensors. */
00263 extern "C" sa_Array *sa_Array_new(ac_AppContext* ac,
00264           GError** error)
00265 {
00266   sa_Array* self = g_try_new0(sa_Array, 1);
00267   if (G_UNLIKELY(!self)) {
00268     if (error) *error = gx_error_no_memory; // out of memory
00269     return NULL;
00270   }
00271 
00272   self->ac = ac;
00273   self->logDb = ac_LogDb(ac);
00274 
00275   gboolean success; // for the macro
00276 
00277   // We indeed require that it be possible to instantiate every single
00278   // sensor that is supported. Starting them up is another matter.
00279   CREATE_ALL_SENSORS_OR_FAIL;
00280 
00281   return self;
00282 
00283  fail:
00284   logt("some sensor failed to initialize");
00285   sa_Array_destroy(self);
00286   return NULL;
00287 }
00288   
00289 /** Starts all supported sensors. */
00290 extern "C" void sa_Array_start(sa_Array* self)
00291 {
00292   gboolean success = TRUE;
00293   GError* localError = NULL;
00294   GError** error = &localError;
00295 
00296   // Errors will be logged and cleared.
00297   TRY_START_ALL_SUPPORTED_SENSORS;
00298 }
00299   
00300 /** Stops all supported sensors. */
00301 extern "C" void sa_Array_stop(sa_Array* self)
00302 {
00303   STOP_ALL_SUPPORTED_SENSORS;
00304 }
00305   
00306 /** Destroys a sensor array. Naturally all the sensors in it are stopped. */
00307 extern "C" void sa_Array_destroy(sa_Array* self)
00308 {
00309   if (self) {
00310     // We assume that destroying a sensor also stops it, as we are not
00311     // requesting stopping separately. In fact here we cannot even
00312     // assume all of the sensors objects have been created.
00313     DESTROY_ALL_SENSORS;
00314     logt("all sensors destroyed");
00315     g_free(self);
00316     logt("sensor array object freed");
00317   }
00318 }
00319   
00320 /** Returns FALSE for unknown names. */
00321 extern "C" gboolean sa_sensor_is_supported(const gchar* name)
00322 {
00323   RETURN_WHETHER_NAMED_SENSOR_IS_SUPPORTED(name);
00324   return FALSE;
00325 }
00326 
00327 extern "C" gboolean sa_Array_sensor_is_running(sa_Array* self, const gchar* name)
00328 {
00329   // This macro requires that you implement the macro
00330   // SENSOR_<NAME>_IS_RUNNING for each supported sensor.
00331   // SENSOR_<NAME>_IS_RUNNING need not check whether the sensor is
00332   // supported; non-supported sensors are not running.
00333   RETURN_WHETHER_NAMED_SENSOR_IS_RUNNING(name);
00334   return FALSE;
00335 }
00336 
00337 extern "C" void sa_Array_sensor_stop(sa_Array* self, const gchar* name)
00338 {
00339   // This macro requires that you implement the macro
00340   // SENSOR_<NAME>_STOP for each supported sensor. SENSOR_<NAME>_STOP
00341   // need not check whether the sensor is supported or running.
00342   STOP_NAMED_SENSOR(name);
00343 }
00344 
00345 // We try to have decent error reporting here, with interactive starting attempts in mind.
00346 extern "C" gboolean sa_Array_sensor_start(sa_Array* self, const gchar* name, GError** error)
00347 {
00348   // This macro requires that you implement the macro
00349   // SENSOR_<NAME>_START for each supported sensor. SENSOR_<NAME>_START
00350   // need not check whether the sensor is supported or running.
00351   gboolean success;
00352   START_NAMED_SENSOR_OR_FAIL(name);
00353 
00354   if (error)
00355     *error = gx_error_new(domain_cl2app, code_not_supported, "sensor '%s' not supported", name);
00356   return FALSE;
00357 }
00358 
00359 extern "C" gboolean sa_Array_reconfigure(sa_Array* self, const gchar* key, const gchar* value, GError** error)
00360 {
00361   (void)self;
00362   (void)value;
00363   (void)error;
00364 
00365   {
00366     gboolean success;
00367     // This macro returns if it finds a match.
00368     RECONFIGURE_MATCHING_SENSOR(key, value);
00369   }
00370 
00371   /*
00372   if (error)
00373     *error = gx_error_new(domain_cl2app, code_not_supported, "configuration key '%s' does not concern any supported component", key);
00374   return FALSE;
00375   */
00376 
00377   // We shall not complain about unsupported keys. It is possible that
00378   // some sensor is not compiled in, or not yet supported, or
00379   // whatever; why should the user not be able to add a config entry
00380   // for it anyway. If the entry need not be propagated at this time,
00381   // then the propagation surely does not fail.
00382   return TRUE;
00383 }
00384 
00385 /**
00386 
00387 sa_array.cpp
00388 
00389 Copyright 2009 Helsinki Institute for Information Technology (HIIT)
00390 and the authors. All rights reserved.
00391 
00392 Authors: Tero Hasu <tero.hasu@hut.fi>
00393 
00394 Permission is hereby granted, free of charge, to any person
00395 obtaining a copy of this software and associated documentation files
00396 (the "Software"), to deal in the Software without restriction,
00397 including without limitation the rights to use, copy, modify, merge,
00398 publish, distribute, sublicense, and/or sell copies of the Software,
00399 and to permit persons to whom the Software is furnished to do so,
00400 subject to the following conditions:
00401 
00402 The above copyright notice and this permission notice shall be
00403 included in all copies or substantial portions of the Software.
00404 
00405 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00406 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00407 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00408 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00409 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00410 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00411 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00412 SOFTWARE.
00413 
00414  **/

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