tizen 2.3.1 release
[framework/web/wearable/wrt-plugins-tizen.git] / src / Systeminfo / SystemInfo.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "SystemInfo.h"
19 #include "SystemInfoDeviceCapability.h"
20 #include "SystemInfoProperty.h"
21 #include "SystemInfoUtil.h"
22 #include "JSSystemInfoBattery.h"
23 #include "JSSystemInfoLocale.h"
24 #include "JSSystemInfoStorage.h"
25 #include "JSSystemInfoDisplay.h"
26 #include "JSSystemInfoDeviceOrientation.h"
27 #include "JSSystemInfoCpu.h"
28 #include "JSSystemInfoBuild.h"
29 #include "JSSystemInfoPeripheral.h"
30 #include "JSSystemInfoNetwork.h"
31 #include "JSSystemInfoMemory.h"
32
33 #ifdef FEATURE_OPTIONAL_WI_FI
34 #include "JSSystemInfoWifiNetwork.h"
35 #endif
36
37 #include "JSSystemInfoCellularNetwork.h"
38 #include "JSSystemInfoSIM.h"
39
40 #include <algorithm>
41 #include <JSWebAPIErrorFactory.h>
42 #include <PlatformException.h>
43 #include <Logger.h>
44 #include <GlobalContextManager.h>
45 #include <device.h>
46
47 namespace DeviceAPI {
48 namespace SystemInfo {
49
50 namespace {
51 const double PROPERTY_WATCHER_TIME = 1;
52 const int MEMORY_TO_BYTE = 1024;
53 const int BASE_GATHERING_INTERVAL = 100;
54
55 }
56
57 CpuInfo SystemInfo::m_cpu_info;
58
59 std::mutex SystemInfo::m_cpu_info_lock;
60
61 using namespace DeviceAPI::Common;
62
63 SystemInfo::SystemInfo() :
64                 m_storage_timer(NULL),
65                 m_cpu_timer(NULL),
66                 m_cpu_last_load(0),
67                 m_connection_handle(NULL),
68                 m_current_id(0),
69                 m_sensor_handle(NULL),
70                 m_is_telephony_enable(false)
71 {
72     LOGD("Entered");
73
74     // add codes to check device's capability for telephony
75     SystemInfoDeviceCapabilityPtr deviceCapability = getCapabilities();
76     m_is_telephony_enable = deviceCapability->isTelephony();
77
78     int i = 0;
79     for (i = 0; i <= TAPI_HANDLE_MAX; i++) {
80         m_tapi_handle[i] = NULL;
81     }
82
83     // create thread pool with max threads = 1 to make API calls async but
84     // only one call at time
85     m_pool = g_thread_pool_new(getPropertyValueThread, NULL, 1, true, NULL);
86 }
87
88 SystemInfo::~SystemInfo()
89 {
90     LOGD("Entered");
91
92     std::for_each(m_watcher_map.begin(), m_watcher_map.end(),
93             [] (const std::pair<unsigned long, Ecore_Timer*>& watcher) {
94                 Ecore_Timer* timer = watcher.second;
95                 if (timer) {
96                     ecore_timer_del(timer);
97                     timer = NULL;
98                 }
99             });
100
101     if (!m_battery_callbacks.empty()) {
102         unregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CAPACITY, SystemInfo::onBatteryChanged);
103         unregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, SystemInfo::onBatteryChanged);
104     }
105
106     if (!m_peripheral_callbacks.empty()) {
107         unregisterVconfCallback(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS,
108                 SystemInfo::onPeripheralChanged);
109         unregisterVconfCallback(VCONFKEY_SYSMAN_HDMI, SystemInfo::onPeripheralChanged);
110         unregisterVconfCallback(VCONFKEY_POPSYNC_ACTIVATED_KEY, SystemInfo::onPeripheralChanged);
111     }
112
113     if (!m_device_orientation_callbacks.empty()) {
114         unregisterVconfCallback(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
115                 SystemInfo::onDeviceAutoRotationChanged);
116         if (m_sensor_handle) {
117             sensord_unregister_event(m_sensor_handle, AUTO_ROTATION_EVENT_CHANGE_STATE);
118             SystemInfoDeviceOrientation::disconnectSensor(m_sensor_handle);
119             m_sensor_handle = NULL;
120         }
121     }
122
123     if (!m_network_callbacks.empty()) {
124         LOGD("the native callback for NETWORK listeners will be removed.");
125         unregisterNetworkTypeChangeCallback();
126     }
127
128     if (m_is_telephony_enable) {
129         if (!m_cellular_network_callbacks.empty() || !m_wifi_network_callbacks.empty()) {
130             //wifi and cellular has common ip callback
131             unregisterIpChangeCallback();
132         }
133
134         if (!m_cellular_network_callbacks.empty()) {
135             unregisterVconfCallback(VCONFKEY_TELEPHONY_FLIGHT_MODE, onConnectionNetworkParamChanged);
136             unregisterVconfCallback(VCONFKEY_TELEPHONY_CELLID, onConnectionNetworkParamChanged);
137             unregisterVconfCallback(VCONFKEY_TELEPHONY_LAC, onConnectionNetworkParamChanged);
138             unregisterVconfCallback(VCONFKEY_TELEPHONY_SVC_ROAM, onConnectionNetworkParamChanged);
139         }
140     }
141
142     if (!m_locale_callbacks.empty()) {
143         if (SYSTEM_SETTINGS_ERROR_NONE
144                 != system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE)) {
145             LOGE("unregistration of language change callback failed");
146         }
147         if (SYSTEM_SETTINGS_ERROR_NONE
148                 != system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY)) {
149             LOGE("unregistration of country change callback failed");
150         }
151     }
152
153     if (!m_storage_callbacks.empty()) {
154         unregisterVconfCallback(VCONFKEY_SYSMAN_MMC_STATUS, SystemInfo::mmcStatusChanged);
155     }
156
157     if (!m_memory_callbacks.empty()) {
158         unregisterVconfCallback(VCONFKEY_SYSMAN_LOW_MEMORY, SystemInfo::onMemoryChanged);
159     }
160
161     stopAndDestroyTimer(&m_cpu_timer, std::string("Cpu"));
162     stopAndDestroyTimer(&m_storage_timer, std::string("Storage"));
163
164     //finish only current task and wait for thread to stop
165     g_thread_pool_free(m_pool, true, true);
166
167     if (m_is_telephony_enable) {
168         unsigned int i = 0;
169         while (m_tapi_handle[i]) {
170             tel_deinit(m_tapi_handle[i]);
171             i++;
172         }
173     }
174
175     for (auto it = m_processing_properties.begin(); it != m_processing_properties.end(); ++it) {
176         delete *it;
177     }
178     m_processing_properties.clear();
179
180     if (NULL != m_connection_handle) {
181         connection_destroy(m_connection_handle);
182     }
183 }
184
185 SystemInfo& SystemInfo::getInstance()
186 {
187     static SystemInfo instance;
188     return instance;
189 }
190
191 long long SystemInfo::getTotalMemory()
192 {
193     LOGD("Entered");
194
195     unsigned int value = 0;
196
197     int ret = device_memory_get_total(&value);
198     if (ret != DEVICE_ERROR_NONE) {
199         std::string log_msg = "Failed to get total memory: ";
200         LOGE("%s %d", log_msg.c_str(), ret);
201         SystemInfoUtil::throwSystemInfoException(0, log_msg);
202     }
203
204     return static_cast<long long>(value * MEMORY_TO_BYTE);
205 }
206
207 long long SystemInfo::getAvailableMemory()
208 {
209     LOGD("Entered");
210
211     unsigned int value = 0;
212
213     int ret = device_memory_get_available(&value);
214     if (ret != DEVICE_ERROR_NONE) {
215         std::string log_msg = "Failed to get total memory: ";
216         LOGE("%s %d", log_msg.c_str(), ret);
217         SystemInfoUtil::throwSystemInfoException(0, log_msg);
218     }
219
220     return static_cast<long long>(value * MEMORY_TO_BYTE);
221 }
222
223 SystemInfoDeviceCapabilityPtr SystemInfo::getCapabilities()
224 {
225     SystemInfoDeviceCapabilityPtr capability(new SystemInfoDeviceCapability());
226     return capability;
227 }
228
229 unsigned long SystemInfo::getCount(SystemInfoPropertyId propertyId)
230 {
231     LOGD("Entered");
232
233     unsigned long count = 0;
234
235     switch (propertyId) {
236         case SystemInfoPropertyId::BATTERY:
237         case SystemInfoPropertyId::CPU:
238         case SystemInfoPropertyId::STORAGE:
239         case SystemInfoPropertyId::DISPLAY:
240         case SystemInfoPropertyId::DEVICE_ORIENTATION:
241         case SystemInfoPropertyId::BUILD:
242         case SystemInfoPropertyId::LOCALE:
243         case SystemInfoPropertyId::NETWORK:
244         case SystemInfoPropertyId::PERIPHERAL:
245         case SystemInfoPropertyId::MEMORY:
246             count = DEFAULT_PROPERTY_COUNT;
247             break;
248 #ifdef FEATURE_OPTIONAL_WI_FI
249         case SystemInfoPropertyId::WIFI_NETWORK:
250             count = DEFAULT_PROPERTY_COUNT;
251             break;
252 #endif
253         case SystemInfoPropertyId::CELLULAR_NETWORK:
254             if (m_is_telephony_enable) {
255                 count = DEFAULT_PROPERTY_COUNT;
256                 break;
257             }
258         case SystemInfoPropertyId::SIM:
259             if (m_is_telephony_enable) {
260                 count = TAPI_HANDLE_MAX;
261                 break;
262             }
263         default:
264             std::string log_msg = "Not supported property: " + std::to_string(propertyId);
265     }
266     return count;
267 }
268
269 gboolean SystemInfo::getPropertyValueCallback(void *data)
270 {
271     LOGD("Entered");
272
273     auto holder = static_cast<PropertyCallbackDataHolder*>(data);
274     if (!holder) {
275         LOGE("callback holder is null");
276         return false;
277     }
278     auto callback = holder->ptr;
279     if (!callback) {
280         LOGE("callback is null");
281         delete holder;
282         holder = NULL;
283         return false;
284     }
285
286     JSContextRef context = callback->getContext();
287     if (!GlobalContextManager::getInstance()->isAliveGlobalContext(context)) {
288         LOGE("context was closed");
289         delete holder;
290         holder = NULL;
291         return false;
292     }
293
294     try {
295         JSObjectRef js_property = NULL;
296         JSObjectRef js_array = JSCreateArrayObject(context, 0, NULL);
297         JSObjectRef js_result = NULL;
298         bool isArrayCallback = callback->isArrayCallback();
299
300         if (js_array == NULL) {
301             std::string log_msg = "Failed to create JSPropertyValueArray";
302             LOGE("%s", log_msg.c_str());
303             SystemInfoUtil::throwSystemInfoException(0, log_msg);
304         }
305
306         std::vector<SystemInfoPropertyHolder*> properties = callback->getPropertyArray();
307         LOGD("%d objects exist", properties.size());
308         LOGD("%d property", callback->getPropertyId());
309
310         try {
311             for (size_t i = 0; i < properties.size(); i++) {
312                 SystemInfoPropertyPtr property = properties[i]->ptr;
313                 LOGD("Entered");
314                 if (property == NULL) {
315                     std::string log_msg = "property is null";
316                     LOGE("%s", log_msg.c_str());
317                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
318                 }
319
320                 switch (callback->getPropertyId()) {
321                     case SystemInfoPropertyId::BATTERY:
322                         js_property = JSSystemInfoBattery::makeJSObject(context, property);
323                         break;
324                     case SystemInfoPropertyId::CPU:
325                         js_property = JSSystemInfoCpu::makeJSObject(context, property);
326                         break;
327                     case SystemInfoPropertyId::STORAGE:
328                         js_property = JSSystemInfoStorage::makeJSObject(context, property);
329                         break;
330                     case SystemInfoPropertyId::DISPLAY:
331                         js_property = JSSystemInfoDisplay::makeJSObject(context, property);
332                         break;
333                     case SystemInfoPropertyId::DEVICE_ORIENTATION:
334                         js_property = JSSystemInfoDeviceOrientation::makeJSObject(context,
335                                 property);
336                         break;
337                     case SystemInfoPropertyId::BUILD:
338                         js_property = JSSystemInfoBuild::makeJSObject(context, property);
339                         break;
340                     case SystemInfoPropertyId::LOCALE:
341                         js_property = JSSystemInfoLocale::makeJSObject(context, property);
342                         break;
343                     case SystemInfoPropertyId::NETWORK:
344                         js_property = JSSystemInfoNetwork::makeJSObject(context, property);
345                         break;
346 #ifdef FEATURE_OPTIONAL_WI_FI
347                     case SystemInfoPropertyId::WIFI_NETWORK:
348                         js_property = JSSystemInfoWifiNetwork::makeJSObject(context, property);
349                         break;
350 #endif
351                     case SystemInfoPropertyId::CELLULAR_NETWORK: {
352                         if (SystemInfo::getInstance().m_is_telephony_enable) {
353                             js_property = JSSystemInfoCellularNetwork::makeJSObject(context, property);
354                             break;
355                         } else {
356                             std::string log_msg = "Not supported property";
357                             LOGE("%s", log_msg.c_str());
358                             SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
359                         }
360                     }
361                     case SystemInfoPropertyId::SIM: {
362                         if (SystemInfo::getInstance().m_is_telephony_enable) {
363                             js_property = JSSystemInfoSIM::makeJSObject(context, property);
364                             break;
365                         } else {
366                             std::string log_msg = "Not supported property";
367                             LOGE("%s", log_msg.c_str());
368                             SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
369                         }
370                     }
371                     case SystemInfoPropertyId::PERIPHERAL:
372                         js_property = JSSystemInfoPeripheral::makeJSObject(context, property);
373                         break;
374                     case SystemInfoPropertyId::MEMORY:
375                         js_property = JSSystemInfoMemory::makeJSObject(context, property);
376                         break;
377                     default:
378                         std::string log_msg = "Not supported property";
379                         LOGE("%s", log_msg.c_str());
380                         SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
381                 }
382
383                 if (!isArrayCallback) {
384                     break;
385                 }
386
387                 if (!JSSetArrayElement(context, js_array, i, js_property)) {
388                     std::string log_msg = "Failed to add property into array";
389                     LOGE("%s", log_msg.c_str());
390                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
391                 }
392             }
393
394             if (isArrayCallback) {
395                 js_result = js_array;
396             } else {
397                 js_result = js_property;
398             }
399
400         } catch (const BasePlatformException &err) {
401             LOGE("getPropertyValueCallback fails, %s: %s", err.getName().c_str(),
402                     err.getMessage().c_str());
403             JSObjectRef error = JSWebAPIErrorFactory::makeErrorObject(context, err);
404             callback->callErrorCallback(error);
405         } catch (...) {
406             LOGE("getPropertyValueCallback fails");
407             JSObjectRef error = JSWebAPIErrorFactory::makeErrorObject(context,
408                     JSWebAPIErrorFactory::UNKNOWN_ERROR, "UnknownError");
409             callback->callErrorCallback(error);
410         }
411
412         if (js_result != NULL) {
413             callback->callSuccessCallback(js_result);
414         } else {
415             LOGE("Invalid callback data");
416             JSObjectRef error = JSWebAPIErrorFactory::makeErrorObject(context,
417                     JSWebAPIErrorFactory::UNKNOWN_ERROR, "property object creation failed");
418             callback->callErrorCallback(error);
419         }
420     } catch (const BasePlatformException &err) {
421         LOGE("getPropertyValueCallback fails, %s: %s", err.getName().c_str(),
422                 err.getMessage().c_str());
423     } catch (...) {
424         LOGE("getPropertyValueCallback fails");
425     }
426
427     delete holder;
428     holder = NULL;
429
430     return false;
431 }
432
433 void SystemInfo::notifyGetPropertyValueReady()
434 {
435     LOGD("Entered");
436     std::lock_guard < std::mutex > lock(m_processing_properties_lock);
437     for (auto it = m_processing_properties.begin(); it != m_processing_properties.end(); ++it) {
438         if ((*it)->ptr->isPropertyReady()) {
439             if (!g_idle_add(getPropertyValueCallback, *it)) {
440                 LOGE("g_idle_add fails");
441                 delete *it;
442             }
443             m_processing_properties.erase(it);
444             break;
445         }
446     }
447 }
448
449 void SystemInfo::addProcessingProperty(PropertyCallbackDataHolder* holder)
450 {
451     std::lock_guard < std::mutex > lock(m_processing_properties_lock);
452     m_processing_properties.push_back(holder);
453 }
454
455 #ifdef FEATURE_OPTIONAL_WI_FI
456 void SystemInfo::registerIpChangeCallback()
457 {
458     LOGD("Registering connection callback");
459     connection_h handle = getConnectionHandle();
460     int ret = connection_set_ip_address_changed_cb(handle, onConnectionIpAddressChanged, NULL);
461     if (CONNECTION_ERROR_NONE != ret) {
462         std::string log_msg = "Failed to register ip change callback";
463         LOGE("%s, %d, %s", log_msg.c_str(), ret,
464                 SystemInfoUtil::getConnectionErrorMessage(ret).c_str());
465         SystemInfoUtil::throwConnectionException(ret, log_msg);
466     }
467 }
468
469 void SystemInfo::unregisterIpChangeCallback()
470 {
471     LOGD("Unregistering connection callback");
472     connection_h handle = getConnectionHandle();
473
474     int ret = connection_unset_ip_address_changed_cb(handle);
475     if (CONNECTION_ERROR_NONE != ret) {
476         std::string log_msg = "Failed to unregister ip change callback";
477         LOGE("%s, %d, %s", log_msg.c_str(), ret,
478                 SystemInfoUtil::getConnectionErrorMessage(ret).c_str());
479         SystemInfoUtil::throwConnectionException(ret, log_msg);
480     }
481 }
482 #else
483 void SystemInfo::registerIpChangeCallback()
484 {
485     LOGD("Registering connection callback");
486     //Not supported
487 }
488
489 void SystemInfo::unregisterIpChangeCallback()
490 {
491     LOGD("Unregistering connection callback");
492     //Not supported
493 }
494 #endif
495 void SystemInfo::registerNetworkTypeChangeCallback()
496 {
497     LOGD("Registering connection callback");
498     connection_h handle = getConnectionHandle();
499     int ret = connection_set_type_changed_cb(handle, onConnectionNetworkTypeChanged, NULL);
500     if (ret != CONNECTION_ERROR_NONE) {
501         std::string log_msg = "Failed to register network type change callback";
502         LOGE("%s, %d, %s", log_msg.c_str(), ret,
503                 SystemInfoUtil::getConnectionErrorMessage(ret).c_str());
504         SystemInfoUtil::throwConnectionException(ret, log_msg);
505     }
506 }
507
508 void SystemInfo::unregisterNetworkTypeChangeCallback()
509 {
510     LOGD("Unregistering connection callback");
511     connection_h handle = getConnectionHandle();
512     int ret = connection_unset_type_changed_cb(handle);
513     if (ret != CONNECTION_ERROR_NONE) {
514         std::string log_msg = "Failed to unregister network type change callback";
515         LOGE("%s, %d, %s", log_msg.c_str(), ret,
516                 SystemInfoUtil::getConnectionErrorMessage(ret).c_str());
517         SystemInfoUtil::throwConnectionException(ret, log_msg);
518     }
519 }
520
521 connection_h SystemInfo::getConnectionHandle()
522 {
523     if (NULL == m_connection_handle) {
524         int ret = connection_create(&m_connection_handle);
525         if (CONNECTION_ERROR_NONE != ret) {
526             std::string log_msg = "Failed to create connection";
527             LOGE("%s, %d, %s", log_msg.c_str(), ret,
528                     SystemInfoUtil::getConnectionErrorMessage(ret).c_str());
529             SystemInfoUtil::throwConnectionException(ret, log_msg);
530         }
531     }
532     return m_connection_handle;
533 }
534
535 void SystemInfo::onConnectionIpAddressChanged(const char* /*ipv4_address*/,
536         const char* /*ipv6_address*/, void* /*user_data*/)
537 {
538     LOGD("Entered");
539     SystemInfo::getInstance().broadcastCellularNetworkChanged();
540     SystemInfo::getInstance().broadcastWifiNetworkChanged();
541 }
542
543 void SystemInfo::onConnectionNetworkParamChanged(keynode_t *node, void *user_data)
544 {
545     LOGD("Entered");
546     SystemInfo::getInstance().broadcastCellularNetworkChanged();
547 }
548
549 void SystemInfo::onConnectionNetworkTypeChanged(connection_type_e type, void *user_data)
550 {
551     LOGD("Enterd");
552     SystemInfo::getInstance().broadcastNetworkTypeChanged();
553 }
554
555 void SystemInfo::broadcastCellularNetworkChanged()
556 {
557     LOGD("Enterd");
558
559     if (!m_is_telephony_enable) {
560         LOGD("\"http://tizen.org/feature/network.telephony\" is not supported");
561         return;
562     }
563
564     try {
565         SystemInfoPropertyPtr property(new SystemInfoCellularNetwork());
566
567         PVCLmap::iterator itr = m_cellular_network_callbacks.begin();
568
569         while (itr != m_cellular_network_callbacks.end()) {
570             PropertyCallbackDataPtr callback = itr->second;
571             callback->setNativeProperty(property);
572
573             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
574             if (!holder) {
575                 std::string log_msg = "Failed to allocate memory";
576                 LOGE("%s", log_msg.c_str());
577                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
578             }
579             holder->ptr = callback;
580
581             guint id = g_idle_add(getPropertyValueCallback, holder);
582             if (!id) {
583                 LOGE("g_idle_add fails");
584                 delete holder;
585             }
586             ++itr;
587         }
588     } catch (const BasePlatformException &err) {
589         LOGE("broadcastCellularNetworkChanged fails, %s: %s", err.getName().c_str(),
590                 err.getMessage().c_str());
591     } catch (...) {
592         LOGE("broadcastCellularNetworkChanged fails");
593     }
594 }
595
596 #ifdef FEATURE_OPTIONAL_WI_FI
597 void SystemInfo::broadcastWifiNetworkChanged()
598 {
599     try {
600         SystemInfoPropertyPtr property(new SystemInfoWifiNetwork());
601
602         PVCLmap::iterator itr = m_wifi_network_callbacks.begin();
603
604         while (itr != m_wifi_network_callbacks.end()) {
605             PropertyCallbackDataPtr callback = itr->second;
606             callback->setNativeProperty(property);
607
608             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
609             if (!holder) {
610                 std::string log_msg = "Failed to allocate memory";
611                 LOGE("%s", log_msg.c_str());
612                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
613             }
614             holder->ptr = callback;
615
616             guint id = g_idle_add(getPropertyValueCallback, holder);
617             if (!id) {
618                 LOGE("g_idle_add failed");
619                 delete holder;
620             }
621             ++itr;
622         }
623     } catch (const BasePlatformException &err) {
624         LOGE("broadcastWifiNetworkChanged failed, %s: %s", err.getName().c_str(),
625                 err.getMessage().c_str());
626     } catch (...) {
627         LOGE("broadcastWifiNetworkChanged failed");
628     }
629 }
630 #else
631 void SystemInfo::broadcastWifiNetworkChanged()
632 {
633     LOGD("Entered");
634     //Not supported
635 }
636 #endif
637 void SystemInfo::broadcastNetworkTypeChanged()
638 {
639     LOGD("Entered");
640     try {
641         SystemInfoPropertyPtr property(new SystemInfoNetwork());
642
643         PVCLmap::iterator itr = m_network_callbacks.begin();
644
645         while (itr != m_network_callbacks.end()) {
646             PropertyCallbackDataPtr callback = itr->second;
647             callback->setNativeProperty(property);
648
649             PropertyCallbackDataHolder* holder = new(std::nothrow) PropertyCallbackDataHolder();
650             if (!holder) {
651                 std::string log_msg = "Failed to allocate memory";
652                 LOGE("%s", log_msg.c_str());
653                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
654             }
655             holder->ptr = callback;
656
657             guint id = g_idle_add(getPropertyValueCallback, holder);
658             if (!id) {
659                 LOGE("g_idle_add failed");
660                 delete holder;
661             }
662             ++itr;
663         }
664     } catch (const BasePlatformException &err) {
665         LOGE("broadcastWifiNetworkChanged failed, %s: %s", err.getName().c_str(),
666                 err.getMessage().c_str());
667     } catch (...) {
668         LOGE("broadcastWifiNetworkChanged failed");
669     }
670 }
671
672 void SystemInfo::getPropertyValueThread(gpointer data, gpointer user_data)
673 {
674     LOGD("Entered");
675
676     auto holder = static_cast<PropertyCallbackDataHolder*>(data);
677     if (!holder) {
678         LOGE("callback holder is null");
679         return;
680     }
681     auto callback = holder->ptr;
682     if (!callback) {
683         LOGE("callback is null");
684         delete holder;
685         holder = NULL;
686         return;
687     }
688
689     bool add_to_idle = false;
690     int modemNum = 0;
691
692     try {
693         SystemInfoPropertyPtr property;
694
695         switch (callback->getPropertyId()) {
696             case SystemInfoPropertyId::BATTERY:
697                 property.reset(new SystemInfoBattery());
698                 break;
699             case SystemInfoPropertyId::CPU:
700                 property = createSystemInfoCpu();
701                 break;
702             case SystemInfoPropertyId::STORAGE:
703                 property.reset(new SystemInfoStorage());
704                 break;
705             case SystemInfoPropertyId::DISPLAY:
706                 property.reset(new SystemInfoDisplay());
707                 break;
708             case SystemInfoPropertyId::DEVICE_ORIENTATION:
709                 property.reset(new SystemInfoDeviceOrientation());
710                 break;
711             case SystemInfoPropertyId::BUILD:
712                 property.reset(new SystemInfoBuild());
713                 break;
714             case SystemInfoPropertyId::LOCALE:
715                 property.reset(new SystemInfoLocale());
716                 break;
717             case SystemInfoPropertyId::NETWORK:
718                 property.reset(new SystemInfoNetwork());
719                 break;
720 #ifdef FEATURE_OPTIONAL_WI_FI
721             case SystemInfoPropertyId::WIFI_NETWORK:
722                 property.reset(new SystemInfoWifiNetwork());
723                 break;
724 #endif
725             case SystemInfoPropertyId::CELLULAR_NETWORK: {
726                 if (SystemInfo::getInstance().m_is_telephony_enable) {
727                     property.reset(new SystemInfoCellularNetwork());
728                     break;
729                 }
730                 std::string log_msg = "Not supported property";
731                 LOGE("%s", log_msg.c_str());
732                 SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
733             }
734             case SystemInfoPropertyId::SIM: {
735                 if (SystemInfo::getInstance().m_is_telephony_enable) {
736                     if (!(getInstance().m_tapi_handle[0])) {
737                         getInstance().setTapiHandles();
738                     }
739                     modemNum = 0;
740                     callback->clearArray();
741                     while (modemNum < TAPI_HANDLE_MAX) {
742                         property.reset(new SystemInfoSIM(getInstance().m_tapi_handle[modemNum]));
743                         if (property) {
744                             SystemInfoPropertyHolder *propertyHolder =
745                                     new (std::nothrow) SystemInfoPropertyHolder();
746                             propertyHolder->ptr = property;
747                             callback->addNativeProperty(propertyHolder);
748                         } else {
749                             std::string log_msg = "Failed to create property object";
750                             LOGE("%s", log_msg.c_str());
751                             SystemInfoUtil::throwSystemInfoException(0, log_msg);
752                         }
753                         modemNum++;
754                     }
755                     add_to_idle = callback->isPropertyReady();
756                     break;
757                 }
758                 std::string log_msg = "Not supported property";
759                 LOGE("%s", log_msg.c_str());
760                 SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
761             }
762             case SystemInfoPropertyId::PERIPHERAL:
763                 property.reset(new SystemInfoPeripheral());
764                 break;
765             case SystemInfoPropertyId::MEMORY:
766                 property.reset(new SystemInfoMemory());
767                 break;
768             default:
769                 std::string log_msg = "Not supported property";
770                 LOGE("%s", log_msg.c_str());
771                 SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
772         }
773         if (callback->isArrayEmpty()) {
774             if (property) {
775                 callback->setNativeProperty(property);
776                 add_to_idle = callback->isPropertyReady();
777             } else {
778                 std::string log_msg = "Failed to create property object";
779                 LOGE("%s", log_msg.c_str());
780                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
781             }
782         }
783     } catch (const BasePlatformException &err) {
784         LOGE("getPropertyValueThread fails, %s: %s", err.getName().c_str(),
785                 err.getMessage().c_str());
786         callback->setError(err.getName(), err.getMessage());
787         add_to_idle = true;
788     } catch (...) {
789         LOGE("getPropertyValueThread fails");
790         callback->setError("UnknownError", "getPropertyValueThread fails");
791         add_to_idle = true;
792     }
793
794     if (add_to_idle) {
795         if (callback->isError()) {
796             if (!g_idle_add(complete, data)) {
797                 LOGE("g_idle_add fails");
798                 delete holder;
799                 holder = NULL;
800             }
801         } else {
802             if (!g_idle_add(getPropertyValueCallback, data)) {
803                 LOGE("g_idle_add fails");
804                 delete holder;
805                 holder = NULL;
806             }
807         }
808     } else {
809         LOGD("Property is being processed, not calling js callback");
810         getInstance().addProcessingProperty(holder);
811     }
812     return;
813 }
814
815 void SystemInfo::getPropertyValue(PropertyCallbackDataPtr callback)
816 {
817     LOGD("Entered");
818     if (!callback) {
819         std::string log_msg = "callback is null";
820         LOGE("%s", log_msg.c_str());
821         SystemInfoUtil::throwSystemInfoException(0, log_msg);
822     }
823     PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
824     if (!holder) {
825         std::string log_msg = "Failed to allocate memory";
826         LOGE("%s", log_msg.c_str());
827         SystemInfoUtil::throwSystemInfoException(0, log_msg);
828     }
829     holder->ptr = callback;
830
831     if (!g_thread_pool_push(m_pool, static_cast<gpointer>(holder), NULL)) {
832         delete holder;
833         holder = NULL;
834         std::string log_msg = "Failed to add task to thread pool";
835         LOGE("%s", log_msg.c_str());
836         SystemInfoUtil::throwSystemInfoException(0, log_msg);
837     }
838 }
839
840 unsigned long SystemInfo::addPropertyValueChangeListener(PropertyCallbackDataPtr callback)
841 {
842     LOGD("Entered");
843
844     JSContextRef context = callback->getContext();
845     if (!GlobalContextManager::getInstance()->isAliveGlobalContext(context)) {
846         LOGE("context was closed");
847         return 0;
848     }
849
850     //Register the successCallback to receive system events
851     //that the status of the requested properties may have changed.
852     //If property value is 'BUILD', listener would not be registered
853     unsigned long new_id = ++m_current_id;
854     std::pair<unsigned long, PropertyCallbackDataPtr> property_cb(new_id, callback);
855
856     // Check type of property for which listener should be registered
857     switch (callback->getPropertyId()) {
858         case SystemInfoPropertyId::BATTERY: {
859             m_battery_callbacks.insert(property_cb);
860             if (m_battery_callbacks.size() == 1) {
861                 registerVconfCallback(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
862                         SystemInfo::onBatteryChanged);
863                 registerVconfCallback(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
864                         SystemInfo::onBatteryChanged);
865             }
866             LOGD("Added callback for BATTERY, id: %d", new_id);
867             break;
868         }
869         case SystemInfoPropertyId::CPU: {
870             m_cpu_callbacks.insert(property_cb);
871             if (m_cpu_callbacks.size() == 1) {
872                 if (!m_cpu_timer) {
873                     LOGD("Creating timer for Cpu listener");
874                     m_cpu_timer = ecore_timer_add(PROPERTY_WATCHER_TIME, SystemInfo::onCpuChanged,
875                     NULL);
876                 } else {
877                     LOGE("Timer not created");
878                 }
879             }
880             LOGD("Added callback for CPU, id: %d", new_id);
881             break;
882         }
883         case SystemInfoPropertyId::STORAGE: {
884             m_storage_callbacks.insert(property_cb);
885             LOGD("m_storage_callbacks.size() = %d", m_storage_callbacks.size());
886             if (m_storage_callbacks.size() == 1) {
887                 registerVconfCallback(VCONFKEY_SYSMAN_MMC_STATUS, SystemInfo::mmcStatusChanged);
888                 if (!m_storage_timer) {
889                     LOGD("Creating timer for Storage listener");
890                     m_storage_timer = ecore_timer_add(PROPERTY_WATCHER_TIME,
891                             SystemInfo::onStorageChanged, NULL);
892                 } else {
893                     LOGE("Timer not created");
894                 }
895             }
896             LOGD("Added callback for STORAGE, id: %d", new_id);
897             break;
898         }
899         case SystemInfoPropertyId::DISPLAY: {
900             m_display_callbacks.insert(property_cb);
901             if (m_display_callbacks.size() == 1) {
902                 registerVconfCallback(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
903                         SystemInfo::onDisplayChanged);
904             }
905             LOGD("Added callback for DISPLAY, id: %d", new_id);
906             break;
907         }
908         case SystemInfoPropertyId::DEVICE_ORIENTATION: {
909             m_device_orientation_callbacks.insert(property_cb);
910             if (m_device_orientation_callbacks.size() == 1) {
911                 registerVconfCallback(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
912                         SystemInfo::onDeviceAutoRotationChanged);
913                 unsigned int interval = BASE_GATHERING_INTERVAL;
914                 if (!m_sensor_handle) {
915                     m_sensor_handle = SystemInfoDeviceOrientation::connectSensor();
916                 }
917                 int ret = sensord_register_event(m_sensor_handle, AUTO_ROTATION_EVENT_CHANGE_STATE,
918                         interval, 0, SystemInfo::onDeviceOrientationChanged, NULL);
919                 if (0 != ret) {
920                     LOGE("Failed to register auto rotation event listener");
921                 } else {
922                     LOGD("sensord_unregister_event succeed to gather data");
923                 }
924             }
925             LOGD("Added callback for DEVICE_ORIENTATION, id: %d", new_id);
926             break;
927         }
928         case SystemInfoPropertyId::BUILD: {
929             LOGD("BUILD property's value is a fixed value");
930             m_inactive_callbacks.insert(property_cb);
931             break;
932         }
933         case SystemInfoPropertyId::LOCALE: {
934             m_locale_callbacks.insert(property_cb);
935             if (m_locale_callbacks.size() == 1) {
936                 if (SYSTEM_SETTINGS_ERROR_NONE
937                         != system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY,
938                                 SystemInfo::onLocaleChanged, NULL)) {
939                     std::string log_msg = "Failed to register country change callback";
940                     LOGE("%s", log_msg.c_str());
941                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
942                 }
943                 if (SYSTEM_SETTINGS_ERROR_NONE
944                         != system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE,
945                                 SystemInfo::onLocaleChanged, NULL)) {
946                     std::string log_msg = "Failed to register language change callback";
947                     LOGE("%s", log_msg.c_str());
948                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
949                 }
950             }
951             LOGD("Added callback for LOCALE, id: %d", new_id);
952             break;
953         }
954         case SystemInfoPropertyId::NETWORK: {
955             connection_h connection;
956             int ret = connection_create(&connection);
957             if (ret == CONNECTION_ERROR_NONE) {
958                 LOGD("it support network connection.");
959                 m_network_callbacks.insert(property_cb);
960                 connection_destroy(connection);
961                 if (m_network_callbacks.size() == 1) {
962                     registerNetworkTypeChangeCallback();
963                 }
964
965             } else if(ret == CONNECTION_ERROR_NOT_SUPPORTED) {
966                 LOGD("it not support network connection.");
967                 m_inactive_callbacks.insert(property_cb);
968             } else {
969                 std::string log_msg = "Failed to register network type change callback";
970                 LOGE("%s", log_msg.c_str());
971                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
972             }
973
974             LOGD("Added callback for NETWORK, id: %d", new_id);
975             break;
976         }
977         case SystemInfoPropertyId::WIFI_NETWORK: {
978 #ifdef FEATURE_OPTIONAL_WI_FI
979             m_wifi_network_callbacks.insert(property_cb);
980             LOGD("Added callback for WIFI_NETWORK, id: %d", new_id);
981             //register callback if there were no callbacks in cellular and
982             //this was new callback for wifi
983             if (0 == m_cellular_network_callbacks.size() && 1 == m_wifi_network_callbacks.size()) {
984                 registerIpChangeCallback();
985             }
986 #else
987             LOGE("WIFI_NETWORK is not supported");
988             m_inactive_callbacks.insert(property_cb);
989             callback->setError(JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, "Not supported property");
990
991 #endif
992             break;
993         }
994         case SystemInfoPropertyId::CELLULAR_NETWORK: {
995             if (m_is_telephony_enable) {
996                 m_cellular_network_callbacks.insert(property_cb);
997                 LOGD("Added callback for CELLULAR_NETWORK, id: %d", new_id);
998                 if (1 == m_cellular_network_callbacks.size()) {
999                     if (0 == m_wifi_network_callbacks.size()) {
1000                         //register callback if there were no callbacks in wifi and
1001                         //this was new callback for cellular
1002                         registerIpChangeCallback();
1003                     }
1004                     registerVconfCallback(VCONFKEY_TELEPHONY_FLIGHT_MODE,
1005                             onConnectionNetworkParamChanged);
1006                     registerVconfCallback(VCONFKEY_TELEPHONY_CELLID, onConnectionNetworkParamChanged);
1007                     registerVconfCallback(VCONFKEY_TELEPHONY_LAC, onConnectionNetworkParamChanged);
1008                     registerVconfCallback(VCONFKEY_TELEPHONY_SVC_ROAM, onConnectionNetworkParamChanged);
1009                 }
1010             } else {
1011                 LOGE("CELLULAR_NETWORK is not supported");
1012                 m_inactive_callbacks.insert(property_cb);
1013                 callback->setError(JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, "Not supported property");
1014             }
1015             break;
1016         }
1017         case SystemInfoPropertyId::SIM: {
1018             if (m_is_telephony_enable) {
1019                 //SIM listeners are not supported by core API, so we just
1020                 //store callback
1021                 m_sim_callbacks.insert(property_cb);
1022                 LOGD("Added callback for SIM, id: %d", new_id);
1023             } else {
1024                 LOGE("SIM is not supported");
1025                 m_inactive_callbacks.insert(property_cb);
1026                 callback->setError(JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR, "Not supported property");
1027             }
1028             break;
1029         }
1030         case SystemInfoPropertyId::PERIPHERAL: {
1031             m_peripheral_callbacks.insert(property_cb);
1032             if (m_peripheral_callbacks.size() == 1) {
1033                 /*check if the key exists.*/
1034                 int value = 0;
1035                 if (vconf_get_int(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &value) != -1) {
1036                     registerVconfCallback(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS,
1037                             SystemInfo::onPeripheralChanged);
1038                 }
1039                 if (vconf_get_int(VCONFKEY_SYSMAN_HDMI, &value) != -1) {
1040                     registerVconfCallback(VCONFKEY_SYSMAN_HDMI, SystemInfo::onPeripheralChanged);
1041                 }
1042                 if (vconf_get_int(VCONFKEY_POPSYNC_ACTIVATED_KEY, &value) != -1) {
1043                     registerVconfCallback(VCONFKEY_POPSYNC_ACTIVATED_KEY,
1044                             SystemInfo::onPeripheralChanged);
1045                 }
1046             }
1047             LOGD("Added callback for PERIPHERAL, id: %d", new_id);
1048             break;
1049         }
1050         case SystemInfoPropertyId::MEMORY: {
1051             m_memory_callbacks.insert(property_cb);
1052             if (m_memory_callbacks.size() == 1) {
1053                 /*check if the key exists.*/
1054                 int value = 0;
1055                 if (vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &value) != -1) {
1056                     registerVconfCallback(VCONFKEY_SYSMAN_LOW_MEMORY, SystemInfo::onMemoryChanged);
1057                 }
1058             }
1059             LOGD("Added callback for MEMORY, id: %d", new_id);
1060             break;
1061         }
1062         default:
1063             std::string log_msg = "Not supported property";
1064             LOGE("%s", log_msg.c_str());
1065             SystemInfoUtil::throwSystemInfoException<NotSupportedException>(0, log_msg);
1066     }
1067     startPropertyWatcherTimer(new_id, callback->getOptions().timeout);
1068
1069     PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1070     if (!holder) {
1071         std::string log_msg = "Failed to allocate memory";
1072         LOGE("%s", log_msg.c_str());
1073         SystemInfoUtil::throwSystemInfoException(0, log_msg);
1074     }
1075     holder->ptr = callback;
1076
1077     if (!g_idle_add(complete, holder)) {
1078         LOGE("g_idle addition failed");
1079     }
1080
1081     return new_id;
1082 }
1083
1084 Eina_Bool SystemInfo::onCpuChanged(void* _event_ptr)
1085 {
1086     LOGD("Entered");
1087     SystemInfo::getInstance().broadcastCpuChanged();
1088     return ECORE_CALLBACK_RENEW;
1089 }
1090
1091 void SystemInfo::broadcastCpuChanged()
1092 {
1093     LOGD("Entered");
1094
1095     try {
1096         PVCLmap::iterator itr = m_cpu_callbacks.begin();
1097
1098         SystemInfoCpuPtr cpu = createSystemInfoCpu();
1099         double load = cpu->getLoad();
1100         if (load == m_cpu_last_load)
1101             return;
1102
1103         m_cpu_last_load = load;
1104
1105         while (itr != m_cpu_callbacks.end()) {
1106             PropertyCallbackDataPtr callback = itr->second;
1107
1108             SystemInfoOptions opt = callback->getOptions();
1109             if (((opt.high_threshold == 0) && (opt.low_threshold == 0))
1110                     || ((opt.high_threshold > 0) && (load >= opt.high_threshold))
1111                     || ((opt.low_threshold > 0) && (load <= opt.low_threshold))) {
1112                 callback->setNativeProperty(cpu);
1113
1114                 PropertyCallbackDataHolder* holder =
1115                         new (std::nothrow) PropertyCallbackDataHolder();
1116                 if (!holder) {
1117                     std::string log_msg = "Failed to allocate memory";
1118                     LOGE("%s", log_msg.c_str());
1119                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
1120                 }
1121                 holder->ptr = callback;
1122
1123                 guint id = g_idle_add(getPropertyValueCallback, holder);
1124                 if (!id) {
1125                     LOGE("g_idle_add fails");
1126                     delete holder;
1127                 }
1128             }
1129             ++itr;
1130         }
1131     } catch (const BasePlatformException &err) {
1132         LOGE("getCpuValue fails, %s: %s", err.getName().c_str(), err.getMessage().c_str());
1133     } catch (...) {
1134         LOGE("getCpuValue fails");
1135     }
1136 }
1137
1138 void SystemInfo::removePropertyValueChangeListener(JSContextRef context, unsigned long id)
1139 {
1140     LOGD("Entered");
1141
1142     JSContextRef g_ctx = NULL;
1143     bool on_timeout = false;
1144     if (context != NULL) {
1145         g_ctx = Common::GlobalContextManager::getInstance()->getGlobalContext(context);
1146     } else {
1147         //it is call from onPropertyWatcherTimeout, context will not be checked
1148         on_timeout = true;
1149     }
1150
1151     if (m_battery_callbacks.find(id) != m_battery_callbacks.end()) {
1152         if (on_timeout || m_battery_callbacks[id]->getContext() == g_ctx) {
1153             stopPropertyWatcherTimer(id);
1154             m_battery_callbacks[id]->setActive(false);
1155             m_battery_callbacks.erase(id);
1156             if (m_battery_callbacks.empty()) {
1157                 unregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
1158                         SystemInfo::onBatteryChanged);
1159                 unregisterVconfCallback(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
1160                         SystemInfo::onBatteryChanged);
1161             }
1162         } else {
1163             std::string log_msg = "Removing callbacks from another context is not allowed";
1164             LOGE("%s", log_msg.c_str());
1165             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1166         }
1167     } else if (m_storage_callbacks.find(id) != m_storage_callbacks.end()) {
1168         if (on_timeout || m_storage_callbacks[id]->getContext() == g_ctx) {
1169             stopPropertyWatcherTimer(id);
1170             m_storage_callbacks[id]->setActive(false);
1171             m_storage_callbacks.erase(id);
1172             if (m_storage_callbacks.empty()) {
1173                 unregisterVconfCallback(VCONFKEY_SYSMAN_MMC_STATUS, SystemInfo::mmcStatusChanged);
1174                 stopAndDestroyTimer(&m_storage_timer, std::string("Storage"));
1175             }
1176         } else {
1177             std::string log_msg = "Removing callbacks from another context is not allowed";
1178             LOGE("%s", log_msg.c_str());
1179             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1180         }
1181     } else if (m_cpu_callbacks.find(id) != m_cpu_callbacks.end()) {
1182         if (on_timeout || m_cpu_callbacks[id]->getContext() == g_ctx) {
1183             stopPropertyWatcherTimer(id);
1184             m_cpu_callbacks[id]->setActive(false);
1185             m_cpu_callbacks.erase(id);
1186             if (m_cpu_callbacks.empty()) {
1187                 stopAndDestroyTimer(&m_cpu_timer, std::string("Cpu"));
1188             }
1189         } else {
1190             std::string log_msg = "Removing callbacks from another context is not allowed";
1191             LOGE("%s", log_msg.c_str());
1192             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1193         }
1194     } else if (m_display_callbacks.find(id) != m_display_callbacks.end()) {
1195         if (on_timeout || m_display_callbacks[id]->getContext() == g_ctx) {
1196             stopPropertyWatcherTimer(id);
1197             m_display_callbacks[id]->setActive(false);
1198             m_display_callbacks.erase(id);
1199             if (m_display_callbacks.empty()) {
1200                 unregisterVconfCallback(VCONFKEY_SETAPPL_LCD_BRIGHTNESS,
1201                         SystemInfo::onDisplayChanged);
1202             }
1203         } else {
1204             std::string log_msg = "Removing callbacks from another context is not allowed";
1205             LOGE("%s", log_msg.c_str());
1206             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1207         }
1208     } else if (m_peripheral_callbacks.find(id) != m_peripheral_callbacks.end()) {
1209         if (on_timeout || m_peripheral_callbacks[id]->getContext() == g_ctx) {
1210             stopPropertyWatcherTimer(id);
1211             m_peripheral_callbacks[id]->setActive(false);
1212             m_peripheral_callbacks.erase(id);
1213             int value = 0;
1214             if (m_peripheral_callbacks.empty()) {
1215                 if (vconf_get_int(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS, &value) != -1) {
1216                     unregisterVconfCallback(VCONFKEY_MIRACAST_WFD_SOURCE_STATUS,
1217                             SystemInfo::onPeripheralChanged);
1218                 }
1219                 if (vconf_get_int(VCONFKEY_SYSMAN_HDMI, &value) != -1) {
1220                     unregisterVconfCallback(VCONFKEY_SYSMAN_HDMI, SystemInfo::onPeripheralChanged);
1221                 }
1222                 if (vconf_get_int(VCONFKEY_POPSYNC_ACTIVATED_KEY, &value) != -1) {
1223                     unregisterVconfCallback(VCONFKEY_POPSYNC_ACTIVATED_KEY,
1224                             SystemInfo::onPeripheralChanged);
1225                 }
1226             }
1227         } else {
1228             std::string log_msg = "Removing callbacks from another context is not allowed";
1229             LOGE("%s", log_msg.c_str());
1230             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1231         }
1232     } else if (m_device_orientation_callbacks.find(id) != m_device_orientation_callbacks.end()) {
1233         if (on_timeout || m_device_orientation_callbacks[id]->getContext() == g_ctx) {
1234             stopPropertyWatcherTimer(id);
1235             m_device_orientation_callbacks[id]->setActive(false);
1236             m_device_orientation_callbacks.erase(id);
1237             if (m_device_orientation_callbacks.empty()) {
1238                 unregisterVconfCallback(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
1239                         SystemInfo::onDeviceAutoRotationChanged);
1240                 sensord_unregister_event(m_sensor_handle, AUTO_ROTATION_EVENT_CHANGE_STATE);
1241             }
1242         } else {
1243             std::string log_msg = "Removing callbacks from another context is not allowed";
1244             LOGE("%s", log_msg.c_str());
1245             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1246         }
1247     } else if (m_locale_callbacks.find(id) != m_locale_callbacks.end()) {
1248         if (on_timeout || m_locale_callbacks[id]->getContext() == g_ctx) {
1249             stopPropertyWatcherTimer(id);
1250             m_locale_callbacks[id]->setActive(false);
1251             m_locale_callbacks.erase(id);
1252             if (m_locale_callbacks.empty()) {
1253                 if (SYSTEM_SETTINGS_ERROR_NONE
1254                         != system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_LANGUAGE)) {
1255                     LOGE("unregistration of language change callback failed");
1256                 }
1257                 if (SYSTEM_SETTINGS_ERROR_NONE
1258                         != system_settings_unset_changed_cb(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY)) {
1259                     LOGE("unregistration of country change callback failed");
1260                 }
1261             }
1262         } else {
1263             std::string log_msg = "Removing callbacks from another context is not allowed";
1264             LOGE("%s", log_msg.c_str());
1265             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1266         }
1267     } else if (m_network_callbacks.find(id) != m_network_callbacks.end()) {
1268         if (on_timeout || m_network_callbacks[id]->getContext() == g_ctx) {
1269             stopPropertyWatcherTimer(id);
1270             m_network_callbacks[id]->setActive(false);
1271             m_network_callbacks.erase(id);
1272             if (m_wifi_network_callbacks.empty() && m_cellular_network_callbacks.empty()) {
1273                 //wifi and cellular has common core callback
1274                 unregisterIpChangeCallback();
1275             }
1276             if (m_network_callbacks.empty()) {
1277                 LOGD("the native callback for NETWORK listeners will be removed.");
1278                 unregisterNetworkTypeChangeCallback();
1279             }
1280         } else {
1281             std::string log_msg = "Removing callbacks from another context is not allowed";
1282             LOGE("%s", log_msg.c_str());
1283             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1284         }
1285     }
1286 #ifdef FEATURE_OPTIONAL_WI_FI
1287     else if (m_wifi_network_callbacks.find(id) != m_wifi_network_callbacks.end()) {
1288         if (on_timeout || m_wifi_network_callbacks[id]->getContext() == g_ctx) {
1289             stopPropertyWatcherTimer(id);
1290             m_wifi_network_callbacks[id]->setActive(false);
1291             m_wifi_network_callbacks.erase(id);
1292             if (m_wifi_network_callbacks.empty()) {
1293                 if (m_cellular_network_callbacks.empty()) {
1294                     //wifi and cellular has common core callback
1295                     unregisterIpChangeCallback();
1296                 }
1297             }
1298         } else {
1299             std::string log_msg = "Removing callbacks from another context is not allowed";
1300             LOGE("%s", log_msg.c_str());
1301             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1302         }
1303     }
1304 #endif
1305     else if (m_is_telephony_enable && (m_cellular_network_callbacks.find(id) != m_cellular_network_callbacks.end())) {
1306         if (on_timeout || m_cellular_network_callbacks[id]->getContext() == g_ctx) {
1307             stopPropertyWatcherTimer(id);
1308             m_cellular_network_callbacks[id]->setActive(false);
1309             m_cellular_network_callbacks.erase(id);
1310             if (m_cellular_network_callbacks.empty()) {
1311                 if (m_wifi_network_callbacks.empty()) {
1312                     //wifi and cellular has common core callback
1313                     unregisterIpChangeCallback();
1314                 }
1315                 unregisterVconfCallback(VCONFKEY_TELEPHONY_FLIGHT_MODE,
1316                         onConnectionNetworkParamChanged);
1317                 unregisterVconfCallback(VCONFKEY_TELEPHONY_CELLID, onConnectionNetworkParamChanged);
1318                 unregisterVconfCallback(VCONFKEY_TELEPHONY_LAC, onConnectionNetworkParamChanged);
1319                 unregisterVconfCallback(VCONFKEY_TELEPHONY_SVC_ROAM,
1320                         onConnectionNetworkParamChanged);
1321             }
1322         } else {
1323             std::string log_msg = "Removing callbacks from another context is not allowed";
1324             LOGE("%s", log_msg.c_str());
1325             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1326         }
1327     } else if (m_is_telephony_enable && (m_sim_callbacks.find(id) != m_sim_callbacks.end())) {
1328         if (on_timeout || m_sim_callbacks[id]->getContext() == g_ctx) {
1329             stopPropertyWatcherTimer(id);
1330             m_sim_callbacks[id]->setActive(false);
1331             m_sim_callbacks.erase(id);
1332         } else {
1333             std::string log_msg = "Removing callbacks from another context is not allowed";
1334             LOGE("%s", log_msg.c_str());
1335             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1336         }
1337     } else if (m_memory_callbacks.find(id) != m_memory_callbacks.end()) {
1338         if (on_timeout || m_memory_callbacks[id]->getContext() == g_ctx) {
1339             stopPropertyWatcherTimer(id);
1340             m_memory_callbacks[id]->setActive(false);
1341             m_memory_callbacks.erase(id);
1342             if (m_memory_callbacks.empty()) {
1343                 unregisterVconfCallback(VCONFKEY_SYSMAN_LOW_MEMORY, SystemInfo::onMemoryChanged);
1344             }
1345         } else {
1346             std::string log_msg = "Removing callbacks from another context is not allowed";
1347             LOGE("%s", log_msg.c_str());
1348             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1349         }
1350     } else if (m_inactive_callbacks.find(id) != m_inactive_callbacks.end()) {
1351         if (on_timeout || m_inactive_callbacks[id]->getContext() == g_ctx) {
1352             stopPropertyWatcherTimer(id);
1353             m_inactive_callbacks[id]->setActive(false);
1354             m_inactive_callbacks.erase(id);
1355         } else {
1356             std::string log_msg = "Removing callbacks from another context is not allowed";
1357             LOGE("%s", log_msg.c_str());
1358             SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1359         }
1360     } else {
1361         std::string log_msg = "ListenerId: " + std::to_string(id) + " not found";
1362         LOGE("%s", log_msg.c_str());
1363         SystemInfoUtil::throwSystemInfoException<InvalidValuesException>(0, log_msg);
1364     }
1365     return;
1366 }
1367
1368 void SystemInfo::startPropertyWatcherTimer(unsigned long listener_id, unsigned long timeout)
1369 {
1370     LOGD("Entered");
1371
1372     if (timeout > 0) {
1373         double value = static_cast<double>(timeout) / 1000.0;
1374         unsigned long* id = new (std::nothrow) unsigned long(listener_id);
1375         if (!id) {
1376             std::string log_msg = "Failed to allocate memory";
1377             LOGE("%s", log_msg.c_str());
1378             SystemInfoUtil::throwSystemInfoException(0, log_msg);
1379         }
1380         Ecore_Timer* timer = ecore_timer_add(value, SystemInfo::onPropertyWatcherTimeout,
1381                 (void *) id);
1382         if (!timer) {
1383             std::string log_msg = "Failed to add timer for listener id";
1384             LOGE("%s, %d", log_msg.c_str(), listener_id);
1385             SystemInfoUtil::throwSystemInfoException(0, log_msg);
1386         }
1387         m_watcher_map[listener_id] = timer;
1388     }
1389 }
1390
1391 void SystemInfo::stopPropertyWatcherTimer(unsigned long listener_id)
1392 {
1393     LOGD("Entered");
1394
1395     std::map<unsigned long, Ecore_Timer*>::iterator watcher_it = m_watcher_map.find(listener_id);
1396     if (watcher_it != m_watcher_map.end()) {
1397         stopAndDestroyTimer(&watcher_it->second, std::to_string(watcher_it->first));
1398         m_watcher_map.erase(watcher_it);
1399     } else {
1400         LOGW("Timer not set for listener id: %u", listener_id);
1401     }
1402 }
1403
1404 Eina_Bool SystemInfo::onPropertyWatcherTimeout(void* event_ptr)
1405 {
1406     LOGD("Entered");
1407
1408     unsigned long *listener_id = static_cast<unsigned long*>(event_ptr);
1409     try {
1410         if (listener_id) {
1411             SystemInfo::getInstance().removePropertyValueChangeListener(NULL, *listener_id);
1412         } else {
1413             LOGE("Listener id is NULL");
1414         }
1415     } catch (...) {
1416         LOGE("Unexpected exception");
1417     }
1418     delete listener_id;
1419
1420     return ECORE_CALLBACK_CANCEL;
1421 }
1422
1423 void SystemInfo::onBatteryChanged(keynode_t *node, void *event_ptr)
1424 {
1425     LOGD("Entered");
1426
1427     SystemInfo::getInstance().broadcastBatteryChanged();
1428 }
1429
1430 void SystemInfo::broadcastBatteryChanged()
1431 {
1432     LOGD("Entered");
1433
1434     try {
1435         PVCLmap::iterator itr = m_battery_callbacks.begin();
1436
1437         while (itr != m_battery_callbacks.end()) {
1438             PropertyCallbackDataPtr callback = itr->second;
1439             SystemInfoBatteryPtr battery(new SystemInfoBattery());
1440             SystemInfoOptions opt = callback->getOptions();
1441             if (((opt.high_threshold == 0) && (opt.low_threshold == 0))
1442                     || ((opt.high_threshold > 0) && (battery->getLevel() >= opt.high_threshold))
1443                     || ((opt.low_threshold > 0) && (battery->getLevel() <= opt.low_threshold))) {
1444                 callback->setNativeProperty(battery);
1445
1446                 PropertyCallbackDataHolder* holder =
1447                         new (std::nothrow) PropertyCallbackDataHolder();
1448                 if (!holder) {
1449                     std::string log_msg = "Failed to allocate memory";
1450                     LOGE("%s", log_msg.c_str());
1451                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
1452                 }
1453                 holder->ptr = callback;
1454
1455                 guint id = g_idle_add(getPropertyValueCallback, holder);
1456                 if (!id) {
1457                     LOGE("g_idle_add fails");
1458                     delete holder;
1459                 }
1460             }
1461             ++itr;
1462         }
1463     } catch (const BasePlatformException &err) {
1464         LOGE("broadcastBatteryChanged fails, %s: %s", err.getName().c_str(),
1465                 err.getMessage().c_str());
1466     } catch (...) {
1467         LOGE("broadcastBatteryChanged fails");
1468     }
1469 }
1470
1471 Eina_Bool SystemInfo::onStorageChanged(void *event_ptr)
1472 {
1473     LOGD("Entered");
1474
1475     SystemInfo::getInstance().broadcastStorageChanged();
1476     return ECORE_CALLBACK_RENEW;
1477 }
1478
1479 void SystemInfo::mmcStatusChanged(keynode_t *node, void *event_ptr)
1480 {
1481     LOGD("Entered");
1482     SystemInfo::getInstance().broadcastStorageChanged();
1483 }
1484
1485 void SystemInfo::broadcastStorageChanged()
1486 {
1487     LOGD("Entered");
1488
1489     try {
1490         PVCLmap::iterator itr = m_storage_callbacks.begin();
1491
1492         SystemInfoStoragePtr storage(new SystemInfoStorage());
1493         if (last_storage) {
1494             if (*last_storage == *storage) {
1495                 LOGD("Storage didn't change. Returning.");
1496                 return;
1497             }
1498         }
1499         last_storage = storage;
1500
1501         while (itr != m_storage_callbacks.end()) {
1502             PropertyCallbackDataPtr callback = itr->second;
1503             callback->setNativeProperty(storage);
1504
1505             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1506             if (!holder) {
1507                 std::string log_msg = "Failed to allocate memory";
1508                 LOGE("%s", log_msg.c_str());
1509                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
1510             }
1511             holder->ptr = callback;
1512
1513             guint id = g_idle_add(getPropertyValueCallback, holder);
1514             if (!id) {
1515                 LOGE("g_idle_add failed");
1516                 delete holder;
1517             }
1518             ++itr;
1519         }
1520     } catch (const BasePlatformException &err) {
1521         LOGE("broadcastStorageChanged failed, %s: %s", err.getName().c_str(),
1522                 err.getMessage().c_str());
1523     } catch (...) {
1524         LOGE("broadcastStorageChanged failed");
1525     }
1526 }
1527
1528 void SystemInfo::onDisplayChanged(keynode_t *node, void *event_ptr)
1529 {
1530     LOGD("Entered");
1531
1532     SystemInfo::getInstance().broadcastDisplayChanged();
1533 }
1534
1535 void SystemInfo::broadcastDisplayChanged()
1536 {
1537     LOGD("Entered");
1538
1539     try {
1540         PVCLmap::iterator itr = m_display_callbacks.begin();
1541
1542         while (itr != m_display_callbacks.end()) {
1543             PropertyCallbackDataPtr callback = itr->second;
1544             SystemInfoDisplayPtr display(new SystemInfoDisplay());
1545             SystemInfoOptions opt = callback->getOptions();
1546             if (((opt.high_threshold == 0) && (opt.low_threshold == 0))
1547                     || ((opt.high_threshold > 0) && (display->getBrightness() >= opt.high_threshold))
1548                     || ((opt.low_threshold > 0) && (display->getBrightness() <= opt.low_threshold))) {
1549                 callback->setNativeProperty(display);
1550
1551                 PropertyCallbackDataHolder* holder =
1552                         new (std::nothrow) PropertyCallbackDataHolder();
1553                 if (!holder) {
1554                     std::string log_msg = "Failed to allocate memory";
1555                     LOGE("%s", log_msg.c_str());
1556                     SystemInfoUtil::throwSystemInfoException(0, log_msg);
1557                 }
1558                 holder->ptr = callback;
1559
1560                 guint id = g_idle_add(getPropertyValueCallback, holder);
1561                 if (!id) {
1562                     LOGE("g_idle_add failed");
1563                     delete holder;
1564                 }
1565             }
1566             ++itr;
1567         }
1568     } catch (const BasePlatformException &err) {
1569         LOGE("broadcastDisplayChanged failed, %s: %s", err.getName().c_str(),
1570                 err.getMessage().c_str());
1571     } catch (...) {
1572         LOGE("broadcastDisplayChanged failed");
1573     }
1574 }
1575
1576 void SystemInfo::onDeviceAutoRotationChanged(keynode_t *node, void *event_ptr)
1577 {
1578     LOGD("Entered");
1579     SystemInfo::getInstance().broadcastDeviceOrientationChanged();
1580 }
1581
1582 void SystemInfo::onDeviceOrientationChanged(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data)
1583 {
1584     LOGD("Entered");
1585     int rotation = 0;
1586
1587     LOGD("size of the data value array:%d", data->value_count);
1588     if (data->value_count > 0) {
1589         rotation = data->values[0];
1590         LOGD("ratation value : %d", rotation);
1591         if (rotation != AUTO_ROTATION_DEGREE_UNKNOWN) {
1592             SystemInfo::getInstance().broadcastDeviceOrientationChanged();
1593         }
1594     } else {
1595         LOGE("failed to get data : the size of array is less than 0");
1596     }
1597 }
1598
1599 void SystemInfo::broadcastDeviceOrientationChanged()
1600 {
1601     LOGD("Entered");
1602
1603     try {
1604         PVCLmap::iterator itr = m_device_orientation_callbacks.begin();
1605
1606         while (itr != m_device_orientation_callbacks.end()) {
1607             PropertyCallbackDataPtr callback = itr->second;
1608             SystemInfoDeviceOrientationPtr dev_orientation(new SystemInfoDeviceOrientation());
1609             callback->setNativeProperty(dev_orientation);
1610
1611             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1612             if (!holder) {
1613                 std::string log_msg = "Failed to allocate memory";
1614                 LOGE("%s", log_msg.c_str());
1615                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
1616             }
1617             holder->ptr = callback;
1618
1619             guint id = g_idle_add(getPropertyValueCallback, holder);
1620             if (!id) {
1621                 LOGE("g_idle_add failed");
1622                 delete holder;
1623             }
1624             ++itr;
1625         }
1626     } catch (const BasePlatformException &err) {
1627         LOGE("broadcastDeviceOrientationChanged failed, %s: %s", err.getName().c_str(),
1628                 err.getMessage().c_str());
1629     } catch (...) {
1630         LOGE("broadcastDeviceOrientationChanged failed");
1631     }
1632 }
1633
1634 void SystemInfo::onLocaleChanged(system_settings_key_e key, void* event_ptr)
1635 {
1636     LOGD("Entered");
1637
1638     SystemInfo::getInstance().broadcastLocaleChanged();
1639 }
1640
1641 void SystemInfo::broadcastLocaleChanged()
1642 {
1643     LOGD("Entered");
1644
1645     try {
1646         PVCLmap::iterator itr = m_locale_callbacks.begin();
1647
1648         while (itr != m_locale_callbacks.end()) {
1649             PropertyCallbackDataPtr callback = itr->second;
1650             SystemInfoLocalePtr locale(new SystemInfoLocale());
1651             callback->setNativeProperty(locale);
1652
1653             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1654             if (!holder) {
1655                 std::string log_msg = "Failed to allocate memory";
1656                 LOGE("%s", log_msg.c_str());
1657                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
1658             }
1659             holder->ptr = callback;
1660
1661             guint id = g_idle_add(getPropertyValueCallback, holder);
1662             if (!id) {
1663                 LOGE("g_idle_add failed");
1664                 delete holder;
1665             }
1666             ++itr;
1667         }
1668     } catch (const BasePlatformException &err) {
1669         LOGE("broadcastLocaleChanged failed, %s: %s", err.getName().c_str(),
1670                 err.getMessage().c_str());
1671     } catch (...) {
1672         LOGE("broadcastLocaleChanged failed");
1673     }
1674 }
1675
1676 SystemInfoCpuPtr SystemInfo::createSystemInfoCpu()
1677 {
1678     std::lock_guard < std::mutex > lock(m_cpu_info_lock);
1679     return std::make_shared < SystemInfoCpu > (m_cpu_info);
1680 }
1681
1682 void SystemInfo::stopAndDestroyTimer(Ecore_Timer ** _p_timer, const std::string & _msg)
1683 {
1684     if (_p_timer && *_p_timer) {
1685         LOGD("Deleting timer for %s listener", _msg.c_str());
1686         ecore_timer_del(*_p_timer);
1687         *_p_timer = NULL;
1688     } else {
1689         LOGD("Deleting timer for %s listener failed, timer already NULL", _msg.c_str());
1690     }
1691 }
1692
1693 void SystemInfo::onPeripheralChanged(keynode_t* /*node*/, void* /*event_ptr*/)
1694 {
1695     LOGD("Entered");
1696
1697     SystemInfo::getInstance().broadcastPeripheralChanged();
1698 }
1699
1700 void SystemInfo::broadcastPeripheralChanged()
1701 {
1702     LOGD("Entered");
1703
1704     try {
1705         PVCLmap::iterator itr = m_peripheral_callbacks.begin();
1706         SystemInfoPeripheralPtr p_peripheral(new SystemInfoPeripheral());
1707
1708         while (itr != m_peripheral_callbacks.end()) {
1709             PropertyCallbackDataPtr callback = itr->second;
1710             callback->setNativeProperty(p_peripheral);
1711
1712             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1713             if (!holder) {
1714                 std::string log_msg = "Failed to allocate memory";
1715                 LOGE("%s", log_msg.c_str());
1716                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
1717             }
1718             holder->ptr = callback;
1719
1720             guint id = g_idle_add(getPropertyValueCallback, holder);
1721             if (!id) {
1722                 LOGE("g_idle_add fails");
1723                 delete holder;
1724             }
1725             ++itr;
1726         }
1727     } catch (const BasePlatformException &err) {
1728         LOGE("broadcastPeripheralChanged fails, %s: %s", err.getName().c_str(),
1729                 err.getMessage().c_str());
1730     } catch (...) {
1731         LOGE("broadcastPeripheralChanged fails");
1732     }
1733 }
1734
1735 void SystemInfo::onMemoryChanged(keynode_t* /*node*/, void* /*event_ptr*/)
1736 {
1737     LOGD("Entered");
1738     SystemInfo::getInstance().broadcastMemoryChanged();
1739 }
1740
1741 void SystemInfo::broadcastMemoryChanged()
1742 {
1743     LOGD("Entered");
1744
1745     try {
1746         PVCLmap::iterator itr = m_memory_callbacks.begin();
1747         SystemInfoMemoryPtr p_memory(new SystemInfoMemory());
1748
1749         while (itr != m_memory_callbacks.end()) {
1750             PropertyCallbackDataPtr callback = itr->second;
1751             callback->setNativeProperty(p_memory);
1752
1753             PropertyCallbackDataHolder* holder = new (std::nothrow) PropertyCallbackDataHolder();
1754             if (!holder) {
1755                 std::string log_msg = "Failed to allocate memory";
1756                 LOGE("%s", log_msg.c_str());
1757                 SystemInfoUtil::throwSystemInfoException(0, log_msg);
1758             }
1759             holder->ptr = callback;
1760
1761             guint id = g_idle_add(getPropertyValueCallback, holder);
1762             if (!id) {
1763                 LOGE("g_idle_add fails");
1764                 delete holder;
1765             }
1766             ++itr;
1767         }
1768     } catch (const BasePlatformException &err) {
1769         LOGE("broadcastMemoryChanged fails, %s: %s", err.getName().c_str(),
1770                 err.getMessage().c_str());
1771     } catch (...) {
1772         LOGE("broadcastMemoryChanged fails");
1773     }
1774 }
1775
1776 void SystemInfo::registerVconfCallback(const char *in_key, vconf_callback_fn cb)
1777 {
1778     if (0 != vconf_notify_key_changed(in_key, cb, NULL)) {
1779         std::string log_msg = "Failed to register vconf callback";
1780         LOGE("%s, %s", log_msg.c_str(), in_key);
1781         SystemInfoUtil::throwSystemInfoException(0, log_msg);
1782     }
1783 }
1784
1785 void SystemInfo::unregisterVconfCallback(const char *in_key, vconf_callback_fn cb)
1786 {
1787     if (0 != vconf_ignore_key_changed(in_key, cb)) {
1788         std::string log_msg = "Failed to unregister vconf callback";
1789         LOGE("%s, %s", log_msg.c_str(), in_key);
1790         SystemInfoUtil::throwSystemInfoException(0, log_msg);
1791     }
1792 }
1793
1794 gboolean SystemInfo::complete(void *data)
1795 {
1796     LOGD("Entered");
1797
1798     auto holder = static_cast<PropertyCallbackDataHolder*>(data);
1799     if (!holder) {
1800         LOGE("callback holder is null");
1801         return false;
1802     }
1803     auto callback = holder->ptr;
1804     if (!callback) {
1805         LOGE("callback is null");
1806         delete holder;
1807         holder = NULL;
1808         return false;
1809     }
1810
1811     JSContextRef context = callback->getContext();
1812
1813     if (callback->isError()) {
1814         LOGD("ErrorCallback triggered");
1815         JSObjectRef error = JSWebAPIErrorFactory::makeErrorObject(context, callback->getErrorName(),
1816                 callback->getErrorMessage());
1817         callback->callErrorCallback(error);
1818     }
1819
1820     delete holder;
1821     holder = NULL;
1822
1823     return false;
1824 }
1825
1826 void SystemInfo::setTapiHandles()
1827 {
1828     LOGD("Entered");
1829
1830     char **cp_list = NULL;
1831     unsigned int modem_num = 0;
1832
1833     cp_list = tel_get_cp_name_list();
1834
1835     if (cp_list != NULL) {
1836         while (cp_list[modem_num]) {
1837             LOGD("cp_name = %s", cp_list[modem_num]);
1838             m_tapi_handle[modem_num] = tel_init(cp_list[modem_num]);
1839             if (m_tapi_handle[modem_num] == NULL) {
1840                 LOGE("Failed to connect with tapi, handle is null");
1841             }
1842             modem_num++;
1843         }
1844     } else {
1845         LOGE("Failed to get cp list");
1846     }
1847     g_strfreev(cp_list);
1848
1849     return;
1850 }
1851
1852
1853 } // SystemInfo
1854 } // DeviceAPI