[SystemInfo] Fix for systemInfo CameraFlash
[platform/core/api/webapi-plugins.git] / src / systeminfo / systeminfo-utils.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "systeminfo-utils.h"
18 #include "systeminfo/systeminfo_instance.h"
19
20 #include <fstream>
21 #include <sstream>
22 #include <memory>
23 #include <mutex>
24
25 #include <system_settings.h>
26 #include <system_info.h>
27 #include <sys/statfs.h>
28
29 #include <vconf.h>
30 #include <vconf-internal-keys.h>
31 #include <net_connection.h>
32 #include <tapi_common.h>
33 #include <ITapiModem.h>
34 #include <ITapiSim.h>
35 #include <device.h>
36 #include <device/callback.h>
37 #include <device/device-error.h>
38 #include <sensor_internal.h>
39 #include <wifi.h>
40
41 #include "common/logger.h"
42 #include "common/platform_exception.h"
43 #include "common/dbus_operation.h"
44 #include "common/scope_exit.h"
45
46 // TODO:: hardcoded value, only for IsBluetoothAlwaysOn
47 #define PROFILE_MOBILE 1
48
49 namespace extension {
50 namespace systeminfo {
51
52 namespace {
53
54 const std::string MEMORY_STATE_NORMAL = "NORMAL";
55 const std::string MEMORY_STATE_WARNING = "WARNING";
56 const int MEMORY_TO_BYTE = 1024;
57 const int BASE_GATHERING_INTERVAL = 100;
58 const double DISPLAY_INCH_TO_MILLIMETER = 2.54;
59
60 const int kTapiMaxHandle = 2;
61 const int kDefaultPropertyCount = 1;
62
63 }  // namespace
64
65 using namespace common;
66
67 //Callback functions declarations
68 static void OnBatteryChangedCb(keynode_t* node, void* event_ptr);
69 static gboolean OnCpuChangedCb(gpointer event_ptr);
70 static gboolean OnStorageChangedCb(gpointer event_ptr);
71 static void OnMmcChangedCb(keynode_t* node, void* event_ptr);
72 static void OnDisplayChangedCb(keynode_t* node, void* event_ptr);
73 static void OnDeviceAutoRotationChangedCb(keynode_t* node, void* event_ptr);
74 static void OnDeviceOrientationChangedCb(sensor_t sensor, unsigned int event_type,
75                                          sensor_data_t *data, void *user_data);
76 static void OnLocaleChangedCb(system_settings_key_e key, void* event_ptr);
77 static void OnNetworkChangedCb(connection_type_e type, void* event_ptr);
78 static void OnNetworkValueChangedCb(const char* ipv4_address,
79                                     const char* ipv6_address, void* event_ptr);
80 static void OnCellularNetworkValueChangedCb(keynode_t *node, void *event_ptr);
81 static void OnPeripheralChangedCb(keynode_t* node, void* event_ptr);
82 static void OnMemoryChangedCb(keynode_t* node, void* event_ptr);
83 static void OnBrightnessChangedCb(device_callback_e type, void *value, void *user_data);
84 static void OnWifiLevelChangedCb (wifi_rssi_level_e rssi_level, void *user_data);
85
86 static void SimCphsValueCallback(TapiHandle *handle, int result, void *data, void *user_data);
87 static void SimMsisdnValueCallback(TapiHandle *handle, int result, void *data, void *user_data);
88 static void SimSpnValueCallback(TapiHandle *handle, int result, void *data, void *user_data);
89
90 namespace {
91 // device profile
92 const char* kPlatformFull = "mobile-full";
93 const char* kPlatformMobile = "mobile-web";
94 const char* kPlatformWearable = "wearable";
95
96 const char* kProfileFull = "MOBILE_FULL";
97 const char* kProfileMobile = "MOBILE_WEB";
98 const char* kProfileWearable = "WEARABLE";
99 //opengles
100 const char* kOpenglesTextureDelimiter = "/";
101 const char* kOpenglesTextureUtc = "utc";
102 const char* kOpenglesTexturePtc = "ptc";
103 const char* kOpenglesTextureEtc = "etc";
104 const char* kOpenglesTexture3dc = "3dc";
105 const char* kOpenglesTextureAtc = "atc";
106 const char* kOpenglesTexturePvrtc = "pvrtc";
107 //core cpu arch
108 const char* kPlatformCoreDelimiter = " | ";
109 const char* kPlatformCoreArmv6 = "armv6";
110 const char* kPlatformCoreArmv7 = "armv7";
111 const char* kPlatformCoreX86 = "x86";
112 //core fpu arch
113 const char* kPlatformCoreSse2 = "sse2";
114 const char* kPlatformCoreSse3 = "sse3";
115 const char* kPlatformCoreSsse3 = "ssse3";
116 const char* kPlatformCoreVfpv2 = "vfpv2";
117 const char* kPlatformCoreVfpv3 = "vfpv3";
118 const std::string kPropertyIdCpu = "CPU";
119 //Battery
120 const double kRemainingBatteryChargeMax = 100.0;
121 const int kVconfErrorNone = 0;
122 //Display
123 const double kDisplayBrightnessDivideValue = 100;
124 //Device Orientation
125 const std::string kOrientationPortraitPrimary = "PORTRAIT_PRIMARY";
126 const std::string kOrientationPortraitSecondary = "PORTRAIT_SECONDARY";
127 const std::string kOrientationLandscapePrimary = "LANDSCAPE_PRIMARY";
128 const std::string kOrientationLandscapeSecondary = "LANDSCAPE_SECONDARY";
129 //Peripheral
130 const std::string kVideoOutputString = "isVideoOutputOn";
131 //Storage
132 const char* kStorageInternalPath = "/opt/usr/media";
133 const char* kStorageSdcardPath = "/opt/storage/sdcard";
134 const std::string kPropertyIdStorage = "STORAGE";
135 const std::string kTypeUnknown = "UNKNOWN";
136 const std::string kTypeInternal = "INTERNAL";
137 const std::string kTypeUsbHost = "USB_HOST";
138 const std::string kTypeMmc = "MMC";
139 const double kPropertyWatcherTime = 1;
140 //Network
141 enum NetworkType {
142   kNone,
143   kType2G,
144   kType2_5G,
145   kType3G,
146   kType4G,
147   kWifi,
148   kEthernet,
149   kUnknown
150 };
151
152 const char* kNetworkTypeNone = "NONE";
153 const char* kNetworkType2G = "2G";
154 const char* kNetworkType2_5G = "2.5G";
155 const char* kNetworkType3G = "3G";
156 const char* kNetworkType4G = "4G";
157 const char* kNetworkTypeWifi = "WIFI";
158 const char* kNetworkTypeEthernet = "ETHERNET";
159 const char* kNetworkTypeUnknown = "UNKNOWN";
160 //Wifi Network
161 const std::string kWifiStatusOn = "ON";
162 const std::string kWifiStatusOff = "OFF";
163 const int kWifiSignalStrengthDivideValue = 100;
164 //Cellular Network
165 const unsigned short kMccDivider = 100;
166 const char* kConnectionOff = "OFF";
167 const char* kConnectionOn = "ON";
168 //Sim
169 const char* kSimStatusAbsent = "ABSENT";
170 const char* kSimStatusInitializing = "INITIALIZING";
171 const char* kSimStatusReady = "READY";
172 const char* kSimStatusPinRequired = "PIN_REQUIRED";
173 const char* kSimStatusPukRequired = "PUK_REQUIRED";
174 const char* kSimStatusSimLocked = "SIM_LOCKED";
175 const char* kSimStatusNetworkLocked = "NETWORK_LOCKED";
176 const char* kSimStatusUnknown = "UNKNOWN";
177
178 ///*for getCapability*/
179 /*API feature*/
180 /*Network feature*/
181 const char* kTizenFeatureBluetoothAlwaysOn = "http://tizen.org/capability/network.bluetooth.always_on"; //TODO mobile/wearable: false, tv: true
182 const char* kTizenFeatureOpenglesTextureFormat = "http://tizen.org/feature/opengles.texture_format";
183 const char* kTizenFeatureCoreApiVersion = "http://tizen.org/feature/platform.core.api.version";
184 const char* kTizenFeaturePlatfromCoreCpuArch = "http://tizen.org/feature/platform.core.cpu.arch";
185 const char* kTizenFeaturePlatfromCoreFpuArch = "http://tizen.org/feature/platform.core.fpu.arch";
186 /*profile feature*/
187 const char* kTizenFeatureProfile = "http://tizen.org/feature/profile";
188 /*Screen feature*/
189 const char* kTizenFeatureScreen = "http://tizen.org/feature/screen";
190 /*Sensor feature*/
191 const char* kTizenFeatureCpuFrequency = "http://tizen.org/feature/platform.core.cpu.frequency";
192 /*platform*/
193 const char* kTizenFeaturePlatformNativeApiVersion = "tizen.org/feature/platform.native.api.version";
194 const char* kTizenFeaturePlatformNativeOspCompatible = "tizen.org/feature/platform.native.osp_compatible";
195 const char* kTizenFeaturePlatformVersionName = "http://tizen.org/feature/platform.version.name";
196
197 static std::string parseWifiNetworkError(int error) {
198   switch (error) {
199     case WIFI_ERROR_NONE : return "WIFI_ERROR_NONE";
200     case WIFI_ERROR_INVALID_PARAMETER : return "WIFI_ERROR_INVALID_PARAMETER";
201     case WIFI_ERROR_OUT_OF_MEMORY : return "WIFI_ERROR_OUT_OF_MEMORY";
202     case WIFI_ERROR_INVALID_OPERATION : return "WIFI_ERROR_INVALID_OPERATION";
203     case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED : return "WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED";
204     case WIFI_ERROR_OPERATION_FAILED : return "WIFI_ERROR_OPERATION_FAILED";
205     case WIFI_ERROR_NO_CONNECTION : return "WIFI_ERROR_NO_CONNECTION";
206     case WIFI_ERROR_NOW_IN_PROGRESS : return "WIFI_ERROR_NOW_IN_PROGRESS";
207     case WIFI_ERROR_ALREADY_EXISTS : return "WIFI_ERROR_ALREADY_EXISTS";
208     case WIFI_ERROR_OPERATION_ABORTED : return "WIFI_ERROR_OPERATION_ABORTED";
209     case WIFI_ERROR_DHCP_FAILED : return "WIFI_ERROR_DHCP_FAILED";
210     case WIFI_ERROR_INVALID_KEY : return "WIFI_ERROR_INVALID_KEY";
211     case WIFI_ERROR_NO_REPLY : return "WIFI_ERROR_NO_REPLY";
212     case WIFI_ERROR_SECURITY_RESTRICTED : return "WIFI_ERROR_SECURITY_RESTRICTED";
213     case WIFI_ERROR_PERMISSION_DENIED : return "WIFI_ERROR_PERMISSION_DENIED";
214     case WIFI_ERROR_NOT_SUPPORTED : return "WIFI_ERROR_NOT_SUPPORTED";
215     default : return "Unknown Wi-Fi error";
216   }
217 }
218
219 }
220
221 /////////////////////////// SimDetailsManager ////////////////////////////////
222
223 class SimDetailsManager {
224  private:
225   unsigned short mcc_;
226   unsigned short mnc_;
227   std::string operator_name_;
228   std::string msin_;
229   std::string state_;
230   std::string msisdn_;
231   std::string iccid_;
232   std::string spn_;
233
234   picojson::object* sim_result_obj_;
235   unsigned short to_process_;
236   std::mutex sim_to_process_mutex_;
237   std::mutex sim_info_mutex_;
238   long sim_count_;
239
240   void ResetSimHolder(picojson::object* out);
241   void FetchSimState(TapiHandle *tapi_handle);
242   PlatformResult FetchSimSyncProps(TapiHandle *tapi_handle);
243   void ReturnSimToJS();
244
245  public:
246   SimDetailsManager();
247
248   PlatformResult GatherSimInformation(TapiHandle* handle, picojson::object* out);
249   long GetSimCount(TapiHandle **tapi_handle);
250   void TryReturn();
251
252   void set_operator_name(const std::string& name)
253   {
254     std::lock_guard<std::mutex> lock(sim_to_process_mutex_);
255     operator_name_ = name;
256     --to_process_;
257     LoggerD("Operator name: %s", operator_name_.c_str());
258   };
259   void set_msisdn(const std::string& msisdn)
260   {
261     std::lock_guard<std::mutex> lock(sim_to_process_mutex_);
262     this->msisdn_ = msisdn;
263     --to_process_;
264     LoggerD("MSISDN number: %s", this->msisdn_.c_str());
265   };
266   void set_spn(const std::string& spn)
267   {
268     std::lock_guard<std::mutex> lock(sim_to_process_mutex_);
269     this->spn_ = spn;
270     --to_process_;
271     LoggerD("SPN value: %s", this->spn_.c_str());
272   };
273 };
274
275 SimDetailsManager::SimDetailsManager():
276             mcc_(0),
277             mnc_(0),
278             operator_name_(""),
279             msin_(""),
280             state_(""),
281             msisdn_(""),
282             iccid_(""),
283             spn_(""),
284             sim_result_obj_(nullptr),
285             to_process_(0),
286             sim_count_(0)
287 {
288 }
289
290 PlatformResult SimDetailsManager::GatherSimInformation(TapiHandle* handle, picojson::object* out)
291 {
292   std::lock_guard<std::mutex> first_lock_sim(sim_info_mutex_);
293   ResetSimHolder(out);
294
295   FetchSimState(handle);
296   if (kSimStatusReady == state_) {
297     PlatformResult ret = FetchSimSyncProps(handle);
298     if (ret.IsError()) {
299       return ret;
300     }
301     {
302       //All props should be fetched synchronously, but sync function does not work
303       std::lock_guard<std::mutex> lock_to_process(sim_to_process_mutex_);
304       //would be deleted on } ending bracket
305       int result = tel_get_sim_cphs_netname(handle, SimCphsValueCallback, nullptr);
306       if (TAPI_API_SUCCESS == result) {
307         ++to_process_;
308       } else {
309         LoggerE("Failed getting cphs netname: %d", result);
310       }
311
312       result = tel_get_sim_msisdn(handle, SimMsisdnValueCallback, nullptr);
313       if (TAPI_API_SUCCESS == result) {
314         ++to_process_;
315       } else {
316         LoggerE("Failed getting msisdn: %d", result);
317       }
318
319       result = tel_get_sim_spn(handle, SimSpnValueCallback, nullptr);
320       if (TAPI_API_SUCCESS == result) {
321         ++to_process_;
322       } else {
323         LoggerE("Failed getting spn: %d", result);
324       }
325     }
326     //prevent returning not filled result
327     std::lock_guard<std::mutex> lock_sim(sim_info_mutex_);
328     //result will come from callbacks
329     return PlatformResult(ErrorCode::NO_ERROR);
330   }
331   //if sim state is not READY return default values and don't wait for callbacks
332   TryReturn();
333   return PlatformResult(ErrorCode::NO_ERROR);
334 }
335
336 void SimDetailsManager::FetchSimState(TapiHandle *tapi_handle)
337 {
338   LoggerD("Entered");
339   if (nullptr == tapi_handle) {
340     LoggerE("Tapi handle is null");
341     state_ = kSimStatusUnknown;
342   } else {
343     int card_changed = 0;
344     TelSimCardStatus_t sim_card_state;
345     int error = tel_get_sim_init_info(tapi_handle, &sim_card_state, &card_changed);
346     if (TAPI_API_SUCCESS == error) {
347       switch (sim_card_state) {
348         case TAPI_SIM_STATUS_CARD_NOT_PRESENT:
349         case TAPI_SIM_STATUS_CARD_REMOVED:
350           state_ = kSimStatusAbsent;
351           break;
352         case TAPI_SIM_STATUS_SIM_INITIALIZING:
353           state_ = kSimStatusInitializing;
354           break;
355         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:
356           state_ = kSimStatusReady;
357           break;
358         case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:
359           state_ = kSimStatusPinRequired;
360           break;
361         case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:
362           state_ = kSimStatusPukRequired;
363           break;
364         case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
365         case TAPI_SIM_STATUS_CARD_BLOCKED:
366           state_ = kSimStatusSimLocked;
367           break;
368         case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:
369         case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED:
370           state_ = kSimStatusNetworkLocked;
371           break;
372         default:
373           state_ = kSimStatusUnknown;
374           break;
375       }
376     }
377   }
378 }
379
380 PlatformResult SimDetailsManager::FetchSimSyncProps(TapiHandle *tapi_handle)
381 {
382   LoggerD("Entered");
383   TelSimImsiInfo_t imsi;
384   int error = tel_get_sim_imsi(tapi_handle, &imsi);
385   if (TAPI_API_SUCCESS == error) {
386     LoggerD("mcc: %s, mnc: %s, msin: %s", imsi.szMcc, imsi.szMnc, imsi.szMsin);
387     mcc_ = std::stoul(imsi.szMcc);
388     mnc_ = std::stoul(imsi.szMnc);
389     msin_ = imsi.szMsin;
390   }
391   else {
392     LoggerE("Failed to get sim imsi: %d", error);
393     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get sim imsi");
394   }
395
396   //TODO add code for iccid value fetching, when proper API would be ready
397   iccid_ = "";
398   return PlatformResult(ErrorCode::NO_ERROR);
399 }
400
401 void SimDetailsManager::ResetSimHolder(picojson::object* out){
402   sim_result_obj_ = out;
403   to_process_ = 0;
404   mcc_ = 0;
405   mnc_ = 0;
406   operator_name_ = "";
407   msin_ = "";
408   state_ = "";
409   msisdn_ = "";
410   iccid_ = "";
411   spn_ = "";
412 }
413
414 void SimDetailsManager::ReturnSimToJS(){
415   LoggerD("Entered");
416   if (nullptr != sim_result_obj_) {
417     sim_result_obj_->insert(std::make_pair("state", picojson::value(state_)));
418     sim_result_obj_->insert(std::make_pair("operatorName", picojson::value(operator_name_)));
419     sim_result_obj_->insert(std::make_pair("msisdn", picojson::value(msisdn_)));
420     sim_result_obj_->insert(std::make_pair("iccid", picojson::value(iccid_)));
421     sim_result_obj_->insert(std::make_pair("mcc", picojson::value(std::to_string(mcc_))));
422     sim_result_obj_->insert(std::make_pair("mnc", picojson::value(std::to_string(mnc_))));
423     sim_result_obj_->insert(std::make_pair("msin", picojson::value(msin_)));
424     sim_result_obj_->insert(std::make_pair("spn", picojson::value(spn_)));
425     //everything returned, clear pointer
426     sim_result_obj_ = nullptr;
427   } else {
428     LoggerE("No sim returned JSON object pointer is null");
429   }
430 }
431
432 long SimDetailsManager::GetSimCount(TapiHandle **tapi_handle){
433   if (0 != sim_count_){
434     LoggerD("Sim counted already");
435   } else {
436     LoggerD("Gathering sim count");
437     char **cp_list = tel_get_cp_name_list();
438     if (cp_list != NULL) {
439       while (cp_list[sim_count_]) {
440         tapi_handle[sim_count_] = tel_init(cp_list[sim_count_]);
441         if (tapi_handle[sim_count_] == NULL) {
442           LoggerE("Failed to connect with tapi, handle is null");
443           break;
444         }
445         sim_count_++;
446         LoggerD("%d modem: %s", sim_count_, cp_list[sim_count_]);
447       }
448     } else {
449       LoggerE("Failed to get cp list");
450       sim_count_ = kTapiMaxHandle;
451     }
452     g_strfreev(cp_list);
453   }
454   return sim_count_;
455 }
456
457 void SimDetailsManager::TryReturn(){
458   if (0 == to_process_){
459     LoggerD("Returning property to JS");
460     ReturnSimToJS();
461     sim_info_mutex_.unlock();
462   } else {
463     LoggerD("Not ready yet - waiting");
464   }
465 }
466
467 /////////////////////////// SystemInfoListeners ////////////////////////////////
468
469 class SystemInfoListeners {
470  public:
471   SystemInfoListeners();
472   ~SystemInfoListeners();
473
474   PlatformResult RegisterBatteryListener(const SysteminfoUtilsCallback& callback,
475                                          SysteminfoInstance& instance);
476   PlatformResult UnregisterBatteryListener();
477   PlatformResult RegisterCpuListener(const SysteminfoUtilsCallback& callback,
478                                      SysteminfoInstance& instance);
479   PlatformResult UnregisterCpuListener();
480   PlatformResult RegisterStorageListener(const SysteminfoUtilsCallback& callback,
481                                          SysteminfoInstance& instance);
482   PlatformResult UnregisterStorageListener();
483   PlatformResult RegisterDisplayListener(const SysteminfoUtilsCallback& callback,
484                                          SysteminfoInstance& instance);
485   PlatformResult UnregisterDisplayListener();
486   PlatformResult RegisterDeviceOrientationListener(const SysteminfoUtilsCallback& callback,
487                                                    SysteminfoInstance& instance);
488   PlatformResult UnregisterDeviceOrientationListener();
489   PlatformResult RegisterLocaleListener(const SysteminfoUtilsCallback& callback,
490                                         SysteminfoInstance& instance);
491   PlatformResult UnregisterLocaleListener();
492   PlatformResult RegisterNetworkListener(const SysteminfoUtilsCallback& callback,
493                                          SysteminfoInstance& instance);
494   PlatformResult UnregisterNetworkListener();
495   PlatformResult RegisterWifiNetworkListener(const SysteminfoUtilsCallback& callback,
496                                              SysteminfoInstance& instance);
497   PlatformResult UnregisterWifiNetworkListener();
498   PlatformResult RegisterEthernetNetworkListener(const SysteminfoUtilsCallback& callback,
499                                                  SysteminfoInstance& instance);
500   PlatformResult UnregisterEthernetNetworkListener();
501   PlatformResult RegisterCellularNetworkListener(const SysteminfoUtilsCallback& callback,
502                                                  SysteminfoInstance& instance);
503   PlatformResult UnregisterCellularNetworkListener();
504   PlatformResult RegisterPeripheralListener(const SysteminfoUtilsCallback& callback,
505                                             SysteminfoInstance& instance);
506   PlatformResult UnregisterPeripheralListener();
507   PlatformResult RegisterMemoryListener(const SysteminfoUtilsCallback& callback,
508                                         SysteminfoInstance& instance);
509   PlatformResult UnregisterMemoryListener();
510   PlatformResult RegisterCameraFlashListener(const SysteminfoUtilsCallback& callback,
511                                         SysteminfoInstance& instance);
512   PlatformResult UnregisterCameraFlashListener();
513
514   void SetCpuInfoLoad(double load);
515   void SetAvailableCapacityInternal(unsigned long long capacity);
516   void SetAvailableCapacityMmc(unsigned long long capacity);
517
518   void OnBatteryChangedCallback(keynode_t* node, void* event_ptr);
519   void OnCpuChangedCallback(void* event_ptr);
520   void OnStorageChangedCallback(void* event_ptr);
521   void OnMmcChangedCallback(keynode_t* node, void* event_ptr);
522   void OnDisplayChangedCallback(keynode_t* node, void* event_ptr);
523   void OnDeviceAutoRotationChangedCallback(keynode_t* node, void* event_ptr);
524   void OnDeviceOrientationChangedCallback(sensor_t sensor, unsigned int event_type,
525                                           sensor_data_t *data, void *user_data);
526   void OnLocaleChangedCallback(system_settings_key_e key, void* event_ptr);
527   void OnNetworkChangedCallback(connection_type_e type, void* event_ptr);
528   void OnNetworkValueCallback(const char* ipv4_address,
529                               const char* ipv6_address, void* event_ptr);
530   void OnCellularNetworkValueCallback(keynode_t *node, void *event_ptr);
531   void OnPeripheralChangedCallback(keynode_t* node, void* event_ptr);
532   void OnMemoryChangedCallback(keynode_t* node, void* event_ptr);
533   void OnBrightnessChangedCallback(device_callback_e type, void* value, void* user_data);
534
535   TapiHandle* GetTapiHandle();
536   TapiHandle** GetTapiHandles();
537   PlatformResult GetConnectionHandle(connection_h&);
538   int GetSensorHandle();
539   PlatformResult ConnectSensor(int* result);
540   void DisconnectSensor(int handle_orientation);
541   wifi_rssi_level_e GetWifiLevel();
542   void SetWifiLevel(wifi_rssi_level_e level);
543   std::string GetCameraTypes(int index);
544   int GetCameraTypesCount();
545  private:
546   static PlatformResult RegisterVconfCallback(const char *in_key, vconf_callback_fn cb,
547                                               SysteminfoInstance& instance);
548   static PlatformResult UnregisterVconfCallback(const char *in_key, vconf_callback_fn cb);
549   PlatformResult RegisterIpChangeCallback(SysteminfoInstance& instance);
550   PlatformResult UnregisterIpChangeCallback();
551   bool IsIpChangeCallbackInvalid();
552   void InitTapiHandles();
553   void InitCameraTypes();
554
555   guint m_cpu_event_id;
556   guint m_storage_event_id;
557
558   double m_cpu_load;
559   double m_last_cpu_load;
560   unsigned long long m_available_capacity_internal;
561   unsigned long long m_available_capacity_mmc;
562   unsigned long long m_last_available_capacity_internal;
563   unsigned long long m_last_available_capacity_mmc;
564   wifi_rssi_level_e m_wifi_level;
565
566   SysteminfoUtilsCallback m_battery_listener;
567   SysteminfoUtilsCallback m_cpu_listener;
568   SysteminfoUtilsCallback m_storage_listener;
569   SysteminfoUtilsCallback m_display_listener;
570   SysteminfoUtilsCallback m_device_orientation_listener;
571   SysteminfoUtilsCallback m_locale_listener;
572   SysteminfoUtilsCallback m_network_listener;
573   SysteminfoUtilsCallback m_wifi_network_listener;
574   SysteminfoUtilsCallback m_ethernet_network_listener;
575   SysteminfoUtilsCallback m_cellular_network_listener;
576   SysteminfoUtilsCallback m_peripheral_listener;
577   SysteminfoUtilsCallback m_memory_listener;
578   SysteminfoUtilsCallback m_camera_flash_listener;
579
580   TapiHandle *m_tapi_handles[kTapiMaxHandle+1];
581   //for ip change callback
582   connection_h m_connection_handle;
583   //! Sensor handle for DeviceOrientation purposes
584   int m_sensor_handle;
585   std::vector<std::string> m_camera_types;
586 };
587 SystemInfoListeners::SystemInfoListeners():
588             m_cpu_event_id(0),
589             m_storage_event_id(0),
590             m_cpu_load(0),
591             m_last_cpu_load(0),
592             m_available_capacity_internal(0),
593             m_available_capacity_mmc(0),
594             m_last_available_capacity_internal(0),
595             m_last_available_capacity_mmc(0),
596             m_wifi_level(WIFI_RSSI_LEVEL_0),
597             m_battery_listener(nullptr),
598             m_cpu_listener(nullptr),
599             m_storage_listener(nullptr),
600             m_display_listener(nullptr),
601             m_device_orientation_listener(nullptr),
602             m_locale_listener(nullptr),
603             m_network_listener(nullptr),
604             m_wifi_network_listener(nullptr),
605             m_ethernet_network_listener(nullptr),
606             m_cellular_network_listener(nullptr),
607             m_peripheral_listener(nullptr),
608             m_memory_listener(nullptr),
609             m_camera_flash_listener(nullptr),
610             m_tapi_handles{nullptr},
611             m_connection_handle(nullptr),
612             m_sensor_handle(-1)
613 {
614   LoggerD("Entered");
615   int error = wifi_initialize();
616   if (WIFI_ERROR_NONE != error) {
617     std::string log_msg = "Initialize failed: " + parseWifiNetworkError(error);
618     LoggerE("%s", log_msg.c_str());
619   } else {
620     LoggerD("WIFI initialization succeed");
621   }
622
623   error = wifi_set_rssi_level_changed_cb(OnWifiLevelChangedCb, nullptr);
624   if (WIFI_ERROR_NONE != error) {
625     std::string log_msg = "Setting wifi listener failed: " + parseWifiNetworkError(error);
626     LoggerE("%s", log_msg.c_str());
627   } else {
628     LoggerD("Setting wifi listener succeed");
629   }
630   InitCameraTypes();
631 }
632
633 SystemInfoListeners::~SystemInfoListeners(){
634   LoggerD("Entered");
635   UnregisterBatteryListener();
636   UnregisterCpuListener();
637   UnregisterStorageListener();
638   UnregisterDisplayListener();
639   UnregisterDeviceOrientationListener();
640   UnregisterLocaleListener();
641   UnregisterNetworkListener();
642   UnregisterWifiNetworkListener();
643   UnregisterCellularNetworkListener();
644   UnregisterPeripheralListener();
645   UnregisterMemoryListener();
646
647   DisconnectSensor(m_sensor_handle);
648
649   unsigned int i = 0;
650   while(m_tapi_handles[i]) {
651     tel_deinit(m_tapi_handles[i]);
652     i++;
653   }
654   if (nullptr != m_connection_handle) {
655     connection_destroy(m_connection_handle);
656   }
657
658   wifi_deinitialize();
659 }
660
661 #define CHECK_LISTENER_ERROR(method) \
662   ret = method; \
663   if (ret.IsError()) { \
664     return ret; \
665   }
666
667 int SystemInfoListeners::GetSensorHandle() {
668   if (m_sensor_handle < 0) {
669     LoggerD("Connecting to sensor");
670     ConnectSensor(&m_sensor_handle);
671   } else {
672     LoggerD("Sensor already connected");
673   }
674   return m_sensor_handle;
675 }
676
677 PlatformResult SystemInfoListeners::ConnectSensor(int* result) {
678   LoggerD("Entered");
679   sensor_t sensor = sensord_get_sensor(AUTO_ROTATION_SENSOR);
680   int handle_orientation = sensord_connect(sensor);
681   if (handle_orientation < 0) {
682     std::string log_msg = "Failed to connect auto rotation sensor";
683     LoggerE("%s", log_msg.c_str());
684     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
685   }
686   bool ret = sensord_start(handle_orientation, 0);
687   if(!ret) {
688     sensord_disconnect(handle_orientation);
689     std::string log_msg = "Failed to start auto rotation sensor";
690     LoggerE("%s", log_msg.c_str());
691     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
692   }
693   LoggerD("Sensor starts successfully = %d", handle_orientation);
694   *result = handle_orientation;
695   return PlatformResult(ErrorCode::NO_ERROR);
696 }
697
698 void SystemInfoListeners::DisconnectSensor(int handle_orientation)
699 {
700   if (handle_orientation >= 0) {
701     LoggerD("Entered");
702     bool state = sensord_stop(handle_orientation);
703     LoggerD("sensord_stop() returned state = %d", state);
704     state = sensord_disconnect(handle_orientation);
705     LoggerD("sensord_disconnect() returned state %d", state);
706   } else {
707     LoggerD("sensor already disconnected - no action needed");
708   }
709 }
710
711 wifi_rssi_level_e SystemInfoListeners::GetWifiLevel()
712 {
713   return m_wifi_level;
714 }
715
716 void SystemInfoListeners::SetWifiLevel(wifi_rssi_level_e level)
717 {
718   m_wifi_level = level;
719 }
720
721 std::string SystemInfoListeners::GetCameraTypes(int index) {
722   if (index >= m_camera_types.size()) {
723     return "";
724   }
725   return m_camera_types[index];
726 }
727
728 int SystemInfoListeners::GetCameraTypesCount() {
729   return m_camera_types.size();
730 }
731
732 PlatformResult SystemInfoListeners::RegisterBatteryListener(
733     const SysteminfoUtilsCallback& callback, SysteminfoInstance& instance) {
734   LoggerD("Entered");
735   if (nullptr == m_battery_listener) {
736     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
737     CHECK_LISTENER_ERROR(
738         RegisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CAPACITY, OnBatteryChangedCb, instance))
739     CHECK_LISTENER_ERROR(
740         RegisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, OnBatteryChangedCb, instance))
741     LoggerD("Added callback for BATTERY");
742     m_battery_listener = callback;
743   }
744   return PlatformResult(ErrorCode::NO_ERROR);
745 }
746
747 PlatformResult SystemInfoListeners::UnregisterBatteryListener()
748 {
749   if (nullptr != m_battery_listener) {
750     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
751     CHECK_LISTENER_ERROR(
752         UnregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CAPACITY, OnBatteryChangedCb))
753     CHECK_LISTENER_ERROR(
754         UnregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, OnBatteryChangedCb))
755     LoggerD("Removed callback for BATTERY");
756     m_battery_listener = nullptr;
757   }
758   return PlatformResult(ErrorCode::NO_ERROR);
759 }
760
761 PlatformResult SystemInfoListeners::RegisterCpuListener(const SysteminfoUtilsCallback& callback,
762                                                         SysteminfoInstance& instance)
763 {
764   if (nullptr == m_cpu_listener) {
765     m_cpu_event_id = g_timeout_add_seconds(kPropertyWatcherTime, OnCpuChangedCb, static_cast<void*>(&instance));
766     LoggerD("Added callback for CPU");
767     m_cpu_listener = callback;
768   }
769   return PlatformResult(ErrorCode::NO_ERROR);
770 }
771
772 PlatformResult SystemInfoListeners::UnregisterCpuListener()
773 {
774   if (nullptr != m_cpu_listener) {
775     g_source_remove(m_cpu_event_id);
776     m_cpu_event_id = 0;
777     LoggerD("Removed callback for CPU");
778     m_cpu_listener = nullptr;
779   }
780   return PlatformResult(ErrorCode::NO_ERROR);
781 }
782
783 PlatformResult SystemInfoListeners::RegisterStorageListener(const SysteminfoUtilsCallback& callback,
784                                                             SysteminfoInstance& instance)
785 {
786   if (nullptr == m_storage_listener) {
787     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
788     CHECK_LISTENER_ERROR(
789         RegisterVconfCallback(VCONFKEY_SYSMAN_MMC_STATUS, OnMmcChangedCb, instance))
790
791     m_storage_event_id = g_timeout_add_seconds(kPropertyWatcherTime, OnStorageChangedCb, static_cast<void*>(&instance));
792     LoggerD("Added callback for STORAGE");
793     m_storage_listener = callback;
794   }
795   return PlatformResult(ErrorCode::NO_ERROR);
796 }
797
798 PlatformResult SystemInfoListeners::UnregisterStorageListener()
799 {
800   if (nullptr != m_storage_listener) {
801     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
802     CHECK_LISTENER_ERROR(
803         UnregisterVconfCallback(VCONFKEY_SYSMAN_MMC_STATUS, OnMmcChangedCb))
804
805     g_source_remove(m_storage_event_id);
806     m_storage_event_id = 0;
807     LoggerD("Removed callback for STORAGE");
808     m_storage_listener = nullptr;
809   }
810   return PlatformResult(ErrorCode::NO_ERROR);
811 }
812
813 PlatformResult SystemInfoListeners::RegisterDisplayListener(const SysteminfoUtilsCallback& callback,
814                                                             SysteminfoInstance& instance)
815 {
816   if (nullptr == m_display_listener) {
817     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
818     CHECK_LISTENER_ERROR(
819         RegisterVconfCallback(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, OnDisplayChangedCb, instance))
820     LoggerD("Added callback for DISPLAY");
821     m_display_listener = callback;
822   }
823   return PlatformResult(ErrorCode::NO_ERROR);
824 }
825
826 PlatformResult SystemInfoListeners::UnregisterDisplayListener()
827 {
828   if (nullptr != m_display_listener) {
829     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
830     CHECK_LISTENER_ERROR(
831         UnregisterVconfCallback(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, OnDisplayChangedCb))
832     LoggerD("Removed callback for DISPLAY");
833     m_display_listener = nullptr;
834   }
835   return PlatformResult(ErrorCode::NO_ERROR);
836 }
837
838 PlatformResult SystemInfoListeners::RegisterDeviceOrientationListener(const SysteminfoUtilsCallback& callback,
839                                                                       SysteminfoInstance& instance)
840 {
841   if (nullptr == m_device_orientation_listener) {
842     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
843     CHECK_LISTENER_ERROR(
844         RegisterVconfCallback(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, OnDeviceAutoRotationChangedCb, instance))
845
846     bool sensor_ret = sensord_register_event(GetSensorHandle(), AUTO_ROTATION_EVENT_CHANGE_STATE,
847                                      BASE_GATHERING_INTERVAL, 0,
848                                      OnDeviceOrientationChangedCb, static_cast<void*>(&instance));
849     if (!sensor_ret) {
850       LoggerE("Failed to register orientation change event listener");
851       return PlatformResult(ErrorCode::UNKNOWN_ERR,
852                             "Failed to register orientation change event listener");
853     }
854
855     LoggerD("Added callback for DEVICE_ORIENTATION");
856     m_device_orientation_listener = callback;
857   }
858   return PlatformResult(ErrorCode::NO_ERROR);
859 }
860
861 PlatformResult SystemInfoListeners::UnregisterDeviceOrientationListener()
862 {
863   if (nullptr != m_device_orientation_listener) {
864     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
865     CHECK_LISTENER_ERROR(
866         UnregisterVconfCallback(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, OnDeviceAutoRotationChangedCb))
867     bool sensor_ret = sensord_unregister_event(GetSensorHandle(), AUTO_ROTATION_EVENT_CHANGE_STATE);
868     if (!sensor_ret) {
869       LoggerE("Failed to unregister orientation change event listener");
870       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to unregister"
871           " orientation change event listener");
872     }
873
874     LoggerD("Removed callback for DEVICE_ORIENTATION");
875     m_device_orientation_listener = nullptr;
876   }
877   return PlatformResult(ErrorCode::NO_ERROR);
878 }
879
880 PlatformResult SystemInfoListeners::RegisterLocaleListener(const SysteminfoUtilsCallback& callback,
881                                                            SysteminfoInstance& instance)
882 {
883   if (nullptr == m_locale_listener) {
884     if (SYSTEM_SETTINGS_ERROR_NONE !=
885         system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY,
886                                     OnLocaleChangedCb, static_cast<void*>(&instance)) ) {
887       LoggerE("Country change callback registration failed");
888       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Country change callback registration failed");
889     }
890     if (SYSTEM_SETTINGS_ERROR_NONE !=
891         system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE,
892                                     OnLocaleChangedCb, static_cast<void*>(&instance)) ) {
893       LoggerE("Language change callback registration failed");
894       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Language change callback registration failed");
895     }
896     LoggerD("Added callback for LOCALE");
897     m_locale_listener = callback;
898   }
899   return PlatformResult(ErrorCode::NO_ERROR);
900 }
901
902 PlatformResult SystemInfoListeners::UnregisterLocaleListener()
903 {
904   if (nullptr != m_locale_listener) {
905     if (SYSTEM_SETTINGS_ERROR_NONE !=
906         system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE) ) {
907       LoggerE("Unregistration of language change callback failed");
908     }
909     if (SYSTEM_SETTINGS_ERROR_NONE !=
910         system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY) ) {
911       LoggerE("Unregistration of country change callback failed");
912     }
913     LoggerD("Removed callback for LOCALE");
914     m_locale_listener = nullptr;
915   }
916   return PlatformResult(ErrorCode::NO_ERROR);
917 }
918
919 PlatformResult SystemInfoListeners::RegisterNetworkListener(const SysteminfoUtilsCallback& callback,
920                                                             SysteminfoInstance& instance)
921 {
922   if (nullptr == m_network_listener) {
923     connection_h handle;
924     PlatformResult ret(ErrorCode::NO_ERROR);
925     CHECK_LISTENER_ERROR(GetConnectionHandle(handle))
926     if (CONNECTION_ERROR_NONE !=
927         connection_set_type_changed_cb(handle, OnNetworkChangedCb, static_cast<void*>(&instance))) {
928       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Registration of listener failed");
929     }
930     LoggerD("Added callback for NETWORK");
931     m_network_listener = callback;
932   }
933   return PlatformResult(ErrorCode::NO_ERROR);
934 }
935
936 PlatformResult SystemInfoListeners::UnregisterNetworkListener()
937 {
938   if (nullptr != m_network_listener) {
939     connection_h handle;
940     PlatformResult ret(ErrorCode::NO_ERROR);
941     CHECK_LISTENER_ERROR(GetConnectionHandle(handle))
942     if (CONNECTION_ERROR_NONE != connection_unset_type_changed_cb(handle)) {
943       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unregistration of listener failed");
944     }
945     LoggerD("Removed callback for NETWORK");
946     m_network_listener = nullptr;
947   }
948   return PlatformResult(ErrorCode::NO_ERROR);
949 }
950
951 PlatformResult SystemInfoListeners::RegisterWifiNetworkListener(const SysteminfoUtilsCallback& callback,
952                                                                 SysteminfoInstance& instance)
953 {
954   LoggerD("Entered");
955
956   if (IsIpChangeCallbackInvalid()) {
957     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
958     CHECK_LISTENER_ERROR(RegisterIpChangeCallback(instance));
959     LoggerD("Registered IP change listener");
960   } else {
961     LoggerD("No need to register IP listener on platform, already registered");
962   }
963
964   if (nullptr == m_wifi_network_listener) {
965     LoggerD("Added callback for WIFI_NETWORK");
966     m_wifi_network_listener = callback;
967   }
968   return PlatformResult(ErrorCode::NO_ERROR);
969 }
970
971 PlatformResult SystemInfoListeners::UnregisterWifiNetworkListener()
972 {
973   LoggerD("Entered");
974
975   m_wifi_network_listener = nullptr;
976
977   if (IsIpChangeCallbackInvalid()) {
978     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
979     CHECK_LISTENER_ERROR(UnregisterIpChangeCallback());
980     LoggerD("Removed IP change listener");
981   } else {
982     LoggerD("Removed callback for WIFI_NETWORK, but IP change listener still works");
983   }
984
985   return PlatformResult(ErrorCode::NO_ERROR);
986 }
987
988 PlatformResult CheckIfEthernetNetworkSupported()
989 {
990   LoggerD("Entered");
991   connection_h connection_handle = nullptr;
992   connection_ethernet_state_e connection_state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
993
994   int error = connection_create(&connection_handle);
995   if (CONNECTION_ERROR_NONE != error) {
996     std::string log_msg = "Cannot create connection: " + std::to_string(error);
997     LoggerE("%s", log_msg.c_str());
998     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
999   }
1000   std::unique_ptr<std::remove_pointer<connection_h>::type, int (*)(connection_h)> connection_handle_ptr(
1001     connection_handle, &connection_destroy);  // automatically release the memory
1002
1003   error = connection_get_ethernet_state(connection_handle, &connection_state);
1004   if (CONNECTION_ERROR_NOT_SUPPORTED == error) {
1005     std::string log_msg = "Cannot get ethernet connection state: Not supported";
1006     LoggerE("%s", log_msg.c_str());
1007     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, log_msg);
1008   }
1009   return PlatformResult(ErrorCode::NO_ERROR);
1010 }
1011
1012 common::PlatformResult CheckTelephonySupport() {
1013   bool supported = false;
1014   PlatformResult ret = SystemInfoDeviceCapability::GetValueBool(
1015     "tizen.org/feature/network.telephony", &supported);
1016   if (ret.IsError()) {
1017     return ret;
1018   }
1019   if (!supported) {
1020     LoggerD("Telephony is not supported on this device");
1021     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1022         "Telephony is not supported on this device");
1023   }
1024   return PlatformResult(ErrorCode::NO_ERROR);
1025 }
1026
1027 common::PlatformResult CheckCameraFlashSupport() {
1028   bool supported = false;
1029   PlatformResult ret = SystemInfoDeviceCapability::GetValueBool(
1030     "tizen.org/feature/camera.back.flash", &supported);
1031   if (ret.IsError()) {
1032     return ret;
1033   }
1034   if (!supported) {
1035     LoggerD("Back-facing camera with a flash is not supported on this device");
1036     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR,
1037         "Back-facing camera with a flash is not supported on this device");
1038   }
1039   return PlatformResult(ErrorCode::NO_ERROR);
1040 }
1041
1042 PlatformResult SystemInfoListeners::RegisterEthernetNetworkListener(const SysteminfoUtilsCallback& callback,
1043                                                                     SysteminfoInstance& instance)
1044 {
1045   LoggerD("Entered");
1046   PlatformResult ret = CheckIfEthernetNetworkSupported();
1047   if (ret.IsError()){
1048     return ret;
1049   }
1050
1051   if (IsIpChangeCallbackInvalid()) {
1052     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1053     CHECK_LISTENER_ERROR(RegisterIpChangeCallback(instance));
1054     LoggerD("Registered IP change listener");
1055   } else {
1056     LoggerD("No need to register IP listener on platform, already registered");
1057   }
1058
1059   if (nullptr == m_ethernet_network_listener) {
1060     LoggerD("Added callback for ETHERNET_NETWORK");
1061     m_ethernet_network_listener = callback;
1062   }
1063   return PlatformResult(ErrorCode::NO_ERROR);
1064 }
1065
1066 PlatformResult SystemInfoListeners::UnregisterEthernetNetworkListener()
1067 {
1068   LoggerD("Entered");
1069
1070   m_ethernet_network_listener = nullptr;
1071
1072   if (IsIpChangeCallbackInvalid()) {
1073     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1074     CHECK_LISTENER_ERROR(UnregisterIpChangeCallback());
1075     LoggerD("Removed IP change listener");
1076   } else {
1077     LoggerD("Removed callback for ETHERNET_NETWORK, but IP change listener still works");
1078   }
1079
1080   return PlatformResult(ErrorCode::NO_ERROR);
1081 }
1082
1083 PlatformResult SystemInfoListeners::RegisterCellularNetworkListener(const SysteminfoUtilsCallback& callback,
1084                                                                     SysteminfoInstance& instance)
1085 {
1086   LoggerD("Entered");
1087   PlatformResult ret = CheckTelephonySupport();
1088   if (ret.IsError()) {
1089       return ret;
1090   }
1091
1092   if (IsIpChangeCallbackInvalid()) {
1093     CHECK_LISTENER_ERROR(RegisterIpChangeCallback(instance));
1094     LoggerD("Registered IP change listener");
1095   } else {
1096     LoggerD("No need to register IP listener on platform, already registered");
1097   }
1098
1099   if (nullptr == m_cellular_network_listener) {
1100     CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_TELEPHONY_FLIGHT_MODE,
1101                           OnCellularNetworkValueChangedCb, instance))
1102     CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_TELEPHONY_CELLID,
1103                           OnCellularNetworkValueChangedCb, instance))
1104     CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_TELEPHONY_LAC,
1105                           OnCellularNetworkValueChangedCb, instance))
1106     CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_TELEPHONY_SVC_ROAM,
1107                           OnCellularNetworkValueChangedCb, instance))
1108     LoggerD("Added callback for CELLULAR_NETWORK");
1109     m_cellular_network_listener = callback;
1110   }
1111   return PlatformResult(ErrorCode::NO_ERROR);
1112 }
1113
1114 PlatformResult SystemInfoListeners::UnregisterCellularNetworkListener()
1115 {
1116   LoggerD("Entered");
1117
1118   if (nullptr != m_cellular_network_listener) {
1119     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1120     CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_TELEPHONY_FLIGHT_MODE,
1121                             OnCellularNetworkValueChangedCb))
1122     CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_TELEPHONY_CELLID,
1123                             OnCellularNetworkValueChangedCb))
1124     CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_TELEPHONY_LAC,
1125                             OnCellularNetworkValueChangedCb))
1126     CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_TELEPHONY_SVC_ROAM,
1127                             OnCellularNetworkValueChangedCb))
1128   }
1129   m_cellular_network_listener = nullptr;
1130
1131   if (IsIpChangeCallbackInvalid()) {
1132     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1133     CHECK_LISTENER_ERROR(UnregisterIpChangeCallback());
1134     LoggerD("Removed IP change listener");
1135   } else {
1136     LoggerD("Removed callback for CELLULAR_NETWORK, but IP change listener still works");
1137   }
1138
1139   return PlatformResult(ErrorCode::NO_ERROR);
1140 }
1141
1142 PlatformResult SystemInfoListeners::RegisterPeripheralListener(const SysteminfoUtilsCallback& callback,
1143                                                                SysteminfoInstance& instance)
1144 {
1145   if (nullptr == m_peripheral_listener) {
1146     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1147     int value = 0;
1148 /*    if (-1 != vconf_get_int(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &value)) {
1149       CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS,
1150                                                  OnPeripheralChangedCb, instance))
1151     }*/
1152     if (-1 != vconf_get_int(VCONFKEY_SYSMAN_HDMI, &value)) {
1153       CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_SYSMAN_HDMI,
1154                                                  OnPeripheralChangedCb, instance))
1155     }
1156
1157     LoggerD("Added callback for PERIPHERAL");
1158     m_peripheral_listener = callback;
1159   }
1160   return PlatformResult(ErrorCode::NO_ERROR);
1161 }
1162
1163 PlatformResult SystemInfoListeners::UnregisterPeripheralListener()
1164 {
1165   if (nullptr != m_peripheral_listener) {
1166     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1167     int value = 0;
1168 /*    if (-1 != vconf_get_int(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &value)) {
1169       CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS,
1170                                                    OnPeripheralChangedCb))
1171     }*/
1172     if (-1 != vconf_get_int(VCONFKEY_SYSMAN_HDMI, &value)) {
1173       CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_SYSMAN_HDMI,
1174                                                    OnPeripheralChangedCb))
1175     }
1176
1177     LoggerD("Removed callback for PERIPHERAL");
1178     m_peripheral_listener = nullptr;
1179   }
1180   return PlatformResult(ErrorCode::NO_ERROR);
1181 }
1182
1183 PlatformResult SystemInfoListeners::RegisterMemoryListener(const SysteminfoUtilsCallback& callback,
1184                                                            SysteminfoInstance& instance)
1185 {
1186   if (nullptr == m_memory_listener) {
1187     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1188     int value = 0;
1189     if (-1 != vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &value)) {
1190       CHECK_LISTENER_ERROR(RegisterVconfCallback(VCONFKEY_SYSMAN_LOW_MEMORY, OnMemoryChangedCb, instance))
1191     }
1192     LoggerD("Added callback for MEMORY");
1193     m_memory_listener = callback;
1194   }
1195   return PlatformResult(ErrorCode::NO_ERROR);
1196 }
1197
1198 PlatformResult SystemInfoListeners::UnregisterMemoryListener()
1199 {
1200   if (nullptr != m_memory_listener) {
1201     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1202     int value = 0;
1203     if (-1 != vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &value)) {
1204       CHECK_LISTENER_ERROR(UnregisterVconfCallback(VCONFKEY_SYSMAN_LOW_MEMORY, OnMemoryChangedCb))
1205     }
1206     LoggerD("Removed callback for MEMORY");
1207     m_memory_listener = nullptr;
1208   }
1209   return PlatformResult(ErrorCode::NO_ERROR);
1210 }
1211
1212 PlatformResult SystemInfoListeners::RegisterCameraFlashListener(const SysteminfoUtilsCallback& callback,
1213                                                            SysteminfoInstance& instance)
1214 {
1215   if (nullptr == m_camera_flash_listener) {
1216     if (DEVICE_ERROR_NONE != device_add_callback(DEVICE_CALLBACK_FLASH_BRIGHTNESS,
1217                               OnBrightnessChangedCb, static_cast<void*>(&instance))) {
1218         return PlatformResult(ErrorCode::UNKNOWN_ERR);
1219       }
1220       m_camera_flash_listener = callback;
1221   }
1222     return PlatformResult(ErrorCode::NO_ERROR);
1223 }
1224
1225 PlatformResult SystemInfoListeners::UnregisterCameraFlashListener()
1226 {
1227   if (nullptr != m_camera_flash_listener) {
1228     PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR);
1229     if (DEVICE_ERROR_NONE != device_remove_callback(DEVICE_CALLBACK_FLASH_BRIGHTNESS,
1230                                                  OnBrightnessChangedCb)) {
1231       return PlatformResult(ErrorCode::UNKNOWN_ERR);
1232     }
1233     LoggerD("Removed callback for camera_flash");
1234     m_camera_flash_listener = nullptr;
1235   }
1236   return PlatformResult(ErrorCode::NO_ERROR);
1237 }
1238
1239
1240 void SystemInfoListeners::SetCpuInfoLoad(double load)
1241 {
1242   m_cpu_load = load;
1243 }
1244
1245 void SystemInfoListeners::SetAvailableCapacityInternal(unsigned long long capacity)
1246 {
1247   m_available_capacity_internal = capacity;
1248 }
1249
1250 void SystemInfoListeners::SetAvailableCapacityMmc(unsigned long long capacity)
1251 {
1252   m_available_capacity_mmc = capacity;
1253 }
1254
1255 void SystemInfoListeners::OnBatteryChangedCallback(keynode_t* /*node*/, void* event_ptr)
1256 {
1257   if (nullptr != m_battery_listener) {
1258     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1259     m_battery_listener(*instance);
1260   }
1261 }
1262
1263 void SystemInfoListeners::OnCpuChangedCallback(void* event_ptr)
1264 {
1265   LoggerD("");
1266   picojson::value result = picojson::value(picojson::object());
1267   PlatformResult ret = SysteminfoUtils::GetPropertyValue(kPropertyIdCpu, false, result);
1268   if (ret.IsSuccess()) {
1269     if (m_cpu_load == m_last_cpu_load) {
1270       return;
1271     }
1272     if (nullptr != m_cpu_listener) {
1273       SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1274       m_last_cpu_load = m_cpu_load;
1275       m_cpu_listener(*instance);
1276     }
1277   }
1278 }
1279
1280 void SystemInfoListeners::OnStorageChangedCallback(void* event_ptr)
1281 {
1282   LoggerD("");
1283   picojson::value result = picojson::value(picojson::object());
1284   PlatformResult ret = SysteminfoUtils::GetPropertyValue(kPropertyIdStorage, false, result);
1285   if (ret.IsSuccess()) {
1286     if (m_available_capacity_internal == m_last_available_capacity_internal) {
1287       return;
1288     }
1289
1290     if (nullptr != m_storage_listener) {
1291       SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1292       m_last_available_capacity_internal = m_available_capacity_internal;
1293       m_storage_listener(*instance);
1294     }
1295   }
1296 }
1297
1298 void SystemInfoListeners::OnMmcChangedCallback(keynode_t* /*node*/, void* event_ptr)
1299 {
1300   LoggerD("");
1301   picojson::value result = picojson::value(picojson::object());
1302   PlatformResult ret = SysteminfoUtils::GetPropertyValue(kPropertyIdStorage, false, result);
1303   if (ret.IsSuccess()) {
1304     if (m_available_capacity_mmc == m_last_available_capacity_mmc) {
1305       return;
1306     }
1307     if (nullptr != m_storage_listener) {
1308       SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1309       m_last_available_capacity_mmc = m_available_capacity_mmc;
1310       m_storage_listener(*instance);
1311     }
1312   }
1313 }
1314
1315
1316 void SystemInfoListeners::OnDisplayChangedCallback(keynode_t* /*node*/, void* event_ptr)
1317 {
1318   if (nullptr != m_display_listener) {
1319     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1320     m_display_listener(*instance);
1321   }
1322 }
1323
1324 void SystemInfoListeners::OnDeviceAutoRotationChangedCallback(keynode_t* /*node*/, void* event_ptr)
1325 {
1326   if (nullptr != m_device_orientation_listener) {
1327     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1328     m_device_orientation_listener(*instance);
1329   }
1330 }
1331
1332 void SystemInfoListeners::OnDeviceOrientationChangedCallback(sensor_t sensor, unsigned int event_type,
1333                                                              sensor_data_t *data, void *user_data)
1334 {
1335   if (nullptr != m_device_orientation_listener) {
1336     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(user_data);
1337     m_device_orientation_listener(*instance);
1338   }
1339 }
1340
1341 void SystemInfoListeners::OnLocaleChangedCallback(system_settings_key_e /*key*/, void* event_ptr)
1342 {
1343   if (nullptr != m_locale_listener) {
1344     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1345     m_locale_listener(*instance);
1346   }
1347 }
1348
1349 void SystemInfoListeners::OnNetworkChangedCallback(connection_type_e /*type*/, void* event_ptr)
1350 {
1351   if (nullptr != m_network_listener) {
1352     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1353     m_network_listener(*instance);
1354   }
1355 }
1356
1357 void SystemInfoListeners::OnNetworkValueCallback(const char* /*ipv4_address*/,
1358                                                  const char* /*ipv6_address*/, void* event_ptr)
1359 {
1360   LoggerD("Entered");
1361
1362   SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1363   if (nullptr != m_wifi_network_listener) {
1364     m_wifi_network_listener(*instance);
1365   }
1366   if (nullptr != m_ethernet_network_listener) {
1367     m_ethernet_network_listener(*instance);
1368   }
1369   if (nullptr != m_cellular_network_listener) {
1370     m_cellular_network_listener(*instance);
1371   }
1372 }
1373
1374 void SystemInfoListeners::OnCellularNetworkValueCallback(keynode_t */*node*/, void *event_ptr)
1375 {
1376   if (nullptr != m_cellular_network_listener) {
1377     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1378     m_cellular_network_listener(*instance);
1379   }
1380 }
1381
1382 void SystemInfoListeners::OnPeripheralChangedCallback(keynode_t* /*node*/, void* event_ptr)
1383 {
1384   if (nullptr != m_peripheral_listener) {
1385     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1386     m_peripheral_listener(*instance);
1387   }
1388 }
1389
1390 void SystemInfoListeners::OnMemoryChangedCallback(keynode_t* /*node*/, void* event_ptr)
1391 {
1392   if (nullptr != m_memory_listener) {
1393     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(event_ptr);
1394     m_memory_listener(*instance);
1395   }
1396 }
1397
1398 void SystemInfoListeners::OnBrightnessChangedCallback(device_callback_e type, void* value, void* user_data)
1399 {
1400   if (nullptr != m_camera_flash_listener) {
1401     SysteminfoInstance* instance = static_cast<SysteminfoInstance*>(user_data);
1402     m_camera_flash_listener(*instance);
1403   }
1404 }
1405
1406 void SystemInfoListeners::InitTapiHandles()
1407 {
1408   LoggerD("Entered");
1409   int sim_count = 0;
1410   if (nullptr == m_tapi_handles[0]){  //check if anything is in table
1411     char **cp_list = tel_get_cp_name_list();
1412     if (nullptr != cp_list) {
1413       while (cp_list[sim_count]) {
1414         m_tapi_handles[sim_count] = tel_init(cp_list[sim_count]);
1415         if (nullptr == m_tapi_handles[sim_count]) {
1416           LoggerE("Failed to connect with tapi, handle is null");
1417           break;
1418         }
1419         sim_count++;
1420         LoggerD("%d modem: %s", sim_count, cp_list[sim_count]);
1421       }
1422     } else {
1423       LoggerE("Failed to get cp list");
1424       sim_count = kTapiMaxHandle;
1425     }
1426     g_strfreev(cp_list);
1427   }
1428 }
1429
1430 void SystemInfoListeners::InitCameraTypes() {
1431   bool supported = false;
1432   PlatformResult ret = SystemInfoDeviceCapability::GetValueBool(
1433       "tizen.org/feature/camera.back.flash", &supported);
1434   if (ret.IsSuccess()) {
1435     if (supported) {
1436       m_camera_types.push_back("BACK");
1437     }
1438   }
1439   ret = SystemInfoDeviceCapability::GetValueBool(
1440       "tizen.org/feature/camera.front.flash", &supported);
1441   if (ret.IsSuccess()) {
1442     if (supported) {
1443       m_camera_types.push_back("FRONT");
1444     }
1445   }
1446 }
1447
1448 TapiHandle* SystemInfoListeners::GetTapiHandle() {
1449
1450   LoggerD("Entered");
1451   InitTapiHandles();
1452   return m_tapi_handles[0];
1453 }
1454
1455 TapiHandle** SystemInfoListeners::GetTapiHandles()
1456 {
1457   InitTapiHandles();
1458   return m_tapi_handles;
1459 }
1460
1461 PlatformResult SystemInfoListeners::GetConnectionHandle(connection_h& handle)
1462 {
1463   if (nullptr == m_connection_handle) {
1464     int error = connection_create(&m_connection_handle);
1465     if (CONNECTION_ERROR_NONE != error) {
1466       LoggerE("Failed to create connection: %d", error);
1467       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot create connection");
1468     }
1469   }
1470   handle = m_connection_handle;
1471   return PlatformResult(ErrorCode::NO_ERROR);
1472 }
1473
1474 //////////////// Private ////////////////////
1475
1476 PlatformResult SystemInfoListeners::RegisterVconfCallback(const char *in_key, vconf_callback_fn cb,
1477                                                           SysteminfoInstance& instance)
1478 {
1479   if (0 != vconf_notify_key_changed(in_key, cb, static_cast<void*>(&instance))) {
1480     LoggerE("Failed to register vconf callback: %s", in_key);
1481     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register vconf callback");
1482   }
1483   return PlatformResult(ErrorCode::NO_ERROR);
1484 }
1485
1486 PlatformResult SystemInfoListeners::UnregisterVconfCallback(const char *in_key, vconf_callback_fn cb)
1487 {
1488   if (0 != vconf_ignore_key_changed(in_key, cb)) {
1489     LoggerE("Failed to unregister vconf callback: %s", in_key);
1490     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to unregister vconf callback");
1491   }
1492   return PlatformResult(ErrorCode::NO_ERROR);
1493 }
1494
1495 PlatformResult SystemInfoListeners::RegisterIpChangeCallback(SysteminfoInstance& instance)
1496 {
1497   LoggerD("Registering connection callback");
1498   connection_h handle;
1499   PlatformResult ret(ErrorCode::NO_ERROR);
1500   CHECK_LISTENER_ERROR(GetConnectionHandle(handle))
1501   int error = connection_set_ip_address_changed_cb(handle,
1502                                                    OnNetworkValueChangedCb,
1503                                                    static_cast<void*>(&instance));
1504   if (CONNECTION_ERROR_NONE != error) {
1505     LoggerE("Failed to register ip change callback: %d", error);
1506     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot register ip change callback");
1507   }
1508   return PlatformResult(ErrorCode::NO_ERROR);
1509 }
1510
1511 PlatformResult SystemInfoListeners::UnregisterIpChangeCallback()
1512 {
1513   LoggerD("Unregistering connection callback");
1514   connection_h handle;
1515   PlatformResult ret(ErrorCode::NO_ERROR);
1516   CHECK_LISTENER_ERROR(GetConnectionHandle(handle))
1517   int error = connection_unset_ip_address_changed_cb(handle);
1518   if (CONNECTION_ERROR_NONE != error) {
1519     LoggerE("Failed to unregister ip change callback: %d", error);
1520     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot unregister ip change callback");
1521   }
1522   return PlatformResult(ErrorCode::NO_ERROR);
1523 }
1524
1525 bool SystemInfoListeners::IsIpChangeCallbackInvalid() {
1526   LoggerD("Entered");
1527   return (nullptr == m_wifi_network_listener &&
1528           nullptr == m_ethernet_network_listener &&
1529           nullptr == m_cellular_network_listener);
1530 }
1531
1532 /////////////////////////// system_info_listeners object ////////////////////////
1533
1534 static SystemInfoListeners system_info_listeners;
1535
1536 //global sim manager - needed for async gathering informations
1537 static SimDetailsManager sim_mgr;
1538
1539 /////////////////// Callbacks ///////////////////////////////////////////////////
1540
1541 void OnBatteryChangedCb(keynode_t* node, void* event_ptr)
1542 {
1543   LoggerD("");
1544   system_info_listeners.OnBatteryChangedCallback(node, event_ptr);
1545 }
1546
1547 gboolean OnCpuChangedCb(gpointer event_ptr)
1548 {
1549   LoggerD("");
1550   system_info_listeners.OnCpuChangedCallback(event_ptr);
1551   return G_SOURCE_CONTINUE;
1552 }
1553 gboolean OnStorageChangedCb(gpointer event_ptr)
1554 {
1555   LoggerD("");
1556   system_info_listeners.OnStorageChangedCallback(event_ptr);
1557   return G_SOURCE_CONTINUE;
1558 }
1559 void OnMmcChangedCb(keynode_t* node, void* event_ptr)
1560 {
1561   LoggerD("");
1562   system_info_listeners.OnMmcChangedCallback(node, event_ptr);
1563 }
1564
1565 void OnDisplayChangedCb(keynode_t* node, void* event_ptr)
1566 {
1567   LoggerD("");
1568   system_info_listeners.OnDisplayChangedCallback(node, event_ptr);
1569 }
1570
1571 void OnDeviceAutoRotationChangedCb(keynode_t* node, void* event_ptr)
1572 {
1573   LoggerD("");
1574   system_info_listeners.OnDeviceAutoRotationChangedCallback(node, event_ptr);
1575 }
1576
1577 void OnDeviceOrientationChangedCb(sensor_t sensor, unsigned int event_type,
1578                                   sensor_data_t *data, void *user_data)
1579 {
1580   LoggerD("");
1581   system_info_listeners.OnDeviceOrientationChangedCallback(sensor, event_type, data, user_data);
1582 }
1583
1584 void OnLocaleChangedCb(system_settings_key_e key, void* event_ptr)
1585 {
1586   LoggerD("");
1587   system_info_listeners.OnLocaleChangedCallback(key, event_ptr);
1588 }
1589
1590 void OnNetworkChangedCb(connection_type_e type, void* event_ptr)
1591 {
1592   LoggerD("");
1593   system_info_listeners.OnNetworkChangedCallback(type, event_ptr);
1594 }
1595
1596 void OnNetworkValueChangedCb(const char* ipv4_address,
1597                              const char* ipv6_address, void* event_ptr)
1598 {
1599   LoggerD("");
1600   system_info_listeners.OnNetworkValueCallback(ipv4_address, ipv6_address, event_ptr);
1601 }
1602
1603 void OnCellularNetworkValueChangedCb(keynode_t *node, void *event_ptr)
1604 {
1605   LoggerD("");
1606   system_info_listeners.OnCellularNetworkValueCallback(node, event_ptr);
1607 }
1608
1609 void OnPeripheralChangedCb(keynode_t* node, void* event_ptr)
1610 {
1611   LoggerD("");
1612   system_info_listeners.OnPeripheralChangedCallback(node, event_ptr);
1613 }
1614
1615 void OnMemoryChangedCb(keynode_t* node, void* event_ptr)
1616 {
1617   LoggerD("");
1618   system_info_listeners.OnMemoryChangedCallback(node, event_ptr);
1619 }
1620
1621 void OnBrightnessChangedCb(device_callback_e type, void* value, void* user_data)
1622 {
1623   LoggerD("");
1624   if (type == DEVICE_CALLBACK_FLASH_BRIGHTNESS) {
1625     system_info_listeners.OnBrightnessChangedCallback(type, value, user_data);
1626   }
1627 }
1628
1629 void OnWifiLevelChangedCb (wifi_rssi_level_e rssi_level, void *user_data)
1630 {
1631   LoggerD("Entered");
1632   LoggerD("Level %d", rssi_level);
1633   system_info_listeners.SetWifiLevel(rssi_level);
1634 }
1635
1636 /////////////////////////// SysteminfoUtils ////////////////////////////////
1637
1638 PlatformResult SystemInfoDeviceCapability::GetValueBool(const char *key, bool* value) {
1639   bool platform_result = false;
1640   int ret = system_info_get_platform_bool(key, &platform_result);
1641   if (SYSTEM_INFO_ERROR_NONE != ret) {
1642     ret = system_info_get_custom_bool(key, &platform_result);
1643     if (SYSTEM_INFO_ERROR_NONE != ret) {
1644       std::string log_msg = "Platform error while getting bool value: ";
1645       log_msg += std::string(key) + " " + std::to_string(ret);
1646       LoggerE("%s", log_msg.c_str());
1647       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
1648     }
1649   }
1650
1651   *value = platform_result;
1652   LoggerD("value[%s]: %s", key, value ? "true" : "false");
1653   return PlatformResult(ErrorCode::NO_ERROR);
1654 }
1655
1656 PlatformResult SystemInfoDeviceCapability::GetValueInt(const char *key, int* value) {
1657   int platform_result = 0;
1658   int ret = system_info_get_platform_int(key, &platform_result);
1659   if (SYSTEM_INFO_ERROR_NONE != ret) {
1660     ret = system_info_get_custom_int(key, &platform_result);
1661     if (SYSTEM_INFO_ERROR_NONE != ret) {
1662       std::string log_msg = "Platform error while getting int value: ";
1663       log_msg += std::string(key) + " " + std::to_string(ret);
1664       LoggerE("%s", log_msg.c_str());
1665       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
1666     }
1667   }
1668
1669   *value = platform_result;
1670   LoggerD("value[%s]: %d", key, value);
1671   return PlatformResult(ErrorCode::NO_ERROR);
1672 }
1673
1674 PlatformResult SystemInfoDeviceCapability::GetValueString(const char *key, std::string* str_value) {
1675   char* value = nullptr;
1676
1677   int ret = system_info_get_platform_string(key, &value);
1678   if (SYSTEM_INFO_ERROR_NONE != ret) {
1679     ret = system_info_get_custom_string(key, &value);
1680     if (SYSTEM_INFO_ERROR_NONE != ret) {
1681       std::string log_msg = "Platform error while getting string value: ";
1682       log_msg += std::string(key) + " " + std::to_string(ret);
1683       LoggerE("%s", log_msg.c_str());
1684       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
1685     }
1686   }
1687
1688   if (value != nullptr) {
1689     *str_value = value;
1690     free(value);
1691     value = nullptr;
1692   }
1693
1694   LoggerD("value[%s]: %s", key, str_value->c_str());
1695   return PlatformResult(ErrorCode::NO_ERROR);
1696 }
1697
1698 static PlatformResult GetRuntimeInfoString(system_settings_key_e key, std::string& platform_string) {
1699   char* platform_c_string;
1700   int err = system_settings_get_value_string(key, &platform_c_string);
1701   if (SYSTEM_SETTINGS_ERROR_NONE == err) {
1702     if (nullptr != platform_c_string) {
1703       platform_string = platform_c_string;
1704       free(platform_c_string);
1705       return PlatformResult(ErrorCode::NO_ERROR);
1706     }
1707   }
1708   const std::string error_msg = "Error when retrieving system setting information: "
1709       + std::to_string(err);
1710   LoggerE("%s", error_msg.c_str());
1711   return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
1712 }
1713
1714 PlatformResult GetVconfInt(const char *key, int &value) {
1715   if (0 == vconf_get_int(key, &value)) {
1716     LoggerD("value[%s]: %d", key, value);
1717     return PlatformResult(ErrorCode::NO_ERROR);
1718   }
1719   const std::string error_msg = "Could not get " + std::string(key);
1720   LoggerD("%s",error_msg.c_str());
1721   return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
1722 }
1723
1724 PlatformResult SysteminfoUtils::GetTotalMemory(long long& result)
1725 {
1726   LoggerD("Entered");
1727
1728   unsigned int value = 0;
1729
1730   int ret = device_memory_get_total(&value);
1731   if (ret != DEVICE_ERROR_NONE) {
1732     std::string log_msg = "Failed to get total memory: " + std::to_string(ret);
1733     LoggerE("%s", log_msg.c_str());
1734     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
1735   }
1736
1737   result = static_cast<long long>(value*MEMORY_TO_BYTE);
1738   return PlatformResult(ErrorCode::NO_ERROR);
1739 }
1740
1741 PlatformResult SysteminfoUtils::GetAvailableMemory(long long& result)
1742 {
1743   LoggerD("Entered");
1744
1745   unsigned int value = 0;
1746
1747   int ret = device_memory_get_available(&value);
1748   if (ret != DEVICE_ERROR_NONE) {
1749     std::string log_msg = "Failed to get total memory: " + std::to_string(ret);
1750     LoggerE("%s", log_msg.c_str());
1751     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
1752   }
1753
1754   result = static_cast<long long>(value*MEMORY_TO_BYTE);
1755   return PlatformResult(ErrorCode::NO_ERROR);
1756 }
1757
1758 PlatformResult SysteminfoUtils::GetCount(const std::string& property, unsigned long& count)
1759 {
1760   LoggerD("Enter");
1761
1762   if ("BATTERY" == property || "CPU" == property || "STORAGE" == property ||
1763       "DISPLAY" == property || "DEVICE_ORIENTATION" == property ||
1764       "BUILD" == property || "LOCALE" == property || "NETWORK" == property ||
1765       "WIFI_NETWORK" == property || "PERIPHERAL" == property ||
1766       "MEMORY" == property) {
1767     count = kDefaultPropertyCount;
1768   } else if ("CELLULAR_NETWORK" == property) {
1769     PlatformResult ret = CheckTelephonySupport();
1770     if (ret.IsError()) {
1771       count = 0;
1772     } else {
1773       count = sim_mgr.GetSimCount(system_info_listeners.GetTapiHandles());
1774     }
1775   } else if ("SIM" == property) {
1776     PlatformResult ret = CheckTelephonySupport();
1777     if (ret.IsError()) {
1778       count = 0;
1779     } else {
1780       count = sim_mgr.GetSimCount(system_info_listeners.GetTapiHandles());
1781     }
1782   } else if ("CAMERA_FLASH" == property) {
1783     count = system_info_listeners.GetCameraTypesCount();
1784   } else if ("ETHERNET_NETWORK" == property) {
1785     PlatformResult ret = CheckIfEthernetNetworkSupported();
1786     if (ret.IsError()) count = 0;
1787     else count = kDefaultPropertyCount;
1788   } else {
1789     LoggerD("Property with given id is not supported");
1790     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Property with given id is not supported");
1791   }
1792   return PlatformResult(ErrorCode::NO_ERROR);
1793 }
1794
1795 PlatformResult SysteminfoUtils::ReportProperty(const std::string& property, int index,
1796                                                picojson::object& res_obj) {
1797   if ("BATTERY" == property){
1798     return ReportBattery(res_obj);
1799   } else if ("CPU" == property) {
1800     return ReportCpu(res_obj);
1801   } else if ("STORAGE" == property) {
1802     return ReportStorage(res_obj);
1803   } else if ("DISPLAY" == property) {
1804     return ReportDisplay(res_obj);
1805   } else if ("DEVICE_ORIENTATION" == property) {
1806     return ReportDeviceOrientation(res_obj);
1807   } else if ("BUILD" == property) {
1808     return ReportBuild(res_obj);
1809   } else if ("LOCALE" == property) {
1810     return ReportLocale(res_obj);
1811   } else if ("NETWORK" == property) {
1812     return ReportNetwork(res_obj);
1813   } else if ("WIFI_NETWORK" == property) {
1814     return ReportWifiNetwork(res_obj);
1815   } else if ("ETHERNET_NETWORK" == property) {
1816     return ReportEthernetNetwork(res_obj);
1817   } else if ("CELLULAR_NETWORK" == property) {
1818     return ReportCellularNetwork(res_obj, index);
1819   } else if ("SIM" == property) {
1820     return ReportSim(res_obj, index);
1821   } else if ("PERIPHERAL" == property) {
1822     return ReportPeripheral(res_obj);
1823   } else if ("MEMORY" == property) {
1824     return ReportMemory(res_obj);
1825   } else if ("CAMERA_FLASH" == property) {
1826     return ReportCameraFlash(res_obj, index);
1827   }
1828   LoggerD("Property with given id is not supported");
1829   return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Property with given id is not supported");
1830 }
1831
1832 PlatformResult SysteminfoUtils::GetPropertyValue(const std::string& property, bool is_array_type,
1833                                                   picojson::value& res)
1834 {
1835   LoggerD("Entered getPropertyValue");
1836
1837   if (!is_array_type) {
1838     picojson::object& res_obj = res.get<picojson::object>();
1839     return ReportProperty(property, 0, res_obj);
1840   } else {
1841     picojson::object& array_result_obj = res.get<picojson::object>();
1842     picojson::array& array = array_result_obj.insert(
1843         std::make_pair("array", picojson::value(picojson::array()))).
1844             first->second.get<picojson::array>();
1845
1846     unsigned long property_count = 0;
1847     PlatformResult ret = SysteminfoUtils::GetCount(property, property_count);
1848     if (ret.IsError()){
1849       return ret;
1850     }
1851
1852     LoggerD("property name: %s", property.c_str());
1853     LoggerD("available property count: %d", property_count);
1854     for (size_t i = 0; i < property_count; i++) {
1855       picojson::value result = picojson::value(picojson::object());
1856       picojson::object& result_obj = result.get<picojson::object>();
1857
1858       ret = ReportProperty(property, i, result_obj);
1859       if (ret.IsError()){
1860         return ret;
1861       }
1862       array.push_back(result);
1863     }
1864     if (property_count == 0) {
1865       return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Property with given id is not supported");
1866     }
1867   }
1868
1869   return PlatformResult(ErrorCode::NO_ERROR);
1870 }
1871
1872 PlatformResult SysteminfoUtils::ReportBattery(picojson::object& out) {
1873   int value = 0;
1874   int ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &value);
1875   if (kVconfErrorNone != ret) {
1876     std::string log_msg = "Platform error while getting battery detail: ";
1877     LoggerE("%s%d", log_msg.c_str(), ret);
1878     return PlatformResult(ErrorCode::UNKNOWN_ERR, (log_msg + std::to_string(ret)));
1879   }
1880
1881   out.insert(std::make_pair("level", picojson::value(static_cast<double>(value)/kRemainingBatteryChargeMax)));
1882   value = 0;
1883   ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &value);
1884   if (kVconfErrorNone != ret) {
1885     std::string log_msg =  "Platform error while getting battery charging: ";
1886     LoggerE("%s%d",log_msg.c_str(), ret);
1887     return PlatformResult(ErrorCode::UNKNOWN_ERR, (log_msg + std::to_string(ret)));
1888   }
1889   out.insert(std::make_pair("isCharging", picojson::value(0 != value)));
1890   return PlatformResult(ErrorCode::NO_ERROR);
1891 }
1892 //TODO maybe make two functions later onGSourceFunc
1893 PlatformResult SysteminfoUtils::ReportCpu(picojson::object& out) {
1894   LoggerD("Entered");
1895   static CpuInfo cpu_info;
1896   FILE *fp = nullptr;
1897   fp = fopen("/proc/stat", "r");
1898   if (nullptr == fp) {
1899     std::string error_msg("Can not open /proc/stat for reading");
1900     LoggerE( "%s", error_msg.c_str() );
1901     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
1902   }
1903
1904   long long usr = 0;
1905   long long system = 0;
1906   long long nice = 0;
1907   long long idle = 0;
1908   double load = 0;
1909
1910   int read_ret = fscanf( fp, "%*s %lld %lld %lld %lld", &usr, &system, &nice, &idle);
1911   fclose(fp);
1912
1913   if (4 == read_ret) {
1914     long long total = usr + nice + system + idle - cpu_info.usr - cpu_info.nice -
1915         cpu_info.system - cpu_info.idle;
1916     long long diff_idle = idle - cpu_info.idle;
1917     if (( total > 0LL ) && ( diff_idle > 0LL )) {
1918       load = static_cast< double >( diff_idle ) * 100LL / total;
1919       cpu_info.usr = usr;
1920       cpu_info.system = system;
1921       cpu_info.nice = nice;
1922       cpu_info.idle = idle;
1923       cpu_info.load = load;
1924     } else {
1925       LoggerW("Cannot calculate cpu load, previous value returned");
1926       load = cpu_info.load;
1927     }
1928   } else {
1929     std::string error_msg( "Could not read /proc/stat" );
1930     LoggerE( "%s", error_msg.c_str() );
1931     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
1932   }
1933
1934   system_info_listeners.SetCpuInfoLoad(cpu_info.load);
1935
1936   load = 100 - load;
1937   LoggerD("Cpu load : %f", load );
1938   out.insert(std::make_pair("load", picojson::value(load / 100.0)));
1939   return PlatformResult(ErrorCode::NO_ERROR);
1940 }
1941
1942 PlatformResult SysteminfoUtils::ReportDisplay(picojson::object& out) {
1943   int screenWidth = 0;
1944   int screenHeight = 0;
1945   int dotsPerInchWidth = 0;
1946   int dotsPerInchHeight = 0;
1947   double physicalWidth = 0;
1948   double physicalHeight = 0;
1949   double scaledBrightness;
1950
1951   // FETCH RESOLUTION
1952   if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_int(
1953       "tizen.org/feature/screen.width", &screenWidth)) {
1954     LoggerE("Cannot get value of screen width");
1955     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get value of screen width");
1956   }
1957   if (SYSTEM_INFO_ERROR_NONE != system_info_get_platform_int(
1958       "tizen.org/feature/screen.height", &screenHeight)) {
1959     LoggerE("Cannot get value of screen height");
1960     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get value of screen height");
1961   }
1962
1963   //FETCH DOTS PER INCH
1964   int dots_per_inch=0;
1965   if (SYSTEM_INFO_ERROR_NONE == system_info_get_platform_int(
1966       "tizen.org/feature/screen.dpi", &dots_per_inch)) {
1967     dotsPerInchWidth = dots_per_inch;
1968     dotsPerInchHeight = dots_per_inch;
1969   } else {
1970     LoggerE("Cannot get 'tizen.org/feature/screen.dpi' value");
1971     return PlatformResult(ErrorCode::UNKNOWN_ERR,
1972                           "Cannot get 'tizen.org/feature/screen.dpi' value");
1973   }
1974
1975   //FETCH PHYSICAL WIDTH
1976   if (dotsPerInchWidth != 0 && screenWidth != 0) {
1977     physicalWidth = (screenWidth / dotsPerInchWidth) * DISPLAY_INCH_TO_MILLIMETER;
1978   } else {
1979     std::string log_msg = "Failed to get physical screen width value";
1980     LoggerE("%s, screenWidth : %d, dotsPerInchWidth: %d", log_msg.c_str(),
1981          screenWidth, dotsPerInchWidth);
1982   }
1983
1984   //FETCH PHYSICAL HEIGHT
1985   if (dotsPerInchHeight != 0 && screenHeight != 0) {
1986     physicalHeight = (screenHeight / dotsPerInchHeight) * DISPLAY_INCH_TO_MILLIMETER;
1987   } else {
1988     std::string log_msg = "Failed to get physical screen height value";
1989     LoggerE("%s, screenHeight : %d, dotsPerInchHeight: %d", log_msg.c_str(),
1990          screenHeight, dotsPerInchHeight);
1991   }
1992
1993   //FETCH BRIGHTNESS
1994   int brightness;
1995   if (kVconfErrorNone == vconf_get_int(VCONFKEY_SETAPPL_LCD_BRIGHTNESS, &brightness)) {
1996     scaledBrightness = static_cast<double>(brightness)/kDisplayBrightnessDivideValue;
1997   } else {
1998     LoggerE("Cannot get brightness value of display");
1999     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get brightness value of display");
2000   }
2001
2002   out.insert(std::make_pair("resolutionWidth", picojson::value(std::to_string(screenWidth))));
2003   out.insert(std::make_pair("resolutionHeight", picojson::value(std::to_string(screenHeight))));
2004   out.insert(std::make_pair("dotsPerInchWidth", picojson::value(std::to_string(dotsPerInchWidth))));
2005   out.insert(std::make_pair("dotsPerInchHeight", picojson::value(std::to_string(dotsPerInchHeight))));
2006   out.insert(std::make_pair("physicalWidth", picojson::value(std::to_string(physicalWidth))));
2007   out.insert(std::make_pair("physicalHeight", picojson::value(std::to_string(physicalHeight))));
2008   out.insert(std::make_pair("brightness", picojson::value(scaledBrightness)));
2009   return PlatformResult(ErrorCode::NO_ERROR);
2010 }
2011
2012 static PlatformResult FetchIsAutoRotation(bool* result)
2013 {
2014   LoggerD("Entered");
2015   int is_auto_rotation = 0;
2016
2017   if ( 0 == vconf_get_bool(
2018       VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &is_auto_rotation)) {
2019     if (is_auto_rotation) {
2020       *result = true;
2021     } else {
2022       *result = false;
2023     }
2024     return PlatformResult(ErrorCode::NO_ERROR);
2025   }
2026   else {
2027     LoggerE("VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL check failed");
2028     return PlatformResult(ErrorCode::UNKNOWN_ERR,
2029                           "VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL check failed");
2030   }
2031 }
2032
2033 static PlatformResult FetchStatus(std::string* result)
2034 {
2035   LoggerD("Entered");
2036   int rotation = 0;
2037   std::string status = kOrientationPortraitPrimary;
2038
2039   sensor_data_t data;
2040   bool ret = sensord_get_data(system_info_listeners.GetSensorHandle(),
2041                              AUTO_ROTATION_BASE_DATA_SET, &data);
2042   if (ret) {
2043     LoggerD("size of the data value array:%d", data.value_count);
2044     if (data.value_count > 0 ) {
2045       rotation = data.values[0];
2046       LoggerD("rotation is: %d", rotation);
2047     } else {
2048       LoggerE("Failed to get data : the size of array is 0. Default rotation would be returned.");
2049     }
2050   } else {
2051     LoggerE("Failed to get data(sensord_get_data). Default rotation would be returned.");
2052   }
2053
2054
2055   switch (rotation) {
2056     case AUTO_ROTATION_DEGREE_UNKNOWN:
2057     case AUTO_ROTATION_DEGREE_0:
2058       LoggerD("AUTO_ROTATION_DEGREE_0");
2059       status = kOrientationPortraitPrimary;
2060       break;
2061     case AUTO_ROTATION_DEGREE_90:
2062       LoggerD("AUTO_ROTATION_DEGREE_90");
2063       status = kOrientationLandscapePrimary;
2064       break;
2065     case AUTO_ROTATION_DEGREE_180:
2066       LoggerD("AUTO_ROTATION_DEGREE_180");
2067       status = kOrientationPortraitSecondary;
2068       break;
2069     case AUTO_ROTATION_DEGREE_270:
2070       LoggerD("AUTO_ROTATION_DEGREE_270");
2071       status = kOrientationLandscapeSecondary;
2072       break;
2073     default:
2074       LoggerE("Received unexpected data: %u", rotation);
2075       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Received unexpected data");
2076   }
2077   *result = status;
2078   return PlatformResult(ErrorCode::NO_ERROR);
2079 }
2080
2081 PlatformResult SysteminfoUtils::ReportDeviceOrientation(picojson::object& out) {
2082   bool is_auto_rotation = false;
2083   std::string status = "";
2084
2085   PlatformResult ret = FetchIsAutoRotation(&is_auto_rotation);
2086   if (ret.IsError()) return ret;
2087
2088   ret = FetchStatus(&status);
2089   if (ret.IsError()) return ret;
2090
2091   out.insert(std::make_pair("isAutoRotation", picojson::value(is_auto_rotation)));
2092   out.insert(std::make_pair("status", picojson::value(status)));
2093   return PlatformResult(ErrorCode::NO_ERROR);
2094 }
2095
2096 PlatformResult SysteminfoUtils::ReportBuild(picojson::object& out) {
2097   std::string model = "";
2098   PlatformResult ret = SystemInfoDeviceCapability::GetValueString(
2099       "tizen.org/system/model_name", &model);
2100   if (ret.IsError()) {
2101     return ret;
2102   }
2103   std::string manufacturer = "";
2104   ret = SystemInfoDeviceCapability::GetValueString(
2105       "tizen.org/system/manufacturer", &manufacturer);
2106   if (ret.IsError()) {
2107     return ret;
2108   }
2109   std::string buildVersion = "";
2110   ret = SystemInfoDeviceCapability::GetValueString(
2111       "tizen.org/system/build.string", &buildVersion);
2112   if (ret.IsError()) {
2113     return ret;
2114   }
2115
2116   out.insert(std::make_pair("model", picojson::value(model)));
2117   out.insert(std::make_pair("manufacturer", picojson::value(manufacturer)));
2118   out.insert(std::make_pair("buildVersion", picojson::value(buildVersion)));
2119   return PlatformResult(ErrorCode::NO_ERROR);
2120 }
2121
2122 PlatformResult SysteminfoUtils::ReportLocale(picojson::object& out) {
2123   std::string str_language = "";
2124   PlatformResult ret = GetRuntimeInfoString(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE, str_language);
2125   if (ret.IsError()) {
2126     return ret;
2127   }
2128
2129   std::string str_country = "";
2130   ret = GetRuntimeInfoString(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, str_country);
2131   if (ret.IsError()) {
2132     return ret;
2133   }
2134
2135   out.insert(std::make_pair("language", picojson::value(str_language)));
2136   out.insert(std::make_pair("country", picojson::value(str_country)));
2137   return PlatformResult(ErrorCode::NO_ERROR);
2138 }
2139
2140 static PlatformResult GetNetworkTypeString(NetworkType type, std::string& type_string)
2141 {
2142   switch (type) {
2143     case kNone:
2144       type_string = kNetworkTypeNone;
2145       break;
2146     case kType2G:
2147       type_string = kNetworkType2G;
2148       break;
2149     case kType2_5G:
2150       type_string = kNetworkType2_5G;
2151       break;
2152     case kType3G:
2153       type_string = kNetworkType3G;
2154       break;
2155     case kType4G:
2156       type_string = kNetworkType4G;
2157       break;
2158     case kWifi:
2159       type_string = kNetworkTypeWifi;
2160       break;
2161     case kEthernet:
2162       type_string = kNetworkTypeEthernet;
2163       break;
2164     case kUnknown:
2165       type_string = kNetworkTypeUnknown;
2166       break;
2167     default:
2168       LoggerE("Incorrect type: %d", type);
2169       return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Incorrect type");
2170   }
2171   return PlatformResult(ErrorCode::NO_ERROR);
2172 }
2173
2174 PlatformResult SysteminfoUtils::ReportNetwork(picojson::object& out) {
2175   connection_h connection_handle = nullptr;
2176   connection_type_e connection_type = CONNECTION_TYPE_DISCONNECTED;
2177   int networkType = 0;
2178   NetworkType type = kNone;
2179
2180   //connection must be created in every call, in other case error occurs
2181   int error = connection_create(&connection_handle);
2182   if (CONNECTION_ERROR_NONE != error) {
2183     std::string log_msg = "Cannot create connection: " + std::to_string(error);
2184     LoggerE("%s", log_msg.c_str());
2185     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2186   }
2187   std::unique_ptr<std::remove_pointer<connection_h>::type, int(*)(connection_h)>
2188   connection_handle_ptr(connection_handle, &connection_destroy);
2189   // automatically release the memory
2190
2191   error = connection_get_type(connection_handle, &connection_type);
2192   if (CONNECTION_ERROR_NONE != error) {
2193     std::string log_msg = "Cannot get connection type: " + std::to_string(error);
2194     LoggerE("%s", log_msg.c_str());
2195     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2196   }
2197
2198   switch (connection_type) {
2199     case CONNECTION_TYPE_DISCONNECTED :
2200       type = kNone;
2201       break;
2202     case CONNECTION_TYPE_WIFI :
2203       type =  kWifi;
2204       break;
2205     case CONNECTION_TYPE_CELLULAR :
2206       if (vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &networkType) == 0) {
2207         if (networkType < VCONFKEY_TELEPHONY_SVCTYPE_2G) {
2208           type =  kNone;
2209         } else if (networkType == VCONFKEY_TELEPHONY_SVCTYPE_2G) {
2210           type =  kType2G;
2211         } else if (networkType == VCONFKEY_TELEPHONY_SVCTYPE_2G
2212             || networkType == VCONFKEY_TELEPHONY_SVCTYPE_2_5G_EDGE) {
2213           type =  kType2_5G;
2214         } else if (networkType == VCONFKEY_TELEPHONY_SVCTYPE_3G
2215             || networkType == VCONFKEY_TELEPHONY_SVCTYPE_HSDPA) {
2216           type =  kType3G;
2217         } else if (networkType == VCONFKEY_TELEPHONY_SVCTYPE_LTE) {
2218           type =  kType4G;
2219         } else {
2220           type =  kNone;
2221         }
2222       }
2223       break;
2224     case CONNECTION_TYPE_ETHERNET :
2225       type =  kEthernet;
2226       break;
2227     default:
2228       LoggerE("Incorrect type: %d", connection_type);
2229       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Incorrect type");
2230   }
2231   std::string type_str = "";
2232   PlatformResult ret = GetNetworkTypeString(type, type_str);
2233   if(ret.IsError()) {
2234     return ret;
2235   }
2236   out.insert(std::make_pair("networkType", picojson::value(type_str)));
2237   return PlatformResult(ErrorCode::NO_ERROR);
2238 }
2239
2240 static PlatformResult GetIps(wifi_ap_h wifi_ap_handle, std::string* ip_addr_str,
2241                    std::string* ipv6_addr_str){
2242   //getting ipv4 address
2243   char* ip_addr = nullptr;
2244   int error = wifi_ap_get_ip_address(wifi_ap_handle,
2245                                      WIFI_ADDRESS_FAMILY_IPV4,
2246                                      &ip_addr);
2247   if (WIFI_ERROR_NONE != error) {
2248     LoggerE("Failed to get ip address: %d", error);
2249     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get ip address");
2250   }
2251   *ip_addr_str = ip_addr;
2252   free(ip_addr);
2253
2254   //getting ipv6 address
2255   ip_addr = nullptr;
2256   error = wifi_ap_get_ip_address(wifi_ap_handle,
2257                                  WIFI_ADDRESS_FAMILY_IPV6,
2258                                  &ip_addr);
2259   if (WIFI_ERROR_NONE != error) {
2260     LoggerE("Failed to get ipv6 address: %d", error);
2261     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get ipv6 address");
2262   }
2263   *ipv6_addr_str = ip_addr;
2264   free(ip_addr);
2265   return PlatformResult(ErrorCode::NO_ERROR);
2266 }
2267
2268 PlatformResult SysteminfoUtils::ReportWifiNetwork(picojson::object& out) {
2269   LoggerD("Entered");
2270
2271   bool result_status = false;
2272   std::string result_ssid;
2273   std::string result_ip_address;
2274   std::string result_ipv6_address;
2275   std::string result_mac_address;
2276   double result_signal_strength = 0;
2277
2278   // wifi_initialize() must be called in each thread
2279   int error = wifi_initialize();
2280   if (WIFI_ERROR_NONE != error) {
2281     std::string log_msg = "Initialize failed: " + parseWifiNetworkError(error);
2282     LoggerE("%s", log_msg.c_str());
2283     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2284   } else {
2285     LoggerD("WIFI initializatino succeed");
2286   }
2287   SCOPE_EXIT {
2288     wifi_deinitialize();
2289   };
2290
2291   wifi_ap_h wifi_ap_handle = nullptr;
2292   error = wifi_get_connected_ap(&wifi_ap_handle);
2293   if (WIFI_ERROR_NONE != error) {
2294     LoggerD("Error while wifi_get_connnected_ap: %s", parseWifiNetworkError(error).c_str());
2295     // in case of no connection, ignore error and leave status as false
2296     if (WIFI_ERROR_NO_CONNECTION != error) {
2297       std::string log_msg = "Cannot get connected access point handle: " + parseWifiNetworkError(error);
2298       LoggerE("%s", log_msg.c_str());
2299       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2300     }
2301   } else {
2302     //if getting connected AP succeed, set status on true
2303     result_status = true;
2304   }
2305
2306   if (result_status) {
2307     std::unique_ptr<std::remove_pointer<wifi_ap_h>::type, int(*)(wifi_ap_h)>
2308     wifi_ap_handle_ptr(wifi_ap_handle, &wifi_ap_destroy);
2309     // automatically release the memory
2310
2311     //gathering mac address
2312     char* mac = nullptr;
2313     error = wifi_get_mac_address(&mac);
2314     if (WIFI_ERROR_NONE == error && nullptr != mac) {
2315       SLoggerD("MAC address fetched: %s", mac);
2316       result_mac_address = mac;
2317       free(mac);
2318     } else {
2319       std::string log_msg = "Failed to get mac address: " + parseWifiNetworkError(error);
2320       LoggerE("%s", log_msg.c_str());
2321       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2322     }
2323
2324     //refreshing access point information
2325     error = wifi_ap_refresh(wifi_ap_handle);
2326     if (WIFI_ERROR_NONE != error) {
2327       std::string log_msg = "Failed to refresh access point information: " + parseWifiNetworkError(error);
2328       LoggerE("%s", log_msg.c_str());
2329       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2330     }
2331
2332     //gathering ssid
2333     char* essid = nullptr;
2334     error = wifi_ap_get_essid(wifi_ap_handle, &essid);
2335     if (WIFI_ERROR_NONE == error) {
2336       result_ssid = essid;
2337       free(essid);
2338     } else {
2339       std::string log_msg = "Failed to get network ssid: " + parseWifiNetworkError(error);
2340       LoggerE("%s", log_msg.c_str());
2341       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2342     }
2343
2344     //gathering ips
2345     PlatformResult ret = GetIps(wifi_ap_handle, &result_ip_address, &result_ipv6_address);
2346     if (ret.IsError()) {
2347       return ret;
2348     }
2349
2350     //gathering strength
2351     wifi_rssi_level_e rssi_level = system_info_listeners.GetWifiLevel();
2352     // this mean that level was not initialized or wifi not connected
2353     if (WIFI_RSSI_LEVEL_0 == rssi_level) {
2354       // so try to gather rssi level with dedicated function
2355       int rssi = 0;
2356       error = wifi_ap_get_rssi(wifi_ap_handle, &rssi);
2357       if (WIFI_ERROR_NONE == error) {
2358         result_signal_strength = ((double) abs(rssi))/kWifiSignalStrengthDivideValue;
2359       } else {
2360         std::string log_msg = "Failed to get signal strength: " + parseWifiNetworkError(error);
2361         LoggerE("%s", log_msg.c_str());
2362         return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2363       }
2364     } else {
2365       result_signal_strength = ((double) rssi_level)/WIFI_RSSI_LEVEL_4;
2366     }
2367   }
2368   //building result object
2369   out.insert(std::make_pair("status", picojson::value(result_status ? kWifiStatusOn : kWifiStatusOff)));
2370   out.insert(std::make_pair("ssid", picojson::value(result_ssid)));
2371   out.insert(std::make_pair("ipAddress", picojson::value(result_ip_address)));
2372   out.insert(std::make_pair("ipv6Address", picojson::value(result_ipv6_address)));
2373   out.insert(std::make_pair("macAddress", picojson::value(result_mac_address)));
2374   out.insert(std::make_pair("signalStrength", picojson::value(std::to_string(result_signal_strength))));
2375
2376   return PlatformResult(ErrorCode::NO_ERROR);
2377 }
2378
2379 PlatformResult SysteminfoUtils::ReportEthernetNetwork(picojson::object& out) {
2380   LoggerD("Entered");
2381
2382   std::string result_cable;
2383   std::string result_status;
2384   std::string result_ip_address;
2385   std::string result_ipv6_address;
2386   std::string result_mac_address;
2387
2388   connection_h connection_handle = nullptr;
2389   connection_ethernet_state_e connection_state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
2390   connection_type_e connection_type = CONNECTION_TYPE_DISCONNECTED;
2391   connection_profile_h profile_handle = nullptr;
2392
2393   // connection must be created in every call, in other case error occurs
2394   int error = connection_create(&connection_handle);
2395   if (CONNECTION_ERROR_NONE != error) {
2396     std::string log_msg = "Cannot create connection: " + std::to_string(error);
2397     LoggerE("%s", log_msg.c_str());
2398     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2399   }
2400   std::unique_ptr<std::remove_pointer<connection_h>::type, int (*)(connection_h)> connection_handle_ptr(
2401       connection_handle, &connection_destroy);  // automatically release the memory
2402
2403   error = connection_get_ethernet_state(connection_handle, &connection_state);
2404   if (CONNECTION_ERROR_NONE != error) {
2405     if (CONNECTION_ERROR_NOT_SUPPORTED == error) {
2406       std::string log_msg = "Cannot get ethernet connection state: Not supported";
2407       LoggerE("%s", log_msg.c_str());
2408       return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, log_msg);
2409     }
2410     std::string log_msg = "Cannot get ethernet connection state: " + std::to_string(error);
2411     LoggerE("%s", log_msg.c_str());
2412     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2413   }
2414
2415   switch (connection_state) {
2416     case CONNECTION_ETHERNET_STATE_DEACTIVATED:
2417       result_status = "DEACTIVATED";
2418       break;
2419
2420     case CONNECTION_ETHERNET_STATE_DISCONNECTED:
2421       result_status = "DISCONNECTED";
2422       break;
2423
2424     case CONNECTION_ETHERNET_STATE_CONNECTED:
2425       result_status = "CONNECTED";
2426       break;
2427
2428     default:
2429       result_status = "UNKNOWN";
2430       break;
2431   }
2432
2433   connection_ethernet_cable_state_e cable_state = CONNECTION_ETHERNET_CABLE_DETACHED;
2434   error = connection_get_ethernet_cable_state(connection_handle, &cable_state);
2435   if (CONNECTION_ERROR_NONE != error) {
2436     std::string log_msg = "Cannot get ethernet cable state: " + std::to_string(error);
2437     LoggerE("%s", log_msg.c_str());
2438     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2439   }
2440
2441   switch (cable_state) {
2442     case CONNECTION_ETHERNET_CABLE_DETACHED:
2443       result_cable = "DETACHED";
2444       break;
2445
2446     case CONNECTION_ETHERNET_CABLE_ATTACHED:
2447       result_cable = "ATTACHED";
2448       break;
2449
2450     default:
2451       result_cable = "UNKNOWN";
2452       break;
2453   }
2454
2455   char* mac = nullptr;
2456   error = connection_get_mac_address(connection_handle, CONNECTION_TYPE_ETHERNET, &mac);
2457   if (CONNECTION_ERROR_NONE == error && nullptr != mac) {
2458     SLoggerD("MAC address fetched: %s", mac);
2459     result_mac_address = mac;
2460     free(mac);
2461   } else {
2462     std::string log_msg = "Failed to get mac address: " + std::to_string(error);
2463     LoggerE("%s", log_msg.c_str());
2464     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2465   }
2466
2467   error = connection_get_type(connection_handle, &connection_type);
2468   if (CONNECTION_ERROR_NONE != error) {
2469     std::string log_msg = "Cannot get connection type: " + std::to_string(error);
2470     LoggerE("%s", log_msg.c_str());
2471     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2472   }
2473
2474   if (CONNECTION_TYPE_ETHERNET == connection_type) {
2475     //gathering profile
2476     error = connection_get_current_profile(connection_handle, &profile_handle);
2477     if (CONNECTION_ERROR_NONE != error) {
2478       std::string log_msg = "Cannot get connection profile: " + std::to_string(error);
2479       LoggerE("%s", log_msg.c_str());
2480       return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2481     }
2482     std::unique_ptr<std::remove_pointer<connection_profile_h>::type,
2483         int (*)(connection_profile_h)> profile_handle_ptr(
2484         profile_handle, &connection_profile_destroy); // automatically release the memory
2485
2486     //gathering ips
2487     PlatformResult ret = GetIps(profile_handle, &result_ip_address, &result_ipv6_address);
2488     if (ret.IsError()) {
2489       return ret;
2490     }
2491   } else {
2492     LoggerD("Connection type = %d. ETHERNET is disabled", connection_type);
2493   }
2494
2495   out.insert(std::make_pair("cable", picojson::value(result_cable)));
2496   out.insert(std::make_pair("status", picojson::value(result_status)));
2497   out.insert(std::make_pair("ipAddress", picojson::value(result_ip_address)));
2498   out.insert(std::make_pair("ipv6Address", picojson::value(result_ipv6_address)));
2499   out.insert(std::make_pair("macAddress", picojson::value(result_mac_address)));
2500
2501   return PlatformResult(ErrorCode::NO_ERROR);
2502 }
2503
2504 static PlatformResult FetchBasicSimProperties(TapiHandle *tapi_handle,
2505     unsigned short *result_mcc,
2506     unsigned short *result_mnc,
2507     unsigned short *result_cell_id,
2508     unsigned short *result_lac,
2509     bool *result_is_roaming,
2510     bool *result_is_flight_mode)
2511 {
2512   LoggerD("Entered");
2513   int result_value = 0;
2514   int tapi_res = TAPI_API_SUCCESS;
2515   tapi_res = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_PLMN, &result_value);
2516   if (TAPI_API_SUCCESS != tapi_res) {
2517     std::string error_msg = "Cannot get mcc value, error: " + std::to_string(tapi_res);
2518     LoggerE("%s", error_msg.c_str());
2519     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
2520   }
2521   *result_mcc = static_cast<unsigned short>(result_value) / kMccDivider;
2522   *result_mnc = static_cast<unsigned short>(result_value) % kMccDivider;
2523
2524   tapi_res = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_CELLID, &result_value);
2525   if (TAPI_API_SUCCESS != tapi_res) {
2526     std::string error_msg = "Cannot get cell_id value, error: " + std::to_string(tapi_res);
2527     LoggerE("%s", error_msg.c_str());
2528     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
2529   }
2530   *result_cell_id = static_cast<unsigned short>(result_value);
2531
2532   tapi_res = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_LAC, &result_value);
2533   if (TAPI_API_SUCCESS != tapi_res) {
2534     std::string error_msg = "Cannot get lac value, error: " + std::to_string(tapi_res);
2535     LoggerE("%s", error_msg.c_str());
2536     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
2537   }
2538   *result_lac = static_cast<unsigned short>(result_value);
2539
2540   tapi_res = tel_get_property_int(tapi_handle, TAPI_PROP_NETWORK_ROAMING_STATUS, &result_value);
2541   if (TAPI_API_SUCCESS != tapi_res) {
2542     std::string error_msg = "Cannot get is_roaming value, error: " + std::to_string(tapi_res);
2543     LoggerE("%s", error_msg.c_str());
2544     return PlatformResult(ErrorCode::UNKNOWN_ERR, error_msg);
2545   }
2546   *result_is_roaming = (0 != result_value) ? true : false;
2547
2548   if (0 != vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &result_value)) {
2549     LoggerE("Cannot get is_flight_mode value");
2550     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get is_flight_mode value");
2551   }
2552   *result_is_flight_mode = (0 != result_value) ? true : false;
2553   return PlatformResult(ErrorCode::NO_ERROR);
2554 }
2555
2556 static PlatformResult FetchConnection(TapiHandle *tapi_handle, std::string* result_status,
2557                             std::string* result_apn, std::string* result_ip_address,
2558                             std::string* result_ipv6_address, std::string* result_imei)
2559 {
2560   LoggerD("Entered");
2561   connection_type_e connection_type = CONNECTION_TYPE_DISCONNECTED;
2562   connection_profile_h profile_handle = nullptr;
2563   connection_h connection_handle = nullptr;
2564
2565   //connection must be created in every call, in other case error occurs
2566   int error = connection_create(&connection_handle);
2567   if (CONNECTION_ERROR_NONE != error) {
2568     std::string log_msg = "Cannot create connection: " + std::to_string(error);
2569     LoggerE("%s", log_msg.c_str());
2570     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
2571   }
2572   std::unique_ptr<std::remove_pointer<connection_h>::type, int(*)(connection_h)>
2573   connection_handle_ptr(connection_handle, &connection_destroy);
2574   // automatically release the memory
2575
2576   error = connection_get_type(connection_handle, &connection_type);
2577   if (CONNECTION_ERROR_NONE != error) {
2578     LoggerE("Failed to get connection type: %d", error);
2579     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get connection type");
2580   }
2581
2582   char* apn = nullptr;
2583   if (CONNECTION_TYPE_CELLULAR == connection_type) {
2584     *result_status = kConnectionOn;
2585
2586     error = connection_get_current_profile(connection_handle,
2587                                            &profile_handle);
2588     std::unique_ptr
2589     <std::remove_pointer<connection_profile_h>::type, int(*)(connection_profile_h)>
2590     profile_handle_ptr(profile_handle, &connection_profile_destroy);
2591     // automatically release the memory
2592     if (CONNECTION_ERROR_NONE != error) {
2593       LoggerE("Failed to get profile: %d", error);
2594       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get profile");
2595     }
2596
2597     error = connection_profile_get_cellular_apn(profile_handle, &apn);
2598     if (CONNECTION_ERROR_NONE != error) {
2599       LoggerE("Failed to get apn name: %d", error);
2600       return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get apn name");
2601     }
2602     *result_apn = apn;
2603     free(apn);
2604
2605     PlatformResult ret = GetIps(profile_handle, result_ip_address, result_ipv6_address);
2606     if (ret.IsError()) {
2607       return ret;
2608     }
2609   } else {
2610     *result_status = kConnectionOff;
2611
2612     //According to previous implementation in case of error
2613     //don't throw exception here
2614     error = connection_get_default_cellular_service_profile(
2615         connection_handle,
2616         CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET,
2617         &profile_handle);
2618     std::unique_ptr
2619     <std::remove_pointer<connection_profile_h>::type, int(*)(connection_profile_h)>
2620     profile_handle_ptr(profile_handle, &connection_profile_destroy);
2621     // automatically release the memory
2622     if (CONNECTION_ERROR_NONE == error) {
2623       error = connection_profile_get_cellular_apn(profile_handle, &apn);
2624       if (CONNECTION_ERROR_NONE == error) {
2625         *result_apn = apn;
2626         free(apn);
2627       } else {
2628         LoggerE("Failed to get default apn name: %d. Failing silently",
2629              error);
2630       }
2631     } else {
2632       LoggerE("Failed to get default profile: %d. Failing silently",
2633            error);
2634     }
2635   }
2636
2637   char* imei = nullptr;
2638   imei = tel_get_misc_me_imei_sync(tapi_handle);
2639   if (nullptr != imei) {
2640     *result_imei = imei;
2641     free(imei);
2642   } else {
2643     LoggerE("Failed to get imei, nullptr pointer. Setting empty value.");
2644     *result_imei = "";
2645   }
2646   return PlatformResult(ErrorCode::NO_ERROR);
2647 }
2648
2649 PlatformResult SysteminfoUtils::ReportCellularNetwork(picojson::object& out, unsigned long count) {
2650   PlatformResult ret = CheckTelephonySupport();
2651   if (ret.IsError()) {
2652     return ret;
2653   }
2654   std::string result_status;
2655   std::string result_apn;
2656   std::string result_ip_address;
2657   std::string result_ipv6_address;
2658   unsigned short result_mcc;
2659   unsigned short result_mnc;
2660   unsigned short result_cell_id;
2661   unsigned short result_lac;
2662   bool result_is_roaming;
2663   bool result_is_flight_mode;
2664   std::string result_imei;
2665
2666   //gathering vconf-based values
2667   ret = FetchBasicSimProperties(system_info_listeners.GetTapiHandles()[count], &result_mcc,
2668                            &result_mnc, &result_cell_id, &result_lac,
2669                            &result_is_roaming, &result_is_flight_mode);
2670   if (ret.IsError()) {
2671     return ret;
2672   }
2673   //gathering connection informations
2674   ret = FetchConnection(system_info_listeners.GetTapiHandles()[count],
2675                   &result_status, &result_apn, &result_ip_address, &result_ipv6_address, &result_imei);
2676   if (ret.IsError()) {
2677     return ret;
2678   }
2679
2680   out.insert(std::make_pair("status", picojson::value(result_status)));
2681   out.insert(std::make_pair("apn", picojson::value(result_apn)));
2682   out.insert(std::make_pair("ipAddress", picojson::value(result_ip_address)));
2683   out.insert(std::make_pair("ipv6Address", picojson::value(result_ipv6_address)));
2684   out.insert(std::make_pair("mcc", picojson::value(std::to_string(result_mcc))));
2685   out.insert(std::make_pair("mnc", picojson::value(std::to_string(result_mnc))));
2686   out.insert(std::make_pair("cellId", picojson::value(std::to_string(result_cell_id))));
2687   out.insert(std::make_pair("lac", picojson::value(std::to_string(result_lac))));
2688   out.insert(std::make_pair("isRoaming", picojson::value(result_is_roaming)));
2689   out.insert(std::make_pair("isFligthMode", picojson::value(result_is_flight_mode)));
2690   out.insert(std::make_pair("imei", picojson::value(result_imei)));
2691   return PlatformResult(ErrorCode::NO_ERROR);
2692 }
2693
2694 void SimCphsValueCallback(TapiHandle */*handle*/, int result, void *data, void */*user_data*/)
2695 {
2696   LoggerD("Entered");
2697   TelSimAccessResult_t access_rt = static_cast<TelSimAccessResult_t>(result);
2698   TelSimCphsNetName_t *cphs_info = static_cast<TelSimCphsNetName_t*>(data);
2699
2700   std::string result_operator;
2701   if (TAPI_SIM_ACCESS_SUCCESS == access_rt) {
2702     std::stringstream s;
2703     s << cphs_info->full_name;
2704     if (s.str().empty()) {
2705       s << cphs_info->short_name;
2706     }
2707     result_operator = s.str();
2708   } else {
2709     LoggerW("Failed to retrieve cphs_info: %d", access_rt);
2710   }
2711   sim_mgr.set_operator_name(result_operator);
2712   sim_mgr.TryReturn();
2713 }
2714
2715 void SimMsisdnValueCallback(TapiHandle */*handle*/, int result, void *data, void */*user_data*/)
2716 {
2717   LoggerD("Entered");
2718   TelSimAccessResult_t access_rt = static_cast<TelSimAccessResult_t>(result);
2719   TelSimMsisdnList_t *msisdn_info = static_cast<TelSimMsisdnList_t*>(data);
2720
2721   std::string result_msisdn;
2722   if (TAPI_SIM_ACCESS_SUCCESS == access_rt) {
2723     if (msisdn_info->count > 0) {
2724       if (strlen(msisdn_info->list[0].num) > 0) {
2725         result_msisdn = msisdn_info->list[0].num;
2726       } else {
2727         LoggerW("MSISDN number empty");
2728       }
2729     } else {
2730       LoggerW("msisdn_info list empty");
2731     }
2732   } else {
2733     LoggerW("Failed to retrieve msisdn_: %d", access_rt);
2734   }
2735
2736   sim_mgr.set_msisdn(result_msisdn);
2737   sim_mgr.TryReturn();
2738 }
2739
2740 void SimSpnValueCallback(TapiHandle */*handle*/, int result, void *data, void */*user_data*/)
2741 {
2742   LoggerD("Entered");
2743   TelSimAccessResult_t access_rt = static_cast<TelSimAccessResult_t>(result);
2744   TelSimSpn_t *spn_info = static_cast<TelSimSpn_t*>(data);
2745
2746   std::string result_spn;
2747   if (TAPI_SIM_ACCESS_SUCCESS == access_rt) {
2748     result_spn = (char *)spn_info->spn;
2749   } else {
2750     LoggerW("Failed to retrieve spn_: %d", access_rt);
2751   }
2752
2753   sim_mgr.set_spn(result_spn);
2754   sim_mgr.TryReturn();
2755 }
2756
2757 PlatformResult SysteminfoUtils::ReportSim(picojson::object& out, unsigned long count) {
2758   PlatformResult ret = CheckTelephonySupport();
2759   if (ret.IsError()) {
2760     return ret;
2761   }
2762   return sim_mgr.GatherSimInformation(
2763       system_info_listeners.GetTapiHandles()[count], &out);
2764 }
2765
2766 PlatformResult SysteminfoUtils::ReportPeripheral(picojson::object& out) {
2767
2768 /*  int wireless_display_status = 0;
2769   PlatformResult ret = GetVconfInt(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, wireless_display_status);
2770   if (ret.IsSuccess()) {
2771     if (VCONFKEY_MIRACAST_WFD_SOURCE_ON == wireless_display_status) {
2772       out.insert(std::make_pair(kVideoOutputString, picojson::value(true)));
2773       return PlatformResult(ErrorCode::NO_ERROR);
2774     }
2775   }*/
2776   int hdmi_status = 0;
2777   PlatformResult ret = GetVconfInt(VCONFKEY_SYSMAN_HDMI, hdmi_status);
2778   if (ret.IsSuccess()) {
2779     if (VCONFKEY_SYSMAN_HDMI_CONNECTED == hdmi_status) {
2780       out.insert(std::make_pair(kVideoOutputString, picojson::value(true)));
2781       return PlatformResult(ErrorCode::NO_ERROR);
2782     }
2783   }
2784
2785   out.insert(std::make_pair(kVideoOutputString, picojson::value(false)));
2786   return PlatformResult(ErrorCode::NO_ERROR);
2787 }
2788
2789 PlatformResult SysteminfoUtils::ReportMemory(picojson::object& out) {
2790   std::string state = MEMORY_STATE_NORMAL;
2791   int status = 0;
2792   PlatformResult ret = GetVconfInt(VCONFKEY_SYSMAN_LOW_MEMORY, status);
2793   if (ret.IsSuccess()) {
2794     switch (status) {
2795       case VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING:
2796       case VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING:
2797         state = MEMORY_STATE_WARNING;
2798         break;
2799       case VCONFKEY_SYSMAN_LOW_MEMORY_NORMAL:
2800       default:
2801         state = MEMORY_STATE_NORMAL;
2802     }
2803   }
2804
2805   out.insert(std::make_pair("state", picojson::value(state)));
2806   return PlatformResult(ErrorCode::NO_ERROR);
2807 }
2808
2809 static void CreateStorageInfo(const std::string& type, struct statfs& fs, picojson::object* out) {
2810   out->insert(std::make_pair("type", picojson::value(type)));
2811   out->insert(std::make_pair("capacity", picojson::value(std::to_string(
2812       static_cast<unsigned long long>(fs.f_bsize) *
2813       static_cast<unsigned long long>(fs.f_blocks)))));
2814   out->insert(std::make_pair("availableCapacity", picojson::value(std::to_string(
2815       static_cast<unsigned long long>(fs.f_bsize) *
2816       static_cast<unsigned long long>(fs.f_bavail)))));
2817   bool isRemovable = (type == kTypeInternal) ? false : true;
2818   out->insert(std::make_pair("isRemovable", picojson::value(isRemovable)));
2819 }
2820
2821 PlatformResult SysteminfoUtils::ReportStorage(picojson::object& out) {
2822   int sdcardState = 0;
2823   struct statfs fs;
2824
2825   picojson::value result = picojson::value(picojson::array());
2826
2827   picojson::array& array = result.get<picojson::array>();
2828   array.push_back(picojson::value(picojson::object()));
2829   picojson::object& internal_obj = array.back().get<picojson::object>();
2830
2831   if (statfs(kStorageInternalPath, &fs) < 0) {
2832     LoggerE("There are no storage units detected");
2833     return PlatformResult(ErrorCode::UNKNOWN_ERR, "There are no storage units detected");
2834   }
2835   CreateStorageInfo(kTypeInternal, fs, &internal_obj);
2836   system_info_listeners.SetAvailableCapacityInternal(fs.f_bavail);
2837
2838   if (0 == vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &sdcardState)) {
2839     if (VCONFKEY_SYSMAN_MMC_MOUNTED == sdcardState){
2840       if (statfs(kStorageSdcardPath, &fs) < 0) {
2841         LoggerE("MMC mounted, but not accessible");
2842         return PlatformResult(ErrorCode::UNKNOWN_ERR, "MMC mounted, but not accessible");
2843       }
2844       array.push_back(picojson::value(picojson::object()));
2845       picojson::object& external_obj = array.back().get<picojson::object>();
2846       CreateStorageInfo(kTypeMmc, fs, &external_obj);
2847       system_info_listeners.SetAvailableCapacityMmc(fs.f_bavail);
2848     }
2849   }
2850
2851   out.insert(std::make_pair("storages", picojson::value(result)));
2852   return PlatformResult(ErrorCode::NO_ERROR);
2853 }
2854 PlatformResult SysteminfoUtils::ReportCameraFlash(picojson::object& out,
2855                                                   unsigned long index) {
2856
2857   if (index < system_info_listeners.GetCameraTypesCount()) {
2858     std::string camera = system_info_listeners.GetCameraTypes(index);
2859     out.insert(std::make_pair("camera", picojson::value(camera)));
2860   } else {
2861     return PlatformResult(
2862         ErrorCode::NOT_SUPPORTED_ERR,
2863         "Camera is not supported on this device");
2864   }
2865
2866   return PlatformResult(ErrorCode::NO_ERROR);
2867 }
2868
2869 PlatformResult SysteminfoUtils::RegisterBatteryListener(const SysteminfoUtilsCallback& callback,
2870                                                         SysteminfoInstance& instance)
2871 {
2872   return system_info_listeners.RegisterBatteryListener(callback, instance);
2873 }
2874
2875 PlatformResult SysteminfoUtils::UnregisterBatteryListener()
2876 {
2877   return system_info_listeners.UnregisterBatteryListener();
2878 }
2879
2880
2881 PlatformResult SysteminfoUtils::RegisterCpuListener(const SysteminfoUtilsCallback& callback,
2882                                                     SysteminfoInstance& instance)
2883 {
2884   return system_info_listeners.RegisterCpuListener(callback, instance);
2885 }
2886
2887 PlatformResult SysteminfoUtils::UnregisterCpuListener()
2888 {
2889   return system_info_listeners.UnregisterCpuListener();
2890 }
2891
2892
2893 PlatformResult SysteminfoUtils::RegisterStorageListener(const SysteminfoUtilsCallback& callback,
2894                                                         SysteminfoInstance& instance)
2895 {
2896   return system_info_listeners.RegisterStorageListener(callback, instance);
2897 }
2898
2899 PlatformResult SysteminfoUtils::UnregisterStorageListener()
2900 {
2901   return system_info_listeners.UnregisterStorageListener();
2902 }
2903
2904 PlatformResult SysteminfoUtils::RegisterDisplayListener(const SysteminfoUtilsCallback& callback,
2905                                                         SysteminfoInstance& instance)
2906 {
2907   return system_info_listeners.RegisterDisplayListener(callback, instance);
2908 }
2909
2910 PlatformResult SysteminfoUtils::UnregisterDisplayListener()
2911 {
2912   return system_info_listeners.UnregisterDisplayListener();
2913 }
2914
2915 PlatformResult SysteminfoUtils::RegisterDeviceOrientationListener(const SysteminfoUtilsCallback& callback,
2916                                                                   SysteminfoInstance& instance)
2917 {
2918   return system_info_listeners.RegisterDeviceOrientationListener(callback, instance);
2919 }
2920
2921 PlatformResult SysteminfoUtils::UnregisterDeviceOrientationListener()
2922 {
2923   return system_info_listeners.UnregisterDeviceOrientationListener();
2924 }
2925
2926 PlatformResult SysteminfoUtils::RegisterLocaleListener(const SysteminfoUtilsCallback& callback,
2927                                                        SysteminfoInstance& instance)
2928 {
2929   return system_info_listeners.RegisterLocaleListener(callback, instance);
2930 }
2931
2932 PlatformResult SysteminfoUtils::UnregisterLocaleListener()
2933 {
2934   return system_info_listeners.UnregisterLocaleListener();
2935 }
2936
2937 PlatformResult SysteminfoUtils::RegisterNetworkListener(const SysteminfoUtilsCallback& callback,
2938                                                         SysteminfoInstance& instance)
2939 {
2940   return system_info_listeners.RegisterNetworkListener(callback, instance);
2941 }
2942
2943 PlatformResult SysteminfoUtils::UnregisterNetworkListener()
2944 {
2945   return system_info_listeners.UnregisterNetworkListener();
2946 }
2947
2948 PlatformResult SysteminfoUtils::RegisterWifiNetworkListener(const SysteminfoUtilsCallback& callback,
2949                                                             SysteminfoInstance& instance)
2950 {
2951   return system_info_listeners.RegisterWifiNetworkListener(callback, instance);
2952 }
2953
2954 PlatformResult SysteminfoUtils::UnregisterWifiNetworkListener()
2955 {
2956   return system_info_listeners.UnregisterWifiNetworkListener();
2957 }
2958
2959 PlatformResult SysteminfoUtils::RegisterEthernetNetworkListener(const SysteminfoUtilsCallback& callback,
2960                                                                 SysteminfoInstance& instance)
2961 {
2962   LoggerD("Entered");
2963   return system_info_listeners.RegisterEthernetNetworkListener(callback, instance);
2964 }
2965
2966 PlatformResult SysteminfoUtils::UnregisterEthernetNetworkListener()
2967 {
2968   LoggerD("Entered");
2969   return system_info_listeners.UnregisterEthernetNetworkListener();
2970 }
2971
2972 PlatformResult SysteminfoUtils::RegisterCellularNetworkListener(const SysteminfoUtilsCallback& callback,
2973                                                                 SysteminfoInstance& instance)
2974 {
2975   return system_info_listeners.RegisterCellularNetworkListener(callback, instance);
2976 }
2977
2978 PlatformResult SysteminfoUtils::UnregisterCellularNetworkListener()
2979 {
2980   return system_info_listeners.UnregisterCellularNetworkListener();
2981 }
2982
2983 PlatformResult SysteminfoUtils::RegisterPeripheralListener(const SysteminfoUtilsCallback& callback,
2984                                                            SysteminfoInstance& instance)
2985 {
2986   return system_info_listeners.RegisterPeripheralListener(callback, instance);
2987 }
2988
2989 PlatformResult SysteminfoUtils::UnregisterPeripheralListener()
2990 {
2991   return system_info_listeners.UnregisterPeripheralListener();
2992 }
2993
2994 PlatformResult SysteminfoUtils::RegisterMemoryListener(const SysteminfoUtilsCallback& callback,
2995                                                        SysteminfoInstance& instance)
2996 {
2997   return system_info_listeners.RegisterMemoryListener(callback, instance);
2998 }
2999
3000 PlatformResult SysteminfoUtils::UnregisterMemoryListener()
3001 {
3002   return system_info_listeners.UnregisterMemoryListener();
3003 }
3004
3005 PlatformResult SysteminfoUtils::RegisterCameraFlashListener(const SysteminfoUtilsCallback& callback,
3006                                                        SysteminfoInstance& instance)
3007 {
3008   return system_info_listeners.RegisterCameraFlashListener(callback, instance);
3009 }
3010
3011 PlatformResult SysteminfoUtils::UnregisterCameraFlashListener()
3012 {
3013   return system_info_listeners.UnregisterCameraFlashListener();
3014 }
3015
3016
3017 static PlatformResult CheckStringCapability(const std::string& key, std::string* value, bool* fetched)
3018 {
3019   LoggerD("Entered CheckStringCapability");
3020   *fetched = false;
3021   if (kTizenFeatureOpenglesTextureFormat == key) {
3022     PlatformResult ret = SystemInfoDeviceCapability::GetOpenglesTextureFormat(value);
3023     if (ret.IsError()) {
3024       return ret;
3025     }
3026   } else if (kTizenFeatureCoreApiVersion == key) {
3027     *value = "2.3";
3028   } else if (key == kTizenFeaturePlatfromCoreCpuArch) {
3029     PlatformResult ret = SystemInfoDeviceCapability::GetPlatfomCoreCpuArch(value);
3030     if (ret.IsError()) {
3031       return ret;
3032     }
3033   } else if (kTizenFeaturePlatfromCoreFpuArch == key) {
3034     PlatformResult ret = SystemInfoDeviceCapability::GetPlatfomCoreFpuArch(value);
3035     if (ret.IsError()) {
3036       return ret;
3037     }
3038   } else if (kTizenFeatureProfile == key) {
3039     PlatformResult ret = SystemInfoDeviceCapability::GetProfile(value);
3040     if (ret.IsError()) {
3041       return ret;
3042     }
3043   } else if (kTizenFeaturePlatformNativeApiVersion == key) {
3044     PlatformResult ret = SystemInfoDeviceCapability::GetNativeAPIVersion(value);
3045     if (ret.IsError()) {
3046       return ret;
3047     }
3048   } else if (kTizenFeaturePlatformVersionName == key) {
3049     PlatformResult ret = SystemInfoDeviceCapability::GetPlatformVersionName(value);
3050     if (ret.IsError()) {
3051       return ret;
3052     }
3053   } else {
3054     PlatformResult ret = SystemInfoDeviceCapability::GetValueString(key.substr(strlen("http://")).c_str(), value);
3055     if (ret.IsError()){
3056       return PlatformResult(ErrorCode::NO_ERROR);
3057     }
3058   }
3059   *fetched = true;
3060   return PlatformResult(ErrorCode::NO_ERROR);
3061 }
3062
3063 static PlatformResult CheckBoolCapability(const std::string& key, bool* bool_value, bool* fetched)
3064 {
3065   LoggerD("Entered CheckBoolCapability");
3066   *fetched = false;
3067   if(kTizenFeatureBluetoothAlwaysOn == key) {
3068     *bool_value = SystemInfoDeviceCapability::IsBluetoothAlwaysOn();
3069     *fetched = true;
3070   } else if (kTizenFeatureScreen == key) {
3071     *bool_value = SystemInfoDeviceCapability::IsScreen();
3072     *fetched = true;
3073   } else if (kTizenFeaturePlatformNativeOspCompatible == key) {
3074     PlatformResult ret = SystemInfoDeviceCapability::IsNativeOspCompatible(bool_value);
3075     if (ret.IsError()) {
3076       return ret;
3077     }
3078     *fetched = true;
3079   } else {
3080     PlatformResult ret = SystemInfoDeviceCapability::GetValueBool(
3081         key.substr(strlen("http://")).c_str(), bool_value);
3082     if (ret.IsSuccess()) {
3083       *fetched = true;
3084     }
3085   }
3086   return PlatformResult(ErrorCode::NO_ERROR);
3087 }
3088
3089 static PlatformResult CheckIntCapability(const std::string& key, std::string* value,
3090                                          bool* fetched)
3091 {
3092   LoggerD("Entered CheckIntCapability");
3093   int result = 0;
3094   if (key == kTizenFeatureCpuFrequency) {
3095     PlatformResult ret = SystemInfoDeviceCapability::GetPlatformCoreCpuFrequency(&result);
3096     if (ret.IsError()) {
3097       *fetched = false;
3098       return ret;
3099     }
3100   } else {
3101     PlatformResult ret = SystemInfoDeviceCapability::GetValueInt(
3102         key.substr(strlen("http://")).c_str(), &result);
3103     if (ret.IsError()) {
3104       *fetched = false;
3105       return PlatformResult(ErrorCode::NO_ERROR);
3106     }
3107   }
3108   *value = std::to_string(result);
3109   *fetched = true;
3110   return PlatformResult(ErrorCode::NO_ERROR);
3111 }
3112
3113 ///////////////////////   SystemInfoDeviceCapability   //////////////////////////////////////
3114 PlatformResult SystemInfoDeviceCapability::GetCapability(const std::string& key,
3115                                                           picojson::value& result)
3116 {
3117   LoggerD("Entered");
3118   picojson::object& result_obj = result.get<picojson::object>();
3119
3120   std::string value = "";
3121   std::string type = "";
3122   bool bool_value = false ;
3123   bool is_fetched = false;
3124
3125   PlatformResult ret = CheckBoolCapability(key, &bool_value, &is_fetched);
3126   if (ret.IsError()) {
3127     return ret;
3128   }
3129   if (is_fetched) {
3130     type = "bool";
3131   } else {
3132     ret = CheckIntCapability(key, &value, &is_fetched);
3133     if (ret.IsError()) {
3134       return ret;
3135     }
3136     if (is_fetched) {
3137       type = "int";
3138     } else {
3139       ret = CheckStringCapability(key, &value, &is_fetched);
3140       if (ret.IsError()) {
3141         return ret;
3142       }
3143       if(is_fetched) {
3144         type = "string";
3145       }
3146     }
3147   }
3148
3149   if (type == "bool") {
3150     result_obj.insert(std::make_pair("value", picojson::value(bool_value)));
3151   } else if (type == "string" || type == "int") {
3152     result_obj.insert(std::make_pair("value", picojson::value(value)));
3153   } else {
3154     LoggerD("Value for given key was not found");
3155     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Value for given key was not found");
3156   }
3157   result_obj.insert(std::make_pair("type", picojson::value(type)));
3158
3159   return PlatformResult(ErrorCode::NO_ERROR);
3160 }
3161
3162 PlatformResult SystemInfoDeviceCapability::IsInputKeyboardLayout(bool* result) {
3163   std::string input_keyboard_layout = "";
3164   PlatformResult ret = GetValueString("tizen.org/feature/input.keyboard.layout",
3165                                       &input_keyboard_layout);
3166   if (ret.IsError()) {
3167     return ret;
3168   }
3169   bool input_keyboard = false;
3170   ret = GetValueBool("tizen.org/feature/input.keyboard", &input_keyboard);
3171   if (ret.IsError()) {
3172     return ret;
3173   }
3174
3175   // according to SystemInfo-DeviceCapabilities-dependency-table
3176   // inputKeyboard   inputKeyboardLayout
3177   //  O               O                   Possible
3178   //  O               X                   Possible
3179   //  X               X                   Possible
3180   //  X               O                   Impossible
3181
3182   *result = input_keyboard ? !(input_keyboard_layout.empty()) : false;
3183   return PlatformResult(ErrorCode::NO_ERROR);
3184 }
3185
3186 PlatformResult SystemInfoDeviceCapability::GetOpenglesTextureFormat(std::string* result) {
3187   bool bool_result = false;
3188   PlatformResult ret = GetValueBool("tizen.org/feature/opengles", &bool_result);
3189   if (!bool_result) {
3190     // this exception is converted to "Undefined" value in JS layer
3191     std::string log_msg = "OpenGL-ES is not supported";
3192     LoggerE("%s", log_msg.c_str());
3193     return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, log_msg);
3194   }
3195   std::string texture_format = "";
3196
3197   ret = GetValueBool("tizen.org/feature/opengles.texture_format.utc", &bool_result);
3198   if (ret.IsError()) {
3199     return ret;
3200   }
3201   if (bool_result) {
3202     texture_format += kOpenglesTextureUtc;
3203   }
3204
3205   ret = GetValueBool("tizen.org/feature/opengles.texture_format.ptc", &bool_result);
3206   if (ret.IsError()) {
3207     return ret;
3208   }
3209   if (bool_result) {
3210     if (!texture_format.empty()) {
3211       texture_format += kOpenglesTextureDelimiter;
3212     }
3213     texture_format += kOpenglesTexturePtc;
3214   }
3215
3216   ret = GetValueBool("tizen.org/feature/opengles.texture_format.etc", &bool_result);
3217   if (ret.IsError()) {
3218     return ret;
3219   }
3220   if (bool_result) {
3221     if (!texture_format.empty()) {
3222       texture_format += kOpenglesTextureDelimiter;
3223     }
3224     texture_format += kOpenglesTextureEtc;
3225   }
3226
3227   ret = GetValueBool("tizen.org/feature/opengles.texture_format.3dc", &bool_result);
3228   if (ret.IsError()) {
3229     return ret;
3230   }
3231   if (bool_result) {
3232     if (!texture_format.empty()) {
3233       texture_format += kOpenglesTextureDelimiter;
3234     }
3235     texture_format += kOpenglesTexture3dc;
3236   }
3237
3238   ret = GetValueBool("tizen.org/feature/opengles.texture_format.atc", &bool_result);
3239   if (ret.IsError()) {
3240     return ret;
3241   }
3242   if (bool_result) {
3243     if (!texture_format.empty()) {
3244       texture_format += kOpenglesTextureDelimiter;
3245     }
3246     texture_format += kOpenglesTextureAtc;
3247   }
3248
3249   ret = GetValueBool("tizen.org/feature/opengles.texture_format.pvrtc", &bool_result);
3250   if (ret.IsError()) {
3251     return ret;
3252   }
3253   if (bool_result) {
3254     if (!texture_format.empty()) {
3255       texture_format += kOpenglesTextureDelimiter;
3256     }
3257     texture_format += kOpenglesTexturePvrtc;
3258   }
3259
3260   if (texture_format.empty()) {
3261     // this exception is converted to "Undefined" value in JS layer
3262     std::string log_msg = "Platform error while getting OpenGL-ES texture format";
3263     LoggerE("%s", log_msg.c_str());
3264     return PlatformResult(ErrorCode::UNKNOWN_ERR, log_msg);
3265   }
3266   *result = texture_format;
3267   return PlatformResult(ErrorCode::NO_ERROR);
3268 }
3269
3270 PlatformResult SystemInfoDeviceCapability::GetPlatfomCoreCpuArch(std::string* return_value) {
3271   std::string result;
3272   bool bool_result = false;
3273   PlatformResult ret = GetValueBool("tizen.org/feature/platform.core.cpu.arch.armv6", &bool_result);
3274   if (ret.IsError()) {
3275     return ret;
3276   }
3277   if (bool_result) {
3278     result = kPlatformCoreArmv6;
3279   }
3280
3281   ret = GetValueBool("tizen.org/feature/platform.core.cpu.arch.armv7", &bool_result);
3282   if (ret.IsError()) {
3283     return ret;
3284   }
3285   if (bool_result) {
3286     if (!result.empty()) {
3287       result += kPlatformCoreDelimiter;
3288     }
3289     result += kPlatformCoreArmv7;
3290   }
3291
3292   ret = GetValueBool("tizen.org/feature/platform.core.cpu.arch.x86", &bool_result);
3293   if (ret.IsError()) {
3294     return ret;
3295   }
3296   if (bool_result) {
3297     if (!result.empty()) {
3298       result += kPlatformCoreDelimiter;
3299     }
3300     result += kPlatformCoreX86;
3301   }
3302
3303   if (result.empty()) {
3304     LoggerE("Platform error while retrieving platformCoreCpuArch: result is empty");
3305     return PlatformResult(ErrorCode::UNKNOWN_ERR, "platformCoreCpuArch result is empty");
3306   }
3307   *return_value = result;
3308   return PlatformResult(ErrorCode::NO_ERROR);
3309 }
3310
3311 PlatformResult SystemInfoDeviceCapability::GetPlatfomCoreFpuArch(std::string* return_value) {
3312   std::string result;
3313   bool bool_result = false;
3314   PlatformResult ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.sse2", &bool_result);
3315   if (ret.IsError()) {
3316     return ret;
3317   }
3318   if (bool_result) {
3319     result = kPlatformCoreSse2;
3320   }
3321
3322   ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.sse3", &bool_result);
3323   if (ret.IsError()) {
3324     return ret;
3325   }
3326   if (bool_result) {
3327     if (!result.empty()) {
3328       result += kPlatformCoreDelimiter;
3329     }
3330     result += kPlatformCoreSse3;
3331   }
3332
3333   ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.ssse3", &bool_result);
3334   if (ret.IsError()) {
3335     return ret;
3336   }
3337   if (bool_result) {
3338     if (!result.empty()) {
3339       result += kPlatformCoreDelimiter;
3340     }
3341     result += kPlatformCoreSsse3;
3342   }
3343
3344   ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.vfpv2", &bool_result);
3345   if (ret.IsError()) {
3346     return ret;
3347   }
3348   if (bool_result) {
3349     if (!result.empty()) {
3350       result += kPlatformCoreDelimiter;
3351     }
3352     result += kPlatformCoreVfpv2;
3353   }
3354
3355   ret = GetValueBool("tizen.org/feature/platform.core.fpu.arch.vfpv3", &bool_result);
3356   if (ret.IsError()) {
3357     return ret;
3358   }
3359   if (bool_result) {
3360     if (!result.empty()) {
3361       result += kPlatformCoreDelimiter;
3362     }
3363     result += kPlatformCoreVfpv3;
3364   }
3365   if (result.empty()) {
3366     LoggerE("Platform error while retrieving platformCoreFpuArch: result is empty");
3367     return PlatformResult(ErrorCode::UNKNOWN_ERR, "platformCoreFpuArch result is empty");
3368   }
3369   *return_value = result;
3370   return PlatformResult(ErrorCode::NO_ERROR);
3371 }
3372
3373 PlatformResult SystemInfoDeviceCapability::GetProfile(std::string* return_value) {
3374   std::string profile = "";
3375   PlatformResult ret = GetValueString("tizen.org/feature/profile", &profile);
3376   if (ret.IsError()) {
3377     return ret;
3378   }
3379
3380   *return_value = kProfileFull;
3381   if ( kPlatformFull == profile ) {
3382     *return_value = kProfileFull;
3383   } else if ( kPlatformMobile == profile ) {
3384     *return_value = kProfileMobile;
3385   } else if ( kPlatformWearable == profile ) {
3386     *return_value = kProfileWearable;
3387   }
3388   return PlatformResult(ErrorCode::NO_ERROR);
3389 }
3390
3391 bool SystemInfoDeviceCapability::IsBluetoothAlwaysOn() {
3392 #ifdef PROFILE_MOBILE_FULL
3393   return false;
3394 #elif PROFILE_MOBILE
3395   return false;
3396 #elif PROFILE_WEARABLE
3397   return false;
3398 #elif PROFILE_TV
3399   return true;
3400 #else
3401   return false;
3402 #endif
3403 }
3404
3405 bool SystemInfoDeviceCapability::IsScreen()
3406 {
3407   return true;
3408 }
3409
3410
3411 PlatformResult SystemInfoDeviceCapability::GetPlatformCoreCpuFrequency(int* return_value)
3412 {
3413   LoggerD("Entered");
3414
3415   std::string freq;
3416   std::string file_name;
3417
3418 #ifdef TIZEN_IS_EMULATOR
3419   file_name = "/proc/cpuinfo";
3420 #else
3421   file_name = "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq";
3422 #endif
3423
3424   std::ifstream cpuinfo_freq(file_name);
3425   if (!cpuinfo_freq.is_open()) {
3426     LoggerE("Failed to get cpu frequency");
3427     return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unable to open file");
3428   }
3429
3430 #ifdef TIZEN_IS_EMULATOR
3431   //get frequency value from cpuinfo file
3432   //example entry for frequency looks like below
3433   //cpu MHz   : 3392.046
3434   std::size_t found;
3435   do {
3436     getline(cpuinfo_freq, freq);
3437     found = freq.find("cpu MHz");
3438   } while (std::string::npos == found && !cpuinfo_freq.eof());
3439
3440   found = freq.find(":");
3441   if (std::string::npos != found) {
3442     *return_value = std::stoi(freq.substr(found + 2));
3443   }
3444 #else
3445   getline(cpuinfo_freq, freq);
3446   *return_value = std::stoi(freq) / 1000; // unit: MHz
3447 #endif
3448
3449   cpuinfo_freq.close();
3450   LoggerD("cpu frequency : %d", *return_value);
3451
3452   return PlatformResult(ErrorCode::NO_ERROR);
3453 }
3454
3455 PlatformResult SystemInfoDeviceCapability::IsNativeOspCompatible(bool* result)
3456 {
3457   LoggerD("Enter");
3458 #ifdef PROFILE_WEARABLE
3459   *result = false;
3460   return PlatformResult(ErrorCode::NO_ERROR);
3461 #else
3462   return GetValueBool(kTizenFeaturePlatformNativeOspCompatible, result);
3463 #endif
3464 }
3465
3466 PlatformResult SystemInfoDeviceCapability::GetNativeAPIVersion(std::string* return_value)
3467 {
3468   LoggerD("Enter");
3469 #ifdef PROFILE_WEARABLE
3470   *return_value = "";
3471   return PlatformResult(ErrorCode::NO_ERROR);
3472 #else
3473   return GetValueString(kTizenFeaturePlatformNativeApiVersion, return_value);
3474 #endif
3475 }
3476
3477 PlatformResult SystemInfoDeviceCapability::GetPlatformVersionName(std::string* result)
3478 {
3479   LoggerD("Enter");
3480
3481   //Because of lack of 'http://tizen.org/feature/platform.version.name'
3482   //key on platform we use 'http://tizen.org/system/platform.name'.
3483   return GetValueString("tizen.org/system/platform.name", result);
3484 }
3485
3486 } // namespace systeminfo
3487 } // namespace webapi