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 <ArgumentValidator.h>
33 #include <SecurityExceptions.h>
34 #include <Commons/Exception.h>
35 #include <Commons/Regex.h>
36 #include <JSWebAPIErrorFactory.h>
37 #include <JSApplicationControl.h>
38 #include <ApplicationControl.h>
39 #include <ApplicationConverter.h>
43 #include "plugin_config_impl.h"
44 #include "AlarmConverter.h"
45 #include "JSAlarmAbsolute.h"
46 #include "AlarmAbsolute.h"
47 #include "JSAlarmRelative.h"
48 #include "AlarmRelative.h"
49 #include "JSAlarmManager.h"
51 #include <TimeTracer.h>
58 using namespace WrtDeviceApis::Commons;
59 using namespace WrtDeviceApis::CommonsJavaScript;
60 using namespace DeviceAPI::Common;
62 static bool alarm_iterate_callback(int alarm_id, void *user_data)
64 std::vector<int> *alarmIds = reinterpret_cast<std::vector<int>*>(user_data);
66 alarmIds->push_back(alarm_id);
70 JSClassRef JSAlarmManager::m_jsClassRef = NULL;
72 JSClassDefinition JSAlarmManager::m_jsClassInfo = {
74 kJSClassAttributeNone,
75 TIZEN_ALARM_INTERFACE,
84 NULL, //deleteProperty,Geolocation
85 NULL, //getPropertyNames,
92 JSStaticFunction JSAlarmManager::m_function[] = {
93 { ALARM_FUNCTION_API_ADD, JSAlarmManager::add,kJSPropertyAttributeNone },
94 { ALARM_FUNCTION_API_REMOVE, JSAlarmManager::remove,kJSPropertyAttributeNone },
95 { ALARM_FUNCTION_API_REMOVE_ALL, JSAlarmManager::removeAll,kJSPropertyAttributeNone },
96 { ALARM_FUNCTION_API_GET_ALL, JSAlarmManager::getAll,kJSPropertyAttributeNone },
97 { ALARM_FUNCTION_API_GET, JSAlarmManager::get,kJSPropertyAttributeNone },
101 JSStaticValue JSAlarmManager::m_property[] = {
102 { TIZEN_ALARM_CONSTANT_PERIOD_MINUTE, getProperty, NULL, kJSPropertyAttributeReadOnly },
103 { TIZEN_ALARM_CONSTANT_PERIOD_HOUR, getProperty, NULL, kJSPropertyAttributeReadOnly },
104 { TIZEN_ALARM_CONSTANT_PERIOD_DAY, getProperty, NULL, kJSPropertyAttributeReadOnly },
105 { TIZEN_ALARM_CONSTANT_PERIOD_WEEK, getProperty, NULL, kJSPropertyAttributeReadOnly },
109 const JSClassRef DLL_EXPORT JSAlarmManager::getClassRef()
112 m_jsClassRef = JSClassCreate(&m_jsClassInfo);
117 const JSClassDefinition* JSAlarmManager::getClassInfo()
119 return &m_jsClassInfo;
122 JSContextRef JSAlarmManager::gContext = NULL;
124 void JSAlarmManager::initialize(JSContextRef ctx, JSObjectRef object)
128 SecurityAccessor *priv = new SecurityAccessor();
129 JSObjectSetPrivate(object, static_cast<void*>(priv));
132 void JSAlarmManager::finalize(JSObjectRef object)
134 SecurityAccessor *priv = static_cast<SecurityAccessor*>(JSObjectGetPrivate(object));
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 SecurityAccessor *thisPriv = static_cast<SecurityAccessor*>(JSObjectGetPrivate(thisObject));
150 LoggerE("private object is null");
151 return JSWebAPIErrorFactory::postException(ctx, exception,
152 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
154 TIME_TRACER_ITEM_BEGIN("(add)ace_check", 0);
155 TIZEN_CHECK_ACCESS(ctx, exception, thisPriv, ALARM_FUNCTION_API_ADD);
156 TIME_TRACER_ITEM_END("(add)ace_check", 0);
159 ArgumentValidator validator(ctx, argumentCount, arguments);
160 AlarmConverter converter(ctx);
163 std::string appId = validator.toString(1);
166 JSObjectRef alarmObj = validator.toObject(0);
167 if (JSValueIsObjectOfClass(ctx, alarmObj, JSAlarmAbsolute::getClassRef())) {
169 JSAlarmAbsolutePriv *priv = static_cast<JSAlarmAbsolutePriv*>(JSObjectGetPrivate(alarmObj));
171 throw TypeMismatchException("Object is null.");
173 AlarmAbsolutePtr alarmPtr = priv->getObject();
175 throw TypeMismatchException("Private object is null.");
178 startDate = alarmPtr->getDate();
179 service = alarmPtr->getService();
180 service_set_app_id(service, appId.c_str());
183 JSObjectRef appControlObj = validator.toObject(2, true);
185 if(!JSValueIsObjectOfClass(ctx, appControlObj, DeviceAPI::Application::JSApplicationControl::getClassRef())) {
186 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
188 DeviceAPI::Application::ApplicationConverter applicationConverter(ctx);
189 DeviceAPI::Application::ApplicationControlPtr appService = applicationConverter.toApplicationControl(appControlObj);
190 if(converter.toAlarmService(service, appService) == false) {
191 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
194 service_set_operation(service, SERVICE_OPERATION_DEFAULT);
197 AbsoluteRecurrence::Type alarmType = alarmPtr->getRecurrenceType();
199 int err = ALARM_ERROR_NONE;
200 if(alarmType == AbsoluteRecurrence::ByDayValue) {
201 int bydayValue = converter.toNativeAlarmValue(alarmPtr->getByDayRecurrence());
202 LoggerI("Native bydayValue = " << bydayValue);
203 TIME_TRACER_ITEM_BEGIN("(add)alarm_schedule_with_recurrence_week_flag", 0);
204 err = alarm_schedule_with_recurrence_week_flag(service, &startDate, bydayValue, &alarm_id);
205 TIME_TRACER_ITEM_END("(add)alarm_schedule_with_recurrence_week_flag", 0);
207 } else if(alarmType == AbsoluteRecurrence::Interval) {
208 int interval = alarmPtr->getInterval();
209 TIME_TRACER_ITEM_BEGIN("(add)alarm_schedule_at_date", 0);
210 err = alarm_schedule_at_date(service, &startDate, interval, &alarm_id);
211 TIME_TRACER_ITEM_END("(add)alarm_schedule_at_date", 0);
213 TIME_TRACER_ITEM_BEGIN("(add)alarm_schedule_at_date", 0);
214 err = alarm_schedule_at_date(service, &startDate, 0, &alarm_id);
215 TIME_TRACER_ITEM_END("(add)alarm_schedule_at_date", 0);
218 if(err == ALARM_ERROR_NONE) {
219 alarmPtr->setId(alarm_id);
221 throw UnknownException("Alarm scheduling failed.");
224 } else if (JSValueIsObjectOfClass(ctx, alarmObj, JSAlarmRelative::getClassRef())) {
226 JSAlarmRelativePriv *priv = static_cast<JSAlarmRelativePriv*>(JSObjectGetPrivate(alarmObj));
228 throw TypeMismatchException("Object is null.");
230 AlarmRelativePtr alarmPtr = priv->getObject();
232 throw TypeMismatchException("Private object is null.");
235 delay = alarmPtr->getDelay();
237 throw InvalidValuesException("Alarm scheduling failed : delay cannot be negative value.");
240 long interval = alarmPtr->getPeriod();
241 service = alarmPtr->getService();
242 service_set_app_id(service, appId.c_str());
245 JSObjectRef appControlObj = validator.toObject(2, true);
247 if(!JSValueIsObjectOfClass(ctx, appControlObj, DeviceAPI::Application::JSApplicationControl::getClassRef())) {
248 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
250 DeviceAPI::Application::ApplicationConverter applicationConverter(ctx);
251 DeviceAPI::Application::ApplicationControlPtr appService = applicationConverter.toApplicationControl(appControlObj);
252 if(converter.toAlarmService(service, appService) == false) {
253 throw TypeMismatchException("Third parameter is not a ApplicationControl object");
256 service_set_operation(service, SERVICE_OPERATION_DEFAULT);
259 TIME_TRACER_ITEM_BEGIN("(add)alarm_schedule_after_delay", 0);
260 int err = alarm_schedule_after_delay(service, delay, interval, &alarm_id);
261 TIME_TRACER_ITEM_END("(add)alarm_schedule_after_delay", 0);
263 if(err == ALARM_ERROR_NONE) {
264 alarmPtr->setId(alarm_id);
266 throw UnknownException("Alarm scheduling failed.");
270 LoggerE("First parameter is not a Alarm object");
271 throw TypeMismatchException("First parameter is not a Alarm object");
273 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
274 return JSValueMakeUndefined(ctx);
276 } catch (const BasePlatformException &err) {
277 return JSWebAPIErrorFactory::postException(ctx, exception, err);
279 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
280 return JSWebAPIErrorFactory::postException(ctx, exception, err);
284 JSValueRef JSAlarmManager::remove(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
286 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
287 SecurityAccessor *thisPriv = static_cast<SecurityAccessor*>(JSObjectGetPrivate(thisObject));
289 LoggerE("private object is null");
290 return JSWebAPIErrorFactory::postException(ctx, exception,
291 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
293 TIME_TRACER_ITEM_BEGIN("(add)ace_check", 0);
294 TIZEN_CHECK_ACCESS(ctx, exception, thisPriv, ALARM_FUNCTION_API_REMOVE);
295 TIME_TRACER_ITEM_END("(add)ace_check", 0);
298 ArgumentValidator validator(ctx, argumentCount, arguments);
301 std::string id = validator.toString(0);
304 std::stringstream(id) >> alarmId;
307 throw InvalidValuesException("Invalid ID");
310 TIME_TRACER_ITEM_BEGIN("(remove)alarm_cancel", 0);
311 int ret = alarm_cancel(alarmId);
312 TIME_TRACER_ITEM_END("(remove)alarm_cancel", 0);
314 if (ret != ALARM_ERROR_NONE) {
315 throw NotFoundException("Alarm not found");
318 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
319 return JSValueMakeUndefined(ctx);
320 } catch (const BasePlatformException &err) {
321 return JSWebAPIErrorFactory::postException(ctx, exception, err);
323 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
324 return JSWebAPIErrorFactory::postException(ctx, exception, err);
328 JSValueRef JSAlarmManager::removeAll(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
330 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
331 SecurityAccessor *thisPriv = static_cast<SecurityAccessor*>(JSObjectGetPrivate(thisObject));
333 LoggerE("private object is null");
334 return JSWebAPIErrorFactory::postException(ctx, exception,
335 JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "Wrong object");
337 TIME_TRACER_ITEM_BEGIN("(add)ace_check", 0);
338 TIZEN_CHECK_ACCESS(ctx, exception, thisPriv, ALARM_FUNCTION_API_REMOVE_ALL);
339 TIME_TRACER_ITEM_END("(add)ace_check", 0);
341 TIME_TRACER_ITEM_BEGIN("(removeAll)alarm_cancel_all", 0);
342 int returnVal = alarm_cancel_all();
343 TIME_TRACER_ITEM_END("(removeAll)alarm_cancel_all", 0);
345 if (ALARM_ERROR_NONE != returnVal) {
346 LoggerE("Error while removing all alarms: "<< returnVal);
349 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
350 return JSValueMakeUndefined(ctx);
353 JSValueRef JSAlarmManager::get(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
355 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
357 service_h service = NULL;
358 char* alarmType = NULL;
359 JSValueRef result = NULL;
361 ArgumentValidator validator(ctx, argumentCount, arguments);
362 AlarmConverter converter(ctx);
365 std::string id = validator.toString(0);
367 std::stringstream(id) >> alarmId;
370 LoggerE("Wrong Alarm ID");
371 throw InvalidValuesException("Invalid ID");
374 TIME_TRACER_ITEM_BEGIN("(get)alarm_get_service", 0);
375 int ret = alarm_get_service(alarmId, &service);
377 if (ret != ALARM_ERROR_NONE) {
378 throw NotFoundException("Alarm not found");
381 ret = service_get_extra_data(service, ALARM_TYPE_KEY, &alarmType);
382 if (ret != SERVICE_ERROR_NONE) {
383 LoggerE("Getting data failed: " << ret);
384 service_destroy(service);
385 throw UnknownException("Unknown error occurred.");
387 TIME_TRACER_ITEM_END("(get)alarm_get_service", 0);
389 if (strcmp(alarmType, ALARM_TYPE_ABSOLUTE_VALUE) == 0) {
390 AlarmAbsolutePtr privateData = AlarmAbsolutePtr(new AlarmAbsolute(service));
392 if(!converter.toAlarmAbsolutePtr(alarmId, service, privateData)) {
393 service_destroy(service);
394 throw TypeMismatchException("Alarm not found");
397 result = JSAlarmAbsolute::createJSObject(ctx, privateData);
399 } else if(strcmp(alarmType, ALARM_TYPE_RELATIVE_VALUE) == 0) {
400 AlarmRelativePtr privateData = AlarmRelativePtr(new AlarmRelative(service));
402 if(!converter.toAlarmRelativePtr(alarmId, service, privateData)) {
403 service_destroy(service);
404 throw TypeMismatchException("Alarm not found");
407 result = JSAlarmRelative::createJSObject(ctx, privateData);
409 service_destroy(service);
410 throw UnknownException("Unknown error occurred.");
413 service_destroy(service);
414 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
416 } catch (const BasePlatformException &err) {
417 return JSWebAPIErrorFactory::postException(ctx, exception, err);
419 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
420 return JSWebAPIErrorFactory::postException(ctx, exception, err);
425 JSValueRef JSAlarmManager::getAll(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
427 TIME_TRACER_ITEM_BEGIN(__FUNCTION__, 0);
429 AlarmConverter converter(ctx);
430 std::vector<int> alarmIds;
432 TIME_TRACER_ITEM_BEGIN("(getAll)alarm_foreach_registered_alarm", 0);
433 int error = alarm_foreach_registered_alarm(alarm_iterate_callback, &alarmIds);
434 TIME_TRACER_ITEM_END("(getAll)alarm_foreach_registered_alarm", 0);
435 if (error == ALARM_ERROR_CONNECTION_FAIL) {
436 LoggerE("Alarm system may not be ready yet.");
438 } else if(error != ALARM_ERROR_NONE) {
439 LoggerE("Error occurred while getting all alarms : " << error);
440 throw UnknownException("Unknown error occurred.");
443 JSObjectRef jsResult = JSCreateArrayObject(ctx, 0, NULL);
444 if (jsResult == NULL) {
445 throw TypeMismatchException("Could not create js array object.");
448 for (size_t i = 0 ; i < alarmIds.size(); i++) {
450 service_h handle = NULL;
451 char* alarmType = NULL;
453 TIME_TRACER_ITEM_BEGIN("(getAll)alarm_get_service", 0);
454 error = alarm_get_service(alarmIds.at(i), &handle);
455 TIME_TRACER_ITEM_END("(getAll)alarm_get_service", 0);
456 if(error != ALARM_ERROR_NONE) {
457 LoggerE("Getting service failed: " << error);
458 throw NotFoundException("Alarm not found");
461 TIME_TRACER_ITEM_BEGIN("(getAll)service_get_extra_data", 0);
462 error = service_get_extra_data(handle, ALARM_TYPE_KEY, &alarmType);
463 TIME_TRACER_ITEM_END("(getAll)service_get_extra_data", 0);
464 if(error != SERVICE_ERROR_NONE) {
465 LoggerI("Getting data failed: " << error);
466 service_destroy(handle);
467 throw UnknownException("Unknown error occurred.");
470 JSValueRef obj = NULL;
471 if (strcmp(alarmType, ALARM_TYPE_ABSOLUTE_VALUE) == 0) {
472 AlarmAbsolutePtr privateData = AlarmAbsolutePtr(new AlarmAbsolute(handle));
474 if(!converter.toAlarmAbsolutePtr(alarmIds.at(i), handle, privateData)) {
475 service_destroy(handle);
476 throw TypeMismatchException("Absolute alarm conversion failed.");
479 obj = JSAlarmAbsolute::createJSObject(ctx, privateData);
481 } else if( !strcmp(alarmType, ALARM_TYPE_RELATIVE_VALUE)) {
482 AlarmRelativePtr privateData = AlarmRelativePtr(new AlarmRelative(handle));
484 if(!converter.toAlarmRelativePtr(alarmIds.at(i), handle, privateData)) {
485 service_destroy(handle);
486 throw TypeMismatchException("Relative alarm conversion failed.");
488 obj = JSAlarmRelative::createJSObject(ctx, privateData);
491 service_destroy(handle);
492 throw UnknownException("Unknown error occurred.");
495 service_destroy(handle);
497 if(!JSSetArrayElement(ctx, jsResult, i, obj)) {
498 service_destroy(handle);
499 throw UnknownException("JS array creation failed.");
503 TIME_TRACER_ITEM_END(__FUNCTION__, 0);
505 } catch (const BasePlatformException &err) {
506 return JSWebAPIErrorFactory::postException(ctx, exception, err);
508 DeviceAPI::Common::UnknownException err("Unknown Error in ApplicationManager.getAppSharedURI().");
509 return JSWebAPIErrorFactory::postException(ctx, exception, err);
513 JSValueRef JSAlarmManager::getProperty(JSContextRef context,
515 JSStringRef propertyName,
516 JSValueRef* exception)
519 if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_MINUTE)) {
520 return JSUtil::toJSValueRef(context, (long)60);
521 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_HOUR)) {
522 return JSUtil::toJSValueRef(context, (long)3600);
523 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_DAY)) {
524 return JSUtil::toJSValueRef(context, (long)86400);
525 } else if (JSStringIsEqualToUTF8CString(propertyName, TIZEN_ALARM_CONSTANT_PERIOD_WEEK)) {
526 return JSUtil::toJSValueRef(context, (long)604800);
528 } catch (const BasePlatformException &err) {
529 LoggerE("Getting property is failed. %s", err.getMessage().c_str());