wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / Systeminfo / EventWatchSysteminfo.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 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 <CommonsJavaScript/Converter.h>
19 #include <Commons/Exception.h>
20 #include "EventWatchSysteminfo.h"
21 #include "Systeminfo.h"
22
23 namespace DeviceAPI {
24 namespace Systeminfo {
25
26 using namespace WrtDeviceApis::CommonsJavaScript;
27 using namespace WrtDeviceApis::Commons;
28
29 namespace {
30
31 static Eina_Bool timeout_timer_cb(void* data)
32 {
33     LoggerD("enter");
34     EventWatchSysteminfo *event = static_cast<EventWatchSysteminfo *> (data);
35     event->timeoutWatch();
36     return ECORE_CALLBACK_RENEW;
37 }
38
39 }
40
41 #define MAX_STORAGE_CNT 3
42 DPL::Atomic EventWatchSysteminfo::m_uniqId = 1;
43
44 EventWatchSysteminfo::EventWatchSysteminfo() : m_id(m_uniqId)
45 {
46     m_initTimer = NULL;
47     m_canceled = false;
48     m_lastValue = NULL;
49     m_storageCnt = 0;
50     m_tmpStorageCnt = 0;
51     m_Systeminfo = NULL;
52     ++m_uniqId;
53 }
54
55 EventWatchSysteminfo::~EventWatchSysteminfo()
56 {
57     if(m_lastValue)
58     {
59         JSCallbackManagerPtr m_cbm = DPL::StaticPointerCast< JSCallbackManager >(getPrivateData());
60         JSValueUnprotect(m_cbm->getContext(), m_lastValue);
61     }
62     LoggerD("destroy event data, id=" << m_id);
63     removeTimer();
64 }
65
66 void EventWatchSysteminfo::setWatchOption(const WatchOption& watchoption) {
67     m_WatchOption = watchoption;
68 }
69
70 WatchOption EventWatchSysteminfo::getWatchOption() {
71     return m_WatchOption;
72 }
73
74 JSCallbackManagerPtr EventWatchSysteminfo::getCallbackManager() {
75     return DPL::StaticPointerCast< JSCallbackManager >(getPrivateData());
76 }
77
78 BasePropertyPtr EventWatchSysteminfo::getBasePropertyPtr() {
79     return m_BaseProperty;
80 }
81
82 void EventWatchSysteminfo::setSysteminfoPtr(void* SysteminfoPtr) {
83     m_Systeminfo = SysteminfoPtr;
84 }
85
86 void EventWatchSysteminfo::setBasePropertyPtr(const BasePropertyPtr& baseProperty) {
87     m_BaseProperty = baseProperty;
88 }
89
90 const char * EventWatchSysteminfo::getProperty() const {
91     return m_BaseProperty->getProperty();
92 }
93
94 const int EventWatchSysteminfo::getWatchType() const {
95     return m_BaseProperty->getWatchType();
96 }
97
98 void EventWatchSysteminfo::getWatchValue(int cnt)
99 {
100     LoggerD("enter");
101     m_tmpStorageCnt = cnt;
102     processGetValue();
103 }
104
105 int EventWatchSysteminfo::getId() const
106 {
107     return m_id;
108 }
109
110 void EventWatchSysteminfo::setId(int id)
111 {
112     m_id = id;
113 }
114
115 JSValueRef EventWatchSysteminfo::getPropertyValue(JSContextRef context, JSValueRef value, std::string key)
116 {
117     JSObjectRef object = NULL;
118     JSValueRef* exception = NULL;
119     JSStringRef propertyName = NULL;
120
121     object = JSValueToObject(context, value, exception);
122     propertyName = JSStringCreateWithUTF8CString(key.c_str());
123
124     return JSObjectGetProperty(context, object, propertyName, exception);
125 }
126
127 void EventWatchSysteminfo::processGetValue()
128 {
129     LoggerD("thread=" << DPL::Thread::GetCurrentThread());
130     if(m_canceled) {
131                 LoggerD("Watch event is cancelled aleardy.");
132         return;
133     }
134     if (m_Systeminfo == NULL) {
135         LoggerE("systeminfo pointer is not set");
136         return;
137     }
138
139     JSCallbackManagerPtr m_cbm = DPL::StaticPointerCast< JSCallbackManager >(getPrivateData());
140     JSContextRef context = m_cbm->getContext();
141     JSValueRef tmpValue = NULL;
142
143     if(!m_lastValue) {
144         m_lastValue = m_BaseProperty->getValue(context, (void*)((Systeminfo*)m_Systeminfo)->getConnectionHandle());
145         return;
146     }
147     else {
148         JSValueUnprotect(context, m_lastValue);
149     }
150
151     JSValueRef* exception = NULL;
152     if (m_BaseProperty->getWatchType() == WATCH_TYPE_CPU) {
153         tmpValue = ((Systeminfo*)m_Systeminfo)->getCpuValue(context);
154     } else {
155         tmpValue = m_BaseProperty->getValue(context, (void*)((Systeminfo*)m_Systeminfo)->getConnectionHandle());
156     }
157     Converter converter(context);
158
159     if (!tmpValue) {
160         return;
161     }
162     LoggerD("watchType : " << m_BaseProperty->getWatchType());
163
164     if (m_BaseProperty->getWatchType() == WATCH_TYPE_BATTERY) {
165         std::string key = "level";
166         JSValueRef propertyLevel = getPropertyValue(context, tmpValue, key);
167         double level = JSValueToNumber(context, propertyLevel, exception);
168         propertyLevel = getPropertyValue(context, m_lastValue, key);
169         double prevLevel = JSValueToNumber(context, propertyLevel, exception);
170
171         key = "isCharging";
172         JSValueRef propertyCharging = getPropertyValue(context, tmpValue, key);
173         bool isCharging = JSValueToBoolean(context, propertyCharging);
174         propertyCharging = getPropertyValue(context, m_lastValue, key);
175         bool prevIsCharging = JSValueToBoolean(context, propertyCharging);
176
177         if(level != prevLevel || isCharging != prevIsCharging) {
178             if (((m_WatchOption.highThreshold > 0) && (level > m_WatchOption.highThreshold))
179             || ((m_WatchOption.lowThreshold > 0) && (level < m_WatchOption.lowThreshold))
180             || ((m_WatchOption.highThreshold == 0) && (m_WatchOption.lowThreshold == 0))) {
181                 m_cbm->callOnSuccess(tmpValue);
182                 setTimer();
183             }
184         }
185         m_lastValue = tmpValue;
186     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_DISPLAY) {
187         std::string key = "brightness";
188         JSValueRef propertyBrightness = getPropertyValue(context, tmpValue, key);
189         double brightness = JSValueToNumber(context, propertyBrightness, exception);
190         propertyBrightness = getPropertyValue(context, m_lastValue, key);
191         double prevBrightness = JSValueToNumber(context, propertyBrightness, exception);
192
193         if(brightness != prevBrightness) {
194             if (((m_WatchOption.highThreshold > 0) && (brightness > m_WatchOption.highThreshold))
195                 || ((m_WatchOption.lowThreshold > 0) && (brightness < m_WatchOption.lowThreshold))
196                 || ((m_WatchOption.highThreshold == 0) && (m_WatchOption.lowThreshold == 0))) {
197                 m_cbm->callOnSuccess(tmpValue);
198                 setTimer();
199             }
200         }
201         m_lastValue = tmpValue;
202     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_WIFINETWORK) {
203         std::string key = "status";
204         JSValueRef propertyStatus = getPropertyValue(context, tmpValue, key);
205         JSStringRef status = JSValueToStringCopy(context, propertyStatus, exception);
206         propertyStatus = getPropertyValue(context, m_lastValue, key);
207         JSStringRef prevStatus = JSValueToStringCopy(context, propertyStatus, exception);
208
209         key = "ssid";
210         JSValueRef propertySsid = getPropertyValue(context, tmpValue, key);
211         JSStringRef ssid = JSValueToStringCopy(context, propertySsid, exception);
212         propertySsid = getPropertyValue(context, m_lastValue, key);
213         JSStringRef prevSsid = JSValueToStringCopy(context, propertySsid, exception);
214
215         key = "signalStrength";
216         JSValueRef propertySignalStrength = getPropertyValue(context, tmpValue, key);
217         double signalStrength = JSValueToNumber(context, propertySignalStrength, exception);
218         propertySignalStrength = getPropertyValue(context, m_lastValue, key);
219         double prevSignalStrength = JSValueToNumber(context, propertySignalStrength, exception);
220
221         if(!JSStringIsEqual(status,prevStatus) || !JSStringIsEqual(ssid,prevSsid) || signalStrength != prevSignalStrength) {
222             if (((m_WatchOption.highThreshold > 0) && (signalStrength > m_WatchOption.highThreshold))
223                 || ((m_WatchOption.lowThreshold > 0) && (signalStrength < m_WatchOption.lowThreshold))
224                 || ((m_WatchOption.highThreshold == 0) && (m_WatchOption.lowThreshold == 0))) {
225                 m_cbm->callOnSuccess(tmpValue);
226                 setTimer();
227             }
228         }
229         m_lastValue = tmpValue;
230     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_CELLULARNETWORK) {
231         std::string key = "status";
232         JSValueRef propertyStatus = getPropertyValue(context, tmpValue, key);
233         JSStringRef status = JSValueToStringCopy(context, propertyStatus, exception);
234         propertyStatus = getPropertyValue(context, m_lastValue, key);
235         JSStringRef prevStatus = JSValueToStringCopy(context, propertyStatus, exception);
236
237         key = "apn";
238         JSValueRef propertyApn = getPropertyValue(context, tmpValue, key);
239         JSStringRef apn = JSValueToStringCopy(context, propertyApn, exception);
240         propertyApn = getPropertyValue(context, m_lastValue, key);
241         JSStringRef prevApn = JSValueToStringCopy(context, propertyApn, exception);
242
243         key = "mcc";
244         JSValueRef propertyMcc = getPropertyValue(context, tmpValue, key);
245         double mcc = JSValueToNumber(context, propertyMcc, exception);
246         propertyMcc = getPropertyValue(context, m_lastValue, key);
247         double prevMcc = JSValueToNumber(context, propertyMcc, exception);
248
249         key = "mnc";
250         JSValueRef propertyMnc = getPropertyValue(context, tmpValue, key);
251         double mnc = JSValueToNumber(context, propertyMnc, exception);
252         propertyMnc = getPropertyValue(context, m_lastValue, key);
253         double prevMnc = JSValueToNumber(context, propertyMnc, exception);
254
255         key = "lac";
256         JSValueRef propertyLac = getPropertyValue(context, tmpValue, key);
257         JSStringRef lac = JSValueToStringCopy(context, propertyLac, exception);
258         propertyLac = getPropertyValue(context, m_lastValue, key);
259         JSStringRef prevLac = JSValueToStringCopy(context, propertyLac, exception);
260
261         key = "cellId";
262         JSValueRef propertyCellId = getPropertyValue(context, tmpValue, key);
263         JSStringRef cellId = JSValueToStringCopy(context, propertyCellId, exception);
264         propertyCellId = getPropertyValue(context, m_lastValue, key);
265         JSStringRef prevCellId = JSValueToStringCopy(context, propertyCellId, exception);
266
267         key = "isRoaming";
268         JSValueRef propertyRoam = getPropertyValue(context, tmpValue, key);
269         bool roam = JSValueToBoolean(context, propertyRoam);
270         propertyRoam = getPropertyValue(context, m_lastValue, key);
271         bool prevRoam = JSValueToBoolean(context, propertyRoam);
272
273         key = "isFlightMode";
274         JSValueRef propertyFlight = getPropertyValue(context, tmpValue, key);
275         bool flight = JSValueToBoolean(context, propertyFlight);
276         propertyFlight = getPropertyValue(context, m_lastValue, key);
277         bool prevFlight = JSValueToBoolean(context, propertyFlight);
278
279         if ( !JSStringIsEqual(status, prevStatus) || !JSStringIsEqual(apn, prevApn) || mcc != prevMcc || mnc != prevMnc
280             || roam != prevRoam || flight != prevFlight || !JSStringIsEqual(lac, prevLac) || !JSStringIsEqual(cellId, prevCellId)) {
281             m_cbm->callOnSuccess(tmpValue);
282             setTimer();
283         }
284         m_lastValue = tmpValue;
285     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_CPU) {
286         std::string key = "load";
287         JSValueRef propertyLoad = getPropertyValue(context, tmpValue, key);
288         double load = JSValueToNumber(context, propertyLoad, exception);
289         propertyLoad = getPropertyValue(context, m_lastValue, key);
290         double prevLoad = JSValueToNumber(context, propertyLoad, exception);
291
292         if(load != prevLoad) {
293             if (((m_WatchOption.highThreshold > 0) && (load > m_WatchOption.highThreshold))
294                 || ((m_WatchOption.lowThreshold > 0) && (load < m_WatchOption.lowThreshold))
295                 || ((m_WatchOption.highThreshold == 0) && (m_WatchOption.lowThreshold == 0))) {
296                 m_cbm->callOnSuccess(tmpValue);
297                 setTimer();
298             }
299         }
300         m_lastValue = tmpValue;
301     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_STORAGE) {
302         JSValueRef tmpValueList[MAX_STORAGE_CNT];
303         JSValueRef lastValueList[MAX_STORAGE_CNT];
304         if (m_tmpStorageCnt > MAX_STORAGE_CNT) {
305             Throw(Exception);
306         }
307
308         for (int i=0; i<m_tmpStorageCnt; i++) {
309             tmpValueList[i] = JSGetArrayElement(context, JSValueToObject(context, tmpValue, NULL), i);
310         }
311
312         for (int j=0; j<m_storageCnt; j++) {
313             lastValueList[j] = JSGetArrayElement(context, JSValueToObject(context, m_lastValue, NULL), j);
314         }
315
316         if (m_tmpStorageCnt == m_storageCnt) {
317             LoggerD("enter");
318             for (int i=0; i<m_tmpStorageCnt; i++) {
319                 LoggerD("enter");
320                 std::string key = "type";
321                 JSValueRef propertyType = getPropertyValue(context, tmpValueList[i], key);
322                 JSStringRef type = JSValueToStringCopy(context, propertyType, exception);
323                 propertyType = getPropertyValue(context, lastValueList[i], key);
324                 JSStringRef prevType = JSValueToStringCopy(context, propertyType, exception);
325
326                 key = "capacity";
327                 JSValueRef propertyCapacity = getPropertyValue(context, tmpValueList[i], key);
328                 double capacity = JSValueToNumber(context, propertyCapacity, exception);
329                 propertyCapacity = getPropertyValue(context, lastValueList[i], key);
330                 double prevCapacity = JSValueToNumber(context, propertyCapacity, exception);
331                 LoggerD("capacity : " << capacity << "prevCapacity : " << prevCapacity);
332
333                 key = "availableCapacity";
334                 JSValueRef propertyAvailableCapacity = getPropertyValue(context, tmpValueList[i], key);
335                 double availableCapacity = JSValueToNumber(context, propertyAvailableCapacity, exception);
336                 propertyAvailableCapacity = getPropertyValue(context, lastValueList[i], key);
337                 double prevAvailableCapacity = JSValueToNumber(context, propertyAvailableCapacity, exception);
338                 LoggerD("availableCapacity : " << availableCapacity << "prevAvailableCapacity : " << prevAvailableCapacity);
339
340                 key = "isRemoveable";
341                 JSValueRef propertyIsRemoveable = getPropertyValue(context, tmpValueList[i], key);
342                 bool isRemoveable = JSValueToBoolean(context, propertyIsRemoveable);
343                 propertyIsRemoveable = getPropertyValue(context, lastValueList[i], key);
344                 double prevIsRemoveable = JSValueToBoolean(context, propertyIsRemoveable);
345                 LoggerD("isRemoveable : " << propertyIsRemoveable << "prevIsRemoveable : " << prevIsRemoveable);
346
347                 if (!JSStringIsEqual(type, prevType) || capacity != prevCapacity || availableCapacity != prevAvailableCapacity
348                     || isRemoveable != prevIsRemoveable) {
349                     LoggerD("make callback");
350                     m_cbm->callOnSuccess(tmpValue);
351                     setTimer();
352                 }
353                 m_lastValue = tmpValue;
354             }
355         } else {
356             LoggerD("enter");
357             m_cbm->callOnSuccess(tmpValue);
358             m_storageCnt = m_tmpStorageCnt;
359             m_lastValue = tmpValue;
360             setTimer();
361         }
362     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_DEVICE_ORIENTATION) {
363         std::string key = "status";
364         JSValueRef propertyStatus = getPropertyValue(context, tmpValue, key);
365         double status = JSValueToNumber(context, propertyStatus, exception);
366         propertyStatus = getPropertyValue(context, m_lastValue, key);
367         double prevStatus = JSValueToNumber(context, propertyStatus, exception);
368         LoggerD("status : " << status << "prevStatus : " << prevStatus);
369         if (status != prevStatus) {
370             LoggerD("make callback");
371             m_cbm->callOnSuccess(tmpValue);
372             setTimer();
373         }
374         m_lastValue = tmpValue;
375     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_NETWORK) {
376         std::string key = "networkType";
377         JSValueRef propertyNetworkType = getPropertyValue(context, tmpValue, key);
378         JSStringRef networkType = JSValueToStringCopy(context, propertyNetworkType, exception);
379         propertyNetworkType = getPropertyValue(context, m_lastValue, key);
380         JSStringRef prevNetworkType = JSValueToStringCopy(context, propertyNetworkType, exception);
381         LoggerD("networkType : " << networkType << "prevNetworkType : " << prevNetworkType);
382         if (!JSStringIsEqual(networkType ,prevNetworkType)) {
383             LoggerD("make callback");
384             m_cbm->callOnSuccess(tmpValue);
385             setTimer();
386         }
387         m_lastValue = tmpValue;
388     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_LOCALE) {
389         std::string key = "country";
390         JSValueRef propertyCountry = getPropertyValue(context, tmpValue, key);
391         JSStringRef country = JSValueToStringCopy(context, propertyCountry, exception);
392         propertyCountry = getPropertyValue(context, m_lastValue, key);
393         JSStringRef prevCountry = JSValueToStringCopy(context, propertyCountry, exception);
394         LoggerD("country : " << country << " prevCountry : " << prevCountry);
395
396         key = "language";
397         JSValueRef propertyLanguage = getPropertyValue(context, tmpValue, key);
398         JSStringRef language = JSValueToStringCopy(context, propertyLanguage, exception);
399         propertyLanguage = getPropertyValue(context, m_lastValue, key);
400         JSStringRef prevLanguage = JSValueToStringCopy(context, propertyLanguage, exception);
401         LoggerD("language : " << language << " prevLanguage : " << prevLanguage);
402
403         if (!JSStringIsEqual(language, prevLanguage) || !JSStringIsEqual(country, prevCountry)) {
404             LoggerD("make callback");
405             m_cbm->callOnSuccess(tmpValue);
406             setTimer();
407         }
408         m_lastValue = tmpValue;
409     } else if (m_BaseProperty->getWatchType() == WATCH_TYPE_PERIPHERAL) {
410         std::string key = "isVideoOutputOn";
411         JSValueRef propertyisVideoOutputOn = getPropertyValue(context, tmpValue, key);
412         bool isVideoOutputOn = JSValueToBoolean(context, propertyisVideoOutputOn);
413         propertyisVideoOutputOn = getPropertyValue(context, m_lastValue, key);
414         bool prevIsVideoOutputOn = JSValueToBoolean(context, propertyisVideoOutputOn);
415
416         if(isVideoOutputOn != prevIsVideoOutputOn) {
417                 m_cbm->callOnSuccess(tmpValue);
418             setTimer();
419         }
420         m_lastValue = tmpValue;
421     }
422
423     JSValueProtect(context, m_lastValue);
424 }
425
426 void EventWatchSysteminfo::setTimer()
427 {
428     if (m_WatchOption.timeout > 0) {
429         if (m_initTimer) {
430             ecore_timer_freeze(m_initTimer);
431             ecore_timer_del(m_initTimer);
432             m_initTimer = NULL;
433         }
434         double value = m_WatchOption.timeout/(double)1000;
435         m_initTimer = ecore_timer_add(value, timeout_timer_cb, this);
436         ecore_timer_thaw(m_initTimer);
437     }
438 }
439
440 void EventWatchSysteminfo::removeTimer()
441 {
442     if (m_initTimer) {
443         ecore_timer_freeze(m_initTimer);
444         ecore_timer_del(m_initTimer);
445     }
446     m_initTimer = NULL;        
447 }
448
449 void EventWatchSysteminfo::clearWatch()
450 {
451     m_canceled = true;
452     removeTimer();
453     ((Systeminfo*)m_Systeminfo)->clearWatch(m_id);
454 }
455
456 void EventWatchSysteminfo::timeoutWatch()
457 {
458     clearWatch();
459 }
460
461 }
462 }