2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <CommonsJavaScript/Converter.h>
25 #include <CommonsJavaScript/Validator.h>
26 #include <CommonsJavaScript/JSUtils.h>
27 #include <CommonsJavaScript/JSDOMExceptionFactory.h>
29 #include <JSWebAPIException.h>
30 #include <ArgumentValidator.h>
33 #include <SecurityExceptions.h>
34 #include <Commons/Exception.h>
35 #include <Commons/Regex.h>
36 #include <JSTizenExceptionFactory.h>
37 #include <JSTizenException.h>
38 #include <JSApplicationControl.h>
39 #include <ApplicationControl.h>
40 #include <ApplicationConverter.h>
44 #include "plugin_config.h"
45 #include "AlarmConverter.h"
46 #include "JSAlarmAbsolute.h"
47 #include "AlarmAbsolute.h"
48 #include "JSAlarmRelative.h"
49 #include "AlarmRelative.h"
50 #include "JSAlarmManager.h"
52 #include <TimeTracer.h>
59 using namespace WrtDeviceApis::Commons;
60 using namespace WrtDeviceApis::CommonsJavaScript;
61 using namespace DeviceAPI::Common;
63 static bool alarm_iterate_callback(int alarm_id, void *user_data)
65 std::vector<int> *alarmIds = reinterpret_cast<std::vector<int>*>(user_data);
67 alarmIds->push_back(alarm_id);
71 JSClassRef JSAlarmManager::m_jsClassRef = NULL;
73 JSClassDefinition JSAlarmManager::m_jsClassInfo = {
75 kJSClassAttributeNone,
76 TIZEN_ALARM_INTERFACE,
85 NULL, //deleteProperty,Geolocation
86 NULL, //getPropertyNames,
93 JSStaticFunction JSAlarmManager::m_function[] = {
94 { ALARM_FUNCTION_API_ADD, JSAlarmManager::add,kJSPropertyAttributeNone },
95 { ALARM_FUNCTION_API_REMOVE, JSAlarmManager::remove,kJSPropertyAttributeNone },
96 { ALARM_FUNCTION_API_REMOVE_ALL, JSAlarmManager::removeAll,kJSPropertyAttributeNone },
97 { ALARM_FUNCTION_API_GET_ALL, JSAlarmManager::getAll,kJSPropertyAttributeNone },
98 { ALARM_FUNCTION_API_GET, JSAlarmManager::get,kJSPropertyAttributeNone },
102 JSStaticValue JSAlarmManager::m_property[] = {
103 { TIZEN_ALARM_CONSTANT_PERIOD_MINUTE, getProperty, NULL, kJSPropertyAttributeReadOnly },
104 { TIZEN_ALARM_CONSTANT_PERIOD_HOUR, getProperty, NULL, kJSPropertyAttributeReadOnly },
105 { TIZEN_ALARM_CONSTANT_PERIOD_DAY, getProperty, NULL, kJSPropertyAttributeReadOnly },
106 { TIZEN_ALARM_CONSTANT_PERIOD_WEEK, getProperty, NULL, kJSPropertyAttributeReadOnly },
110 const JSClassRef DLL_EXPORT JSAlarmManager::getClassRef()
113 m_jsClassRef = JSClassCreate(&m_jsClassInfo);
118 const JSClassDefinition* JSAlarmManager::getClassInfo()
120 return &m_jsClassInfo;
123 JSContextRef JSAlarmManager::gContext = NULL;
125 void JSAlarmManager::initialize(JSContextRef ctx, JSObjectRef object)
130 void JSAlarmManager::finalize(JSObjectRef object)
134 bool JSAlarmManager::hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception) {
135 return JSValueIsObjectOfClass(context, possibleInstance, getClassRef());
138 JSValueRef JSAlarmManager::add(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
140 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
145 std::string applicationId;
148 TIME_TRACER_ITEM_BEGIN("(add)ace_check", 0);
149 AceSecurityStatus status = ALARM_CHECK_ACCESS(ALARM_FUNCTION_API_ADD);
150 TIZEN_SYNC_ACCESS_HANDLER(status, ctx, exception);
151 TIME_TRACER_ITEM_END("(add)ace_check", 0);
154 ArgumentValidator validator(ctx, argumentCount, arguments);
155 AlarmConverter converter(ctx);
158 std::string appId = validator.toString(1);
161 JSObjectRef alarmObj = validator.toObject(0);
162 if (JSValueIsObjectOfClass(ctx, alarmObj, JSAlarmAbsolute::getClassRef())) {
164 JSAlarmAbsolutePriv *priv = static_cast<JSAlarmAbsolutePriv*>(JSObjectGetPrivate(alarmObj));
166 throw TypeMismatchException("Object is null.");
168 AlarmAbsolutePtr alarmPtr = priv->getObject();
170 throw TypeMismatchException("Private object is null.");
173 startDate = alarmPtr->getDate();
174 service = alarmPtr->getService();
175 service_set_app_id(service, appId.c_str());
178 JSObjectRef appControlObj = validator.toObject(2, true);
180 if(!JSValueIsObjectOfClass(ctx, appControlObj, DeviceAPI::Application::JSApplicationControl::getClassRef())) {
181 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
183 DeviceAPI::Application::ApplicationConverter applicationConverter(ctx);
184 DeviceAPI::Application::ApplicationControlPtr appService = applicationConverter.toApplicationControl(appControlObj);
185 if(converter.toAlarmService(service, appService) == false) {
186 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
189 service_set_operation(service, SERVICE_OPERATION_DEFAULT);
192 AbsoluteRecurrence::Type alarmType = alarmPtr->getRecurrenceType();
194 int err = ALARM_ERROR_NONE;
195 if(alarmType == AbsoluteRecurrence::ByDayValue) {
196 int bydayValue = converter.toNativeAlarmValue(alarmPtr->getByDayRecurrence());
197 LoggerI("Native bydayValue = " << bydayValue);
198 err = alarm_schedule_with_recurrence_week_flag(service, &startDate, bydayValue, &alarm_id);
199 } else if(alarmType == AbsoluteRecurrence::Interval) {
200 int interval = alarmPtr->getInterval();
201 err = alarm_schedule_at_date(service, &startDate, interval, &alarm_id);
203 err = alarm_schedule_at_date(service, &startDate, 0, &alarm_id);
206 if(err == ALARM_ERROR_NONE) {
207 alarmPtr->setId(alarm_id);
209 throw UnknownException("Alarm scheduling failed.");
212 } else if (JSValueIsObjectOfClass(ctx, alarmObj, JSAlarmRelative::getClassRef())) {
214 JSAlarmRelativePriv *priv = static_cast<JSAlarmRelativePriv*>(JSObjectGetPrivate(alarmObj));
216 throw TypeMismatchException("Object is null.");
218 AlarmRelativePtr alarmPtr = priv->getObject();
220 throw TypeMismatchException("Private object is null.");
223 delay = alarmPtr->getDelay();
224 long interval = alarmPtr->getPeriod();
225 service = alarmPtr->getService();
226 service_set_app_id(service, appId.c_str());
229 JSObjectRef appControlObj = validator.toObject(2, true);
231 if(!JSValueIsObjectOfClass(ctx, appControlObj, DeviceAPI::Application::JSApplicationControl::getClassRef())) {
232 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
234 DeviceAPI::Application::ApplicationConverter applicationConverter(ctx);
235 DeviceAPI::Application::ApplicationControlPtr appService = applicationConverter.toApplicationControl(appControlObj);
236 if(converter.toAlarmService(service, appService) == false) {
237 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
240 service_set_operation(service, SERVICE_OPERATION_DEFAULT);
243 int err = alarm_schedule_after_delay(service, delay, interval, &alarm_id);
245 if(err == ALARM_ERROR_NONE) {
246 alarmPtr->setId(alarm_id);
248 throw UnknownException("Alarm scheduling failed.");
252 LoggerE("First parameter is not a Alarm object");
253 throw TypeMismatchException("First parameter is not a Alarm object");
255 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
256 return JSValueMakeUndefined(ctx);
258 } catch (const BasePlatformException &err) {
259 return JSWebAPIException::throwException(ctx, exception, err);
261 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
262 return JSWebAPIException::throwException(ctx, exception, err);
266 JSValueRef JSAlarmManager::remove(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
268 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
269 AceSecurityStatus status = ALARM_CHECK_ACCESS(ALARM_FUNCTION_API_REMOVE);
270 TIZEN_SYNC_ACCESS_HANDLER(status, ctx, exception);
273 ArgumentValidator validator(ctx, argumentCount, arguments);
276 std::string id = validator.toString(0);
279 std::stringstream(id) >> alarmId;
282 throw InvalidValuesException("Invalid ID");
285 TIME_TRACER_ITEM_BEGIN("(remove)alarm_cancel", 0);
286 int ret = alarm_cancel(alarmId);
287 TIME_TRACER_ITEM_END("(remove)alarm_cancel", 0);
289 if (ret != ALARM_ERROR_NONE) {
290 throw NotFoundException("Alarm not found");
293 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
294 return JSValueMakeUndefined(ctx);
295 } catch (const BasePlatformException &err) {
296 return JSWebAPIException::throwException(ctx, exception, err);
298 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
299 return JSWebAPIException::throwException(ctx, exception, err);
303 JSValueRef JSAlarmManager::removeAll(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
305 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
306 AceSecurityStatus status = ALARM_CHECK_ACCESS(ALARM_FUNCTION_API_REMOVE_ALL);
307 TIZEN_SYNC_ACCESS_HANDLER(status, ctx, exception);
309 TIME_TRACER_ITEM_BEGIN("(removeAll)alarm_cancel_all", 0);
310 int returnVal = alarm_cancel_all();
311 TIME_TRACER_ITEM_END("(removeAll)alarm_cancel_all", 0);
313 if (ALARM_ERROR_NONE != returnVal) {
314 LoggerE("Error while removing all alarms: "<< returnVal);
317 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
318 return JSValueMakeUndefined(ctx);
321 JSValueRef JSAlarmManager::get(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
323 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
325 service_h service = NULL;
326 char* alarmType = NULL;
327 JSValueRef result = NULL;
329 ArgumentValidator validator(ctx, argumentCount, arguments);
330 AlarmConverter converter(ctx);
333 std::string id = validator.toString(0);
335 std::stringstream(id) >> alarmId;
338 LoggerE("Wrong Alarm ID");
339 throw InvalidValuesException("Invalid ID");
342 TIME_TRACER_ITEM_BEGIN("(get)alarm_get_service", 0);
343 int ret = alarm_get_service(alarmId, &service);
344 TIME_TRACER_ITEM_END("(get)alarm_get_service", 0);
346 if (ret != ALARM_ERROR_NONE) {
347 throw NotFoundException("Alarm not found");
350 ret = service_get_extra_data(service, ALARM_TYPE_KEY, &alarmType);
351 if (ret != SERVICE_ERROR_NONE) {
352 LoggerE("Getting data failed: " << ret);
353 service_destroy(service);
354 throw UnknownException("Unknown error occurred.");
357 if (strcmp(alarmType, ALARM_TYPE_ABSOLUTE_VALUE) == 0) {
358 AlarmAbsolutePtr privateData = AlarmAbsolutePtr(new AlarmAbsolute(service));
360 if(!converter.toAlarmAbsolutePtr(alarmId, service, privateData)) {
361 service_destroy(service);
362 throw TypeMismatchException("Alarm not found");
365 result = JSAlarmAbsolute::createJSObject(ctx, privateData);
367 } else if(strcmp(alarmType, ALARM_TYPE_RELATIVE_VALUE) == 0) {
368 AlarmRelativePtr privateData = AlarmRelativePtr(new AlarmRelative(service));
370 if(!converter.toAlarmRelativePtr(alarmId, service, privateData)) {
371 service_destroy(service);
372 throw TypeMismatchException("Alarm not found");
375 result = JSAlarmRelative::createJSObject(ctx, privateData);
377 service_destroy(service);
378 throw UnknownException("Unknown error occurred.");
381 service_destroy(service);
382 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
384 } catch (const BasePlatformException &err) {
385 return JSWebAPIException::throwException(ctx, exception, err);
387 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
388 return JSWebAPIException::throwException(ctx, exception, err);
393 JSValueRef JSAlarmManager::getAll(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
395 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
397 AlarmConverter converter(ctx);
398 std::vector<int> alarmIds;
400 int error = alarm_foreach_registered_alarm(alarm_iterate_callback, &alarmIds);
401 if (error == ALARM_ERROR_CONNECTION_FAIL) {
402 LoggerE("Alarm system may not be ready yet.");
404 } else if(error != ALARM_ERROR_NONE) {
405 LoggerE("Error occurred while getting all alarms : " << error);
406 throw UnknownException("Unknown error occurred.");
409 JSObjectRef jsResult = JSCreateArrayObject(ctx, 0, NULL);
410 if (jsResult == NULL) {
411 throw TypeMismatchException("Could not create js array object.");
414 for (size_t i = 0 ; i < alarmIds.size(); i++) {
416 service_h handle = NULL;
417 char* alarmType = NULL;
419 error = alarm_get_service(alarmIds.at(i), &handle);
420 if(error != ALARM_ERROR_NONE) {
421 LoggerE("Getting service failed: " << error);
422 throw NotFoundException("Alarm not found");
425 error = service_get_extra_data(handle, ALARM_TYPE_KEY, &alarmType);
426 if(error != SERVICE_ERROR_NONE) {
427 LoggerI("Getting data failed: " << error);
428 service_destroy(handle);
429 throw UnknownException("Unknown error occurred.");
432 JSValueRef obj = NULL;
433 if (strcmp(alarmType, ALARM_TYPE_ABSOLUTE_VALUE) == 0) {
434 AlarmAbsolutePtr privateData = AlarmAbsolutePtr(new AlarmAbsolute(handle));
436 if(!converter.toAlarmAbsolutePtr(alarmIds.at(i), handle, privateData)) {
437 service_destroy(handle);
438 throw TypeMismatchException("Absolute alarm conversion failed.");
441 obj = JSAlarmAbsolute::createJSObject(ctx, privateData);
443 } else if( !strcmp(alarmType, ALARM_TYPE_RELATIVE_VALUE)) {
444 AlarmRelativePtr privateData = AlarmRelativePtr(new AlarmRelative(handle));
446 if(!converter.toAlarmRelativePtr(alarmIds.at(i), handle, privateData)) {
447 service_destroy(handle);
448 throw TypeMismatchException("Relative alarm conversion failed.");
450 obj = JSAlarmRelative::createJSObject(ctx, privateData);
453 service_destroy(handle);
454 throw UnknownException("Unknown error occurred.");
457 service_destroy(handle);
459 if(!JSSetArrayElement(ctx, jsResult, i, obj)) {
460 service_destroy(handle);
461 throw UnknownException("JS array creation failed.");
465 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
467 } catch (const BasePlatformException &err) {
468 return JSWebAPIException::throwException(ctx, exception, err);
470 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
471 return JSWebAPIException::throwException(ctx, exception, err);
475 JSValueRef JSAlarmManager::getProperty(JSContextRef context,
477 JSStringRef propertyName,
478 JSValueRef* exception)
481 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_MINUTE)) {
482 return JSUtil::toJSValueRef(context, (long)60);
483 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_HOUR)) {
484 return JSUtil::toJSValueRef(context, (long)3600);
485 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_DAY)) {
486 return JSUtil::toJSValueRef(context, (long)86400);
487 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_WEEK)) {
488 return JSUtil::toJSValueRef(context, (long)604800);
490 } catch (const BasePlatformException &err) {
491 LoggerE("Getting property is failed. %s", err.getMessage().c_str());