--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_alarm',
+ 'type': 'loadable_module',
+ 'sources': [
+ 'alarm_api.js',
+ 'alarm_extension.cc',
+ 'alarm_extension.h',
+ 'alarm_info.cc',
+ 'alarm_info.h',
+ 'alarm_instance.cc',
+ 'alarm_instance.h',
+ 'alarm_manager.cc',
+ 'alarm_manager.h',
+ ],
+ 'conditions': [
+ ['tizen == 1', {
+ 'includes': [
+ '../common/pkg-config.gypi',
+ ],
+ 'variables': {
+ 'packages': [
+ 'appcore-common',
+ 'capi-appfw-application',
+ ]
+ },
+ }],
+ ],
+ },
+ ],
+
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function sendSyncMessage(msg) {
+ return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
+}
+
+function daysOfWeekToFlag(days) {
+ var flag = 0;
+ if (days instanceof Array && days.length > 0) {
+ for (var i = 0, len = days.length; i < len; i++) {
+ var day = days[i];
+ if (day === 'SU')
+ flag |= 0x01;
+ else if (day === 'MO')
+ flag |= 0x02;
+ else if (day === 'TU')
+ flag |= 0x04;
+ else if (day === 'WE')
+ flag |= 0x08;
+ else if (day === 'TH')
+ flag |= 0x10;
+ else if (day === 'FR')
+ flag |= 0x20;
+ else if (day === 'SA')
+ flag |= 0x40;
+ }
+ }
+
+ return flag;
+}
+
+function flagToDaysOfWeek(flag) {
+ var days = [];
+ if (flag & 0x01)
+ days.push('SU');
+ if (flag & 0x02)
+ days.push('MO');
+ if (flag & 0x04)
+ days.push('TU');
+ if (flag & 0x08)
+ days.push('WE');
+ if (flag & 0x10)
+ days.push('TH');
+ if (flag & 0x20)
+ days.push('FR');
+ if (flag & 0x40)
+ days.push('SA');
+
+ return days;
+}
+
+function defineReadOnlyProperty(object, key, value) {
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ writable: false,
+ value: value
+ });
+}
+
+var OperationEnum = {
+ AddAlarmAbs: 'alarm.add.absolute',
+ AddAlarmRel: 'alarm.add.relative',
+ GetRemainingSec: 'alarm.get.remainingsec',
+ GetNextScheduledDate: 'alarm.get.nextScheduledDate',
+ RemoveAlarm: 'alarm.remove',
+ RemoveAllAlarm: 'alarm.removeAll',
+ GetAlarm: 'alarm.getInfo',
+ GetAllAlarms: 'alarm.getAllInfo'
+};
+
+defineReadOnlyProperty(exports, 'PERIOD_MINUTE', 60);
+defineReadOnlyProperty(exports, 'PERIOD_HOUR', 3600);
+defineReadOnlyProperty(exports, 'PERIOD_DAY', 86400);
+defineReadOnlyProperty(exports, 'PERIOD_WEEK', 604800);
+
+tizen.Alarm = function() {};
+tizen.Alarm.prototype.constructor = tizen.Alarm;
+
+tizen.AlarmAbsolute = function(date, periodOrDaysOfWeek) {
+ tizen.Alarm.apply(this);
+
+ if (date instanceof Date) {
+ defineReadOnlyProperty(this, 'date', date);
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ var daysOfTheWeek = [];
+ if (typeof periodOrDaysOfWeek === 'number' && !isNaN(periodOrDaysOfWeek)) {
+ defineReadOnlyProperty(this, 'period', periodOrDaysOfWeek);
+ } else if (periodOrDaysOfWeek instanceof Array && periodOrDaysOfWeek.length > 0) {
+ daysOfTheWeek = periodOrDaysOfWeek;
+ }
+ defineReadOnlyProperty(this, 'daysOfTheWeek', daysOfTheWeek);
+};
+
+tizen.AlarmAbsolute.prototype = new tizen.Alarm();
+tizen.AlarmAbsolute.prototype.constructor = tizen.AlarmAbsolute;
+
+tizen.AlarmAbsolute.prototype.getNextScheduledDate = function() {
+ if (this.id === undefined) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+ }
+
+ var operation = { cmd: OperationEnum.GetNextScheduledDate, alarm: this.id };
+ var ret = sendSyncMessage(operation);
+ if (ret.error) {
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+ }
+
+ var seconds = ret.data['nextScheduledDate'] || 0;
+ return new Date(seconds * 1000);
+};
+
+tizen.AlarmRelative = function(delay, period) {
+ tizen.Alarm.apply(this);
+
+ if (typeof delay === 'number' && !isNaN(delay))
+ defineReadOnlyProperty(this, 'delay', delay);
+ else
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ if (typeof period === 'number' && !isNaN(period))
+ defineReadOnlyProperty(this, 'period', period);
+};
+
+tizen.AlarmRelative.prototype = new tizen.Alarm();
+tizen.AlarmRelative.prototype.constructor = tizen.AlarmRelative;
+
+tizen.AlarmRelative.prototype.getRemainingSeconds = function() {
+ if (this.id === undefined)
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+
+ var operation = { cmd: OperationEnum.GetRemainingSec, alarm: this.id };
+ var ret = sendSyncMessage(operation);
+ if (ret.error)
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+
+ return ret.data['remainingSeconds'];
+};
+
+exports.add = function(alarm, applicationId, appControl) {
+ var cmd = undefined;
+ var alarmInfo = {};
+ if (alarm instanceof tizen.AlarmAbsolute) {
+ cmd = OperationEnum.AddAlarmAbs;
+ // Convert milliseconds to seconds and round it.
+ alarmInfo['date'] = Math.floor(alarm.date.getTime() / 1000 + 0.5);
+ alarmInfo['period'] = alarm.period || 0;
+ alarmInfo['daysOfTheWeek'] = daysOfWeekToFlag(alarm.daysOfTheWeek);
+ } else if (alarm instanceof tizen.AlarmRelative) {
+ cmd = OperationEnum.AddAlarmRel;
+ alarmInfo['delay'] = alarm.delay;
+ alarmInfo['period'] = alarm.period || 0;
+ } else {
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+ }
+
+ var operation = {
+ cmd: cmd,
+ alarm: alarmInfo,
+ applicationId: applicationId,
+ appControl: appControl
+ };
+ var ret = sendSyncMessage(operation);
+ if (ret.error)
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+
+ defineReadOnlyProperty(alarm, 'id', ret.data['id']);
+};
+
+exports.remove = function(alarmId) {
+ var operation = { cmd: OperationEnum.RemoveAlarm, alarm: alarmId };
+ var ret = sendSyncMessage(operation);
+ if (ret.error)
+ throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR);
+ console.debug('Succeed to remove alarm ' + alarmId);
+};
+
+exports.removeAll = function() {
+ var operation = { cmd: OperationEnum.RemoveAllAlarm };
+ var ret = sendSyncMessage(operation);
+ if (ret.error)
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+ console.debug('Succeed to remove all alarms');
+};
+
+function parseAlarm(data) {
+ var alarm = null;
+ var obj = JSON.parse(data);
+
+ if (obj['type'] === 'absolute') {
+ // Convert seconds to milliseconds and use it to create Date object.
+ var date = new Date(obj['date'] * 1000);
+ var daysOfTheWeek = flagToDaysOfWeek(obj['weekFlag']);
+ alarm = new tizen.AlarmAbsolute(date, daysOfTheWeek.length > 0 ? daysOfTheWeek : obj['period']);
+ defineReadOnlyProperty(alarm, 'id', obj['id']);
+ } else if (obj['type'] === 'relative') {
+ alarm = new tizen.AlarmRelative(obj['delay'], obj['period']);
+ defineReadOnlyProperty(alarm, 'id', obj['id']);
+ }
+
+ return alarm;
+}
+
+exports.get = function(alarmId) {
+ var operation = { cmd: OperationEnum.GetAlarm, alarm: alarmId };
+ var ret = sendSyncMessage(operation);
+ if (ret.error)
+ throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR);
+ else if (!ret.data)
+ throw new tizen.WebAPIException(tizen.WebAPIException.INVALID_VALUES_ERR);
+
+ return parseAlarm(ret.data);
+};
+
+exports.getAll = function() {
+ var operation = { cmd: OperationEnum.GetAllAlarms };
+ var ret = sendSyncMessage(operation);
+ if (ret.error || !ret.data)
+ throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+
+ var alarms = [];
+ for (var i = 0, len = ret.data.length; i < len; i++) {
+ var alarm = parseAlarm(ret.data[i]);
+ alarms.push(alarm);
+ }
+ return alarms;
+};
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "alarm/alarm_extension.h"
+
+#include "alarm/alarm_instance.h"
+
+common::Extension* CreateExtension() {
+ return new AlarmExtension;
+}
+
+// This will be generated from alarm_api.js.
+extern const char kSource_alarm_api[];
+
+AlarmExtension::AlarmExtension() {
+ SetExtensionName("tizen.alarm");
+ SetJavaScriptAPI(kSource_alarm_api);
+ const char* entry_points[] = {
+ "tizen.AlarmAbsolute",
+ "tizen.AlarmRelative",
+ NULL
+ };
+ SetExtraJSEntryPoints(entry_points);
+}
+
+AlarmExtension::~AlarmExtension() {}
+
+common::Instance* AlarmExtension::CreateInstance() {
+ return new AlarmInstance();
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ALARM_ALARM_EXTENSION_H_
+#define ALARM_ALARM_EXTENSION_H_
+
+#include "common/extension.h"
+
+class AlarmExtension : public common::Extension {
+ public:
+ AlarmExtension();
+ virtual ~AlarmExtension();
+
+ private:
+ virtual common::Instance* CreateInstance();
+};
+
+#endif // ALARM_ALARM_EXTENSION_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "alarm/alarm_info.h"
+
+#include <iostream>
+
+#include "common/picojson.h"
+
+std::string AlarmInfo::Serialize() {
+ picojson::object obj;
+ obj["id"] = picojson::value(static_cast<double>(id_));
+
+ if (type_ == ABSOLUTE) {
+ obj["type"] = picojson::value(std::string("absolute"));
+ obj["date"] = picojson::value(static_cast<double>(date_));
+ obj["period"] = picojson::value(static_cast<double>(period_));
+ obj["weekFlag"] = picojson::value(static_cast<double>(weekflag_));
+ } else if (type_ == RELATIVE) {
+ obj["type"] = picojson::value(std::string("relative"));
+ obj["delay"] = picojson::value(static_cast<double>(delay_));
+ obj["period"] = picojson::value(static_cast<double>(period_));
+ } else {
+ // Should never come here.
+ std::cerr << "Unknown alarm type " << type_ << std::endl;
+ }
+
+ picojson::value val(obj);
+ return val.serialize();
+}
+
+bool AlarmInfo::Deserialize(const char* stream) {
+ picojson::value obj;
+
+ std::string err;
+ picojson::parse(obj, stream, stream + strlen(stream), &err);
+ if (!err.empty()) {
+ std::cerr << "Failed to deserialize alarm object: " << stream << std::endl;
+ return false;
+ }
+
+ id_ = static_cast<int>(obj.get("id").get<double>());
+ std::string type = obj.get("type").to_str();
+
+ if (type == "absolute") {
+ type_ = ABSOLUTE;
+ date_ = static_cast<int>(obj.get("date").get<double>());
+ period_ = static_cast<int>(obj.get("period").get<double>());
+ weekflag_ = static_cast<int>(obj.get("weekFlag").get<double>());
+ } else if (type == "relative") {
+ type_ = RELATIVE;
+ delay_ = static_cast<int>(obj.get("delay").get<double>());
+ period_ = static_cast<int>(obj.get("period").get<double>());
+ } else {
+ std::cerr << "Unknown alarm type " << type << std::endl;
+ return false;
+ }
+
+ return true;
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ALARM_ALARM_INFO_H_
+#define ALARM_ALARM_INFO_H_
+
+#include <string>
+
+class AlarmInfo {
+ public:
+ enum AlarmType {
+ ABSOLUTE,
+ RELATIVE
+ };
+
+ AlarmInfo() {}
+ AlarmInfo(int id, AlarmType type, int date,
+ int delay, int period, int weekflag)
+ : id_(id), type_(type), date_(date), delay_(delay),
+ period_(period), weekflag_(weekflag) {}
+
+ ~AlarmInfo() {}
+
+ int id() const { return id_; }
+ void SetId(int id) { id_ = id; }
+ int type() const { return type_; }
+ int date() const { return date_; }
+ int delay() const { return delay_; }
+ int period() const { return period_; }
+ int weekflag() const { return weekflag_; }
+
+ std::string Serialize();
+ bool Deserialize(const char* stream);
+
+ private:
+ int id_;
+ AlarmType type_;
+ int date_;
+ int delay_;
+ int period_;
+ int weekflag_;
+};
+
+#endif // ALARM_ALARM_INFO_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "alarm/alarm_instance.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "alarm/alarm_info.h"
+#include "alarm/alarm_manager.h"
+
+namespace {
+
+const char cmdAddAbsAlarm[] = "alarm.add.absolute";
+const char cmdAddRelAlarm[] = "alarm.add.relative";
+const char cmdGetRemainingSec[] = "alarm.get.remainingsec";
+const char cmdGetNextScheduledDate[] = "alarm.get.nextScheduledDate";
+const char cmdGetAlarm[] = "alarm.getInfo";
+const char cmdGetAllAlarms[] = "alarm.getAllInfo";
+const char cmdRemoveAlarm[] = "alarm.remove";
+const char cmdRemoveAllAlarm[] = "alarm.removeAll";
+
+} // namespace
+
+AlarmInstance::AlarmInstance() {
+ alarm_manager_.reset(new AlarmManager());
+
+ // Store the host application Id into the manager.
+ std::string id_str = common::Extension::GetRuntimeVariable("app_id", 64);
+ std::istringstream buf(id_str);
+ picojson::value id_val;
+ picojson::parse(id_val, buf);
+ alarm_manager_->SetHostAppId(id_val.get<std::string>());
+}
+
+AlarmInstance::~AlarmInstance() {}
+
+void AlarmInstance::HandleMessage(const char* msg) {
+ picojson::value msg_obj;
+ std::string err;
+ picojson::parse(msg_obj, msg, msg + strlen(msg), &err);
+ if (!err.empty()) {
+ std::cerr << "Failed to parse the message." << std::endl;
+ return;
+ }
+}
+
+void AlarmInstance::HandleSyncMessage(const char* msg) {
+ picojson::value msg_obj;
+ std::string err;
+ picojson::parse(msg_obj, msg, msg + strlen(msg), &err);
+ if (!err.empty()) {
+ std::cerr << "Failed to parse the sync message: " << msg << std::endl;
+ return;
+ }
+
+ std::string cmdName = msg_obj.get("cmd").to_str();
+ if (cmdName == cmdAddAbsAlarm)
+ HandleAddAbsoluteAlarm(msg_obj);
+ else if (cmdName == cmdAddRelAlarm)
+ HandleAddRelativeAlarm(msg_obj);
+ else if (cmdName == cmdGetRemainingSec)
+ HandleGetRemainingSeconds(msg_obj);
+ else if (cmdName == cmdGetNextScheduledDate)
+ HandleGetNextScheduledDate(msg_obj);
+ else if (cmdName == cmdGetAlarm)
+ HandleGetAlarm(msg_obj);
+ else if (cmdName == cmdGetAllAlarms)
+ HandleGetAllAlarms();
+ else if (cmdName == cmdRemoveAlarm)
+ HandleRemoveAlarm(msg_obj);
+ else if (cmdName == cmdRemoveAllAlarm)
+ HandleRemoveAllAlarms();
+}
+
+void AlarmInstance::HandleAddAbsoluteAlarm(const picojson::value& msg) {
+ std::string app_id = msg.get("applicationId").to_str();
+ picojson::value alarm_value = msg.get("alarm");
+ int dateval = static_cast<int>(alarm_value.get("date").get<double>());
+ int period = static_cast<int>(alarm_value.get("period").get<double>());
+ int week_flag = static_cast<int>(alarm_value.get("daysOfTheWeek")
+ .get<double>());
+
+ std::unique_ptr<AlarmInfo> alarm(new AlarmInfo(0, AlarmInfo::ABSOLUTE,
+ dateval, 0, period, week_flag));
+
+ int ret = alarm_manager_->ScheduleAlarm(app_id, alarm.get());
+
+ if (!ret) {
+ picojson::object obj;
+ obj["id"] = picojson::value(static_cast<double>(alarm->id()));
+ SendSyncMessage(0, picojson::value(obj));
+ } else {
+ SendSyncMessage(ret,
+ picojson::value(std::string("Failed to add alarm")));
+ }
+}
+
+void AlarmInstance::HandleAddRelativeAlarm(const picojson::value& msg) {
+ std::string app_id = msg.get("applicationId").to_str();
+ picojson::value alarm_value = msg.get("alarm");
+ int delay = static_cast<int>(alarm_value.get("delay").get<double>());
+ int period = static_cast<int>(alarm_value.get("period").get<double>());
+
+ std::unique_ptr<AlarmInfo> alarm(new AlarmInfo(0, AlarmInfo::RELATIVE,
+ 0, delay, period, 0));
+
+ int ret = alarm_manager_->ScheduleAlarm(app_id, alarm.get());
+
+ if (!ret) {
+ picojson::object obj;
+ obj["id"] = picojson::value(static_cast<double>(alarm->id()));
+ SendSyncMessage(0, picojson::value(obj));
+ } else {
+ SendSyncMessage(ret,
+ picojson::value(std::string("Failed to add alarm")));
+ }
+}
+
+void AlarmInstance::HandleGetRemainingSeconds(const picojson::value& msg) {
+ int alarm_id = static_cast<int>(msg.get("alarm").get<double>());
+ int seconds = 0;
+
+ int ret = alarm_manager_->GetRemainingSeconds(alarm_id, seconds);
+
+ if (!ret) {
+ picojson::object obj;
+ obj["remainingSeconds"] = picojson::value(static_cast<double>(seconds));
+ SendSyncMessage(ret, picojson::value(obj));
+ } else {
+ SendSyncMessage(ret, picojson::value(std::string("")));
+ }
+}
+
+void AlarmInstance::HandleGetNextScheduledDate(const picojson::value& msg) {
+ int alarm_id = static_cast<int>(msg.get("alarm").get<double>());
+ int date = 0;
+
+ int ret = alarm_manager_->GetNextScheduledDate(alarm_id, date);
+
+ if (!ret) {
+ picojson::object obj;
+ obj["nextScheduledDate"] = picojson::value(static_cast<double>(date));
+ SendSyncMessage(ret, picojson::value(obj));
+ } else {
+ SendSyncMessage(ret, picojson::value(std::string("")));
+ }
+}
+
+void AlarmInstance::HandleGetAlarm(const picojson::value& msg) {
+ int alarm_id = static_cast<int>(msg.get("alarm").get<double>());
+ std::unique_ptr<AlarmInfo> alarm(new AlarmInfo());
+
+ int ret = alarm_manager_->GetAlarm(alarm_id, alarm.get());
+
+ if (!ret) {
+ SendSyncMessage(0, picojson::value(alarm->Serialize()));
+ } else {
+ SendSyncMessage(ret, picojson::value(std::string("Not found.")));
+ }
+}
+
+void AlarmInstance::HandleGetAllAlarms() {
+ std::vector<std::shared_ptr<AlarmInfo> > alarms;
+
+ int ret = alarm_manager_->GetAllAlarms(alarms);
+ picojson::array alarm_infos;
+ for (int i = 0; i < alarms.size(); i++) {
+ alarm_infos.push_back(picojson::value(alarms[i]->Serialize()));
+ }
+
+ SendSyncMessage(0, picojson::value(alarm_infos));
+}
+
+void AlarmInstance::HandleRemoveAlarm(const picojson::value& msg) {
+ int alarm_id = static_cast<int>(msg.get("alarm").get<double>());
+ int ret = alarm_manager_->RemoveAlarm(alarm_id);
+ SendSyncMessage(ret, picojson::value(std::string("")));
+}
+
+void AlarmInstance::HandleRemoveAllAlarms() {
+ int ret = alarm_manager_->RemoveAllAlarms();
+ SendSyncMessage(ret, picojson::value(std::string("")));
+}
+
+void AlarmInstance::SendSyncMessage(int err_code, const picojson::value& data) {
+ picojson::object obj;
+ if (err_code)
+ obj["error"] = picojson::value(static_cast<double>(err_code));
+ obj["data"] = data;
+ picojson::value val(obj);
+ SendSyncReply(val.serialize().c_str());
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ALARM_ALARM_INSTANCE_H_
+#define ALARM_ALARM_INSTANCE_H_
+
+#include <memory>
+
+#include "common/extension.h"
+#include "common/picojson.h"
+
+class AlarmManager;
+
+class AlarmInstance : public common::Instance {
+ public:
+ AlarmInstance();
+ virtual ~AlarmInstance();
+
+ private:
+ virtual void HandleMessage(const char* msg);
+ virtual void HandleSyncMessage(const char* msg);
+
+ void HandleAddAbsoluteAlarm(const picojson::value& msg);
+ void HandleAddRelativeAlarm(const picojson::value& msg);
+ void HandleGetRemainingSeconds(const picojson::value& msg);
+ void HandleGetNextScheduledDate(const picojson::value& msg);
+ void HandleGetAlarm(const picojson::value& msg);
+ void HandleGetAllAlarms();
+ void HandleRemoveAlarm(const picojson::value& msg);
+ void HandleRemoveAllAlarms();
+
+ void SendSyncMessage(int err_code, const picojson::value& data);
+
+ std::unique_ptr<AlarmManager> alarm_manager_;
+};
+
+#endif // ALARM_ALARM_INSTANCE_H_
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "alarm/alarm_manager.h"
+
+#include <app.h>
+#include <iostream>
+
+#include "alarm/alarm_info.h"
+
+namespace {
+
+const char kAlarmInfoKey[] = "service.extra.alarm";
+const char kHostAppIdKey[] = "service.extra.hostappid";
+
+bool AlarmIterateCallback(int id, void* userdata) {
+ std::vector<int>* ids = reinterpret_cast<std::vector<int>*>(userdata);
+ ids->push_back(id);
+ return true;
+}
+
+} // namespace
+
+AlarmManager::AlarmManager() {}
+
+AlarmManager::~AlarmManager() {}
+
+void AlarmManager::SetHostAppId(const std::string &host_app_id) {
+ host_app_id_ = host_app_id;
+}
+
+int AlarmManager::ScheduleAlarm(const std::string& app_id,
+ AlarmInfo* alarm) const {
+ if (!alarm)
+ return -1;
+
+ service_h service = CreateAppLaunchService(app_id);
+ if (!service)
+ return SERVICE_RESULT_FAILED;
+
+ int ret = StoreAlarmInService(service, alarm);
+ if (ret) {
+ DestoryService(service);
+ std::cerr << "Failed to store the alarm information." << std::endl;
+ return ret;
+ }
+
+ ret = service_add_extra_data(service, kHostAppIdKey, host_app_id_.c_str());
+ if (ret) {
+ DestoryService(service);
+ std::cerr << "Failed to store host application ID." << std::endl;
+ return ret;
+ }
+
+ int alarm_id = 0;
+ if (alarm->type() == AlarmInfo::ABSOLUTE) {
+ time_t tval = static_cast<time_t>(alarm->date());
+ struct tm date_tm = {0};
+ localtime_r(&tval, &date_tm);
+ if (alarm->weekflag()) {
+ ret = alarm_schedule_with_recurrence_week_flag(service, &date_tm,
+ alarm->weekflag(), &alarm_id);
+ } else {
+ ret = alarm_schedule_at_date(service, &date_tm, alarm->period(),
+ &alarm_id);
+ }
+ } else if (alarm->type() == AlarmInfo::RELATIVE) {
+ ret = alarm_schedule_after_delay(service, alarm->delay(),
+ alarm->period(), &alarm_id);
+ }
+ alarm->SetId(alarm_id);
+ DestoryService(service);
+
+ if (ret) {
+ std::cerr << "Failed to schedule an alarm." << std::endl;
+ return ret;
+ }
+
+ return 0;
+}
+
+int AlarmManager::GetNextScheduledDate(int alarm_id, int& output) const {
+ if (!CheckOwnership(alarm_id))
+ return -1;
+
+ struct tm date_tm;
+ int ret = alarm_get_scheduled_date(alarm_id, &date_tm);
+ if (ret)
+ return ret;
+
+ struct tm cur_date_tm;
+ ret = alarm_get_current_time(&cur_date_tm);
+ if (ret)
+ return ret;
+
+ int next = mktime(&date_tm);
+ if (next < mktime(&cur_date_tm))
+ return -1;
+
+ output = next;
+ return 0;
+}
+
+int AlarmManager::GetRemainingSeconds(int alarm_id, int& output) const {
+ if (!CheckOwnership(alarm_id))
+ return -1;
+
+ struct tm date_tm;
+ int ret = alarm_get_scheduled_date(alarm_id, &date_tm);
+ if (ret)
+ return ret;
+
+ struct tm cur_date_tm;
+ ret = alarm_get_current_time(&cur_date_tm);
+ if (ret)
+ return ret;
+
+ int next = static_cast<int>(mktime(&date_tm));
+ int current = static_cast<int>(mktime(&cur_date_tm));
+ if (next < current)
+ return -1;
+
+ output = next - current;
+ return 0;
+}
+
+int AlarmManager::RemoveAlarm(int alarm_id) const {
+ service_h service = 0;
+ int ret = alarm_get_service(alarm_id, &service);
+ if (ret)
+ return ret;
+
+ if (!CheckOwnership(service)) {
+ DestoryService(service);
+ return -1;
+ }
+
+ ret = alarm_cancel(alarm_id);
+ DestoryService(service);
+ return ret;
+}
+
+int AlarmManager::RemoveAllAlarms() const {
+ std::vector<int> alarm_ids;
+ int ret = alarm_foreach_registered_alarm(AlarmIterateCallback, &alarm_ids);
+ if (ret)
+ return ret;
+
+ for (int i = 0; i < alarm_ids.size(); i++) {
+ RemoveAlarm(alarm_ids[i]);
+ }
+ return 0;
+}
+
+int AlarmManager::GetAlarm(int alarm_id, AlarmInfo* alarm) const {
+ if (!alarm)
+ return -1;
+
+ service_h service = NULL;
+ int ret = alarm_get_service(alarm_id, &service);
+ if (ret)
+ return ret;
+
+ if (!CheckOwnership(service)) {
+ DestoryService(service);
+ return -1;
+ }
+
+ ret = RestoreAlarmFromService(service, alarm);
+ alarm->SetId(alarm_id);
+
+ DestoryService(service);
+ return ret;
+}
+
+int AlarmManager::GetAllAlarms(
+ std::vector<std::shared_ptr<AlarmInfo> >& output) const {
+ std::vector<int> alarm_ids;
+ int ret = alarm_foreach_registered_alarm(AlarmIterateCallback, &alarm_ids);
+ if (ret)
+ return ret;
+
+ for (int i = 0; i < alarm_ids.size(); i++) {
+ std::shared_ptr<AlarmInfo> alarm(new AlarmInfo());
+ if (GetAlarm(alarm_ids[i], alarm.get()) == 0)
+ output.push_back(alarm);
+ }
+
+ return 0;
+}
+
+service_h
+AlarmManager::CreateAppLaunchService(const std::string& app_id) const {
+ service_h service = 0;
+ if (service_create(&service)) {
+ std::cerr << "Failed to call service_create()" << std::endl;
+ return 0;
+ }
+
+ service_set_app_id(service, app_id.c_str());
+ service_set_operation(service, SERVICE_OPERATION_DEFAULT);
+ return service;
+}
+
+void AlarmManager::DestoryService(service_h service) const {
+ if (service_destroy(service))
+ std::cerr << "Failed to call service_destroy()" << std::endl;
+}
+
+int AlarmManager::StoreAlarmInService(service_h service,
+ AlarmInfo* alarm) const {
+ if (!service || !alarm)
+ return -1;
+
+ return service_add_extra_data(service, kAlarmInfoKey,
+ alarm->Serialize().c_str());
+}
+
+int AlarmManager::RestoreAlarmFromService(service_h service,
+ AlarmInfo* alarm) const {
+ if (!service || !alarm)
+ return -1;
+
+ char* buffer = NULL;
+ int ret = service_get_extra_data(service, kAlarmInfoKey, &buffer);
+ if (ret)
+ return ret;
+
+ if (!alarm->Deserialize(buffer)) {
+ ret = -1;
+ }
+
+ free(buffer);
+ return ret;
+}
+
+// Return true if the alarm is created by this application.
+// Otherwise return false.
+bool AlarmManager::CheckOwnership(int alarm_id) const {
+ service_h service = NULL;
+ int ret = alarm_get_service(alarm_id, &service);
+ if (ret)
+ return false;
+
+ bool passed = CheckOwnership(service);
+ DestoryService(service);
+
+ return passed;
+}
+
+bool AlarmManager::CheckOwnership(service_h service) const {
+ char* buffer = NULL;
+ if (!service || service_get_extra_data(service, kHostAppIdKey, &buffer))
+ return false;
+
+ bool passed = (host_app_id_ == std::string(buffer));
+ free(buffer);
+
+ return passed;
+}
--- /dev/null
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ALARM_ALARM_MANAGER_H_
+#define ALARM_ALARM_MANAGER_H_
+
+#include <app_service.h>
+#include <memory>
+#include <string>
+#include <vector>
+
+class AlarmInfo;
+
+class AlarmManager {
+ public:
+ AlarmManager();
+ ~AlarmManager();
+
+ void SetHostAppId(const std::string &host_app_id);
+ int ScheduleAlarm(const std::string& app_id, AlarmInfo* alarm) const;
+ int GetNextScheduledDate(int alarm_id, int& output) const;
+ int GetRemainingSeconds(int alarm_id, int& output) const;
+ int RemoveAlarm(int alarm_id) const;
+ int RemoveAllAlarms() const;
+ int GetAlarm(int alarm_id, AlarmInfo* alarm) const;
+ int GetAllAlarms(std::vector<std::shared_ptr<AlarmInfo> >& output) const;
+
+ private:
+ service_h CreateAppLaunchService(const std::string& app_id) const;
+ void DestoryService(service_h service) const;
+ int StoreAlarmInService(service_h service, AlarmInfo* alarm) const;
+ int RestoreAlarmFromService(service_h service, AlarmInfo* alarm) const;
+ bool CheckOwnership(int alarm_id) const;
+ bool CheckOwnership(service_h service) const;
+
+ std::string host_app_id_;
+};
+
+#endif // ALARM_ALARM_MANAGER_H_
--- /dev/null
+<html>
+<head><h1>Hello, Alarm API</h1></head>
+<body>
+<hr>
+<h3>Launch Application at date</h3>
+Application Id: <input type="text" id="appId1" value="xwalk."></input> <br>
+At date: <input type="text" id="scheduledAt"></input><br>
+Period: <input type="text" id="period1" value="0">seconds</input><br>
+<input type="button" value="Launch" onclick="LaunchAtDate()"></input>
+
+<br><br>
+<hr>
+<h3>Launch Application after delay</h3>
+Application Id:<input type="text" id="appId2" value="xwalk."></input> <br>
+After Delay: <input type="text" id="afterDelay" value="1">seconds</input><br>
+Period: <input type="text" id="period2" value="0">seconds</input><br>
+<input type="button" value="Launch" onclick="LaunchAfterDelay()"></input>
+
+<br><br>
+<hr>
+<h3>Get alarm information</h3>
+Alarm Id:<input type="text" id="alarmIdToGet"><br>
+<input type="button" value="query" onclick="GetAlarmInfo()"><br>
+<textarea id="alarmInfoArea" rows="10" cols="64">no alarm found</textarea><br>
+
+<br><br>
+<hr>
+<h3>Remove alarm(s)</h3>
+Alarm Id:<input type="text" id="alarmIdToRemove"><br>
+<input type="button" value="remove" onclick="RemoveAlarm()"><br>
+<textarea id="removeFeedback" rows="10" cols="64"></textarea><br>
+
+<pre id="console"></pre>
+<script src="js/js-test-pre.js"></script>
+<script>
+ var now = new Date();
+ document.getElementById('scheduledAt').value = now.toString();
+
+ function LaunchAtDate() {
+ try {
+ var appId = document.getElementById('appId1').value;
+ var atDate = new Date(document.getElementById('scheduledAt').value);
+ var period = Number.parseInt(document.getElementById('period1').value);
+ //period = period * tizen.alarm.PERIOD_MINUTE;
+ var alarm = new tizen.AlarmAbsolute(atDate, period);
+ if (alarm instanceof tizen.Alarm && alarm instanceof tizen.AlarmAbsolute) {
+ console.log('It is an absolute alarm.');
+ }
+ tizen.alarm.add(alarm, appId);
+ console.log('Alarm:'+JSON.stringify(alarm));
+ } catch (e) {
+ debug(e.name);
+ }
+ }
+
+ function LaunchAfterDelay() {
+ try {
+ var appId = document.getElementById('appId2').value;
+ var delay = Number.parseInt(document.getElementById('afterDelay').value);
+ var period = Number.parseInt(document.getElementById('period2').value);
+ //period = period * tizen.alarm.PERIOD_MINUTE;
+ var alarm = new tizen.AlarmRelative(delay, period);
+ if (alarm instanceof tizen.Alarm && alarm instanceof tizen.AlarmRelative) {
+ console.log('It is a relative alarm.');
+ }
+ tizen.alarm.add(alarm, appId);
+ console.log('Alarm:' + JSON.stringify(alarm));
+ } catch (e) {
+ debug(e.name);
+ }
+ }
+
+ function GetAlarmInfo() {
+ try {
+ var alarmId = Number.parseInt(document.getElementById('alarmIdToGet').value);
+ document.getElementById('alarmInfoArea').value = 'Begin querying alarm.';
+ var output = '';
+ if (!alarmId || isNaN(alarmId)) {
+ var alarms = tizen.alarm.getAll();
+ if (!alarms || alarms.length === 0) {
+ output = 'No alarm is found';
+ } else {
+ for (var i = 0, len = alarms.length; i < len; i++) {
+ output += 'No.' + i + ':' + JSON.stringify(alarms[i]) + '\n';
+ }
+ }
+ } else {
+ var alarm = tizen.alarm.get(alarmId);
+ if (alarm) {
+ output = JSON.stringify(alarm);
+ if (alarm instanceof tizen.AlarmRelative) {
+ output += '\n remaining seconds:' + alarm.getRemainingSeconds();
+ } else if (alarm instanceof tizen.AlarmAbsolute) {
+ output += '\n next Scheduled Date:' + alarm.getNextScheduledDate();
+ }
+ } else {
+ output = 'The alarm is not found.';
+ }
+ }
+ document.getElementById('alarmInfoArea').value = output;
+ }catch(e) {
+ debug(e.name);
+ console.debug(JSON.stringify(e));
+ }
+ }
+
+ function RemoveAlarm() {
+ try {
+ var alarmId = Number.parseInt(document.getElementById('alarmIdToRemove').value);
+ document.getElementById('removeFeedback').value = 'Begin removing alarms.';
+ if (!alarmId || isNaN(alarmId)) {
+ tizen.alarm.removeAll();
+ document.getElementById('removeFeedback').value = 'All alarms have been removed.';
+ } else {
+ tizen.alarm.remove(alarmId);
+ document.getElementById('removeFeedback').value = 'The alarm ' + alarmId + ' has been removed.';
+ }
+ } catch (e) {
+ debug(e.name);
+ console.debug(JSON.stringify(e));
+ }
+ }
+
+</script>
+</body>
+</html>
<a href="audiosystem.html"><div class="block">audiosystem</div></a>
<a href="content.html"><div class="block">content</div></a>
<a href="speech.html"><div class="block">speech</div></a>
+<a href="alarm.html"><div class="block">alarm</div></a>
</body>
</html>
'conditions': [
[ 'tizen == 1', {
'dependencies': [
+ 'alarm/alarm.gyp:*',
'application/application.gyp:*',
'audiosystem/audiosystem.gyp:*',
'bookmark/bookmark.gyp:*',