return false;
};
+var _timeUtilDateTimeChangeListener;
+
+function _timeUtilDateTimeChangeListenerCallback() {
+ native_.callIfPossible(_timeUtilDateTimeChangeListener);
+}
+
+exports.setDateTimeChangeListener = function() {
+ var args = AV.validateArgs(arguments, [
+ {
+ name: 'changeCallback',
+ type: AV.Types.FUNCTION
+ }
+ ]);
+ _timeUtilDateTimeChangeListener = args.changeCallback;
+ native_.addListener('DateTimeChangeListener',
+ _timeUtilDateTimeChangeListenerCallback);
+ var result = native_.callSync('Time_setDateTimeChangeListener', {});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+exports.unsetDateTimeChangeListener = function() {
+ native_.removeListener('DateTimeChangeListener',
+ _timeUtilDateTimeChangeListenerCallback);
+ var result = native_.callSync('Time_unsetDateTimeChangeListener', {});
+ _timeUtilDateTimeChangeListener = undefined;
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+var _timeUtilTimezoneChangeListener;
+
+function _timeUtilTimezoneChangeListenerCallback() {
+ native_.callIfPossible(_timeUtilTimezoneChangeListener);
+}
+
+exports.setTimezoneChangeListener = function() {
+ var args = AV.validateArgs(arguments, [
+ {
+ name: 'changeCallback',
+ type: AV.Types.FUNCTION
+ }
+ ]);
+
+ _timeUtilTimezoneChangeListener = args.changeCallback;
+ native_.addListener('TimezoneChangeListener',
+ _timeUtilTimezoneChangeListenerCallback);
+ var result = native_.callSync('Time_setTimezoneChangeListener', {});
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+exports.unsetTimezoneChangeListener = function() {
+ native_.removeListener('TimezoneChangeListener',
+ _timeUtilTimezoneChangeListenerCallback);
+ var result = native_.callSync('Time_unsetTimezoneChangeListener', {});
+ _timeUtilTimezoneChangeListener = undefined;
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
function _throwProperTizenException(e) {
if (e instanceof TypeError)
throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
Object.defineProperties(this, {
length: {
- get: function () {
+ get: function() {
return length_;
},
- set: function (v) {
+ set: function(v) {
if (v !== null) {
length_ = Math.floor(v);
}
enumerable: true
},
unit: {
- get: function () {
+ get: function() {
return unit_;
},
- set: function (v) {
+ set: function(v) {
if (TimeDurationUnit.indexOf(v) >= 0) {
unit_ = v;
}
tizen.TZDate.prototype.getPreviousDSTTransition = function() {
var result = native_.callSync('Time_getDSTTransition', {
- "timezone": this.timezone_,
- "value": _getTimeWithOffset(this.date_),
- "trans": 'NEXT_TRANSITION'
+ 'timezone': this.timezone_,
+ 'value': _getTimeWithOffset(this.date_),
+ 'trans': 'NEXT_TRANSITION'
});
if (native_.isFailure(result)) {
return null;
// found in the LICENSE file.
#include "time/time_instance.h"
+#include "common/platform_exception.h"
+#include "common/logger.h"
#if defined(TIZEN)
#include <vconf.h>
namespace extension {
namespace time {
+using namespace common;
+
+enum ListenerType {
+ kTimeChange,
+ kTimezoneChange
+};
+
namespace {
const int _hourInMilliseconds = 3600000;
+const char kTimezoneListenerId[] = "TimezoneChangeListener";
+const char kDateTimeListenerId[] = "DateTimeChangeListener";
} // namespace
TimeInstance& TimeInstance::GetInstance() {
- static TimeInstance instance;
- return instance;
+ static TimeInstance instance;
+ return instance;
}
TimeInstance::TimeInstance() {
REGISTER_SYNC("Time_toString", Time_toString);
REGISTER_SYNC("Time_toDateString", Time_toDateString);
REGISTER_SYNC("Time_toTimeString", Time_toTimeString);
+ REGISTER_SYNC("Time_setDateTimeChangeListener", Time_setDateTimeChangeListener);
+ REGISTER_SYNC("Time_unsetDateTimeChangeListener", Time_unsetDateTimeChangeListener);
+ REGISTER_SYNC("Time_setTimezoneChangeListener", Time_setTimezoneChangeListener);
+ REGISTER_SYNC("Time_unsetTimezoneChangeListener", Time_unsetTimezoneChangeListener);
#undef REGISTER_SYNC
#undef REGISTER_ASYNC
}
+static void OnTimeChangedCallback(keynode_t* /*node*/, void* /*event_ptr*/);
+static std::string GetDefaultTimezone();
+
TimeInstance::~TimeInstance() {}
void TimeInstance::Time_getLocalTimeZone(const JsonValue& /*args*/,
}
JsonArray a;
- const char *timezone = NULL;
+ const char* timezone = NULL;
int i = 0;
do {
int32_t resultLen = 0;
a.push_back(JsonValue(timezone));
i++;
}
- }while(timezone && i < count);
+ } while (timezone && i < count);
ReportSuccess(JsonValue(a), out);
}
void TimeInstance::Time_getTimeZoneOffset(const JsonValue& args,
JsonObject& out) {
std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
+ new UnicodeString(args.get("timezone").to_str().c_str()));
UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
if (errno == ERANGE) {
int32_t offset = timezone->getRawOffset();
- if (cal->inDaylightTime(ec))
- offset += _hourInMilliseconds;
+ if (cal->inDaylightTime(ec)) offset += _hourInMilliseconds;
std::stringstream offsetStr;
offsetStr << offset;
void TimeInstance::Time_getTimeZoneAbbreviation(const JsonValue& args,
JsonObject& out) {
std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
+ new UnicodeString(args.get("timezone").to_str().c_str()));
UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
if (errno == ERANGE) {
UErrorCode ec = U_ZERO_ERROR;
std::unique_ptr<Calendar> cal(
- Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
+ Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
if (U_FAILURE(ec)) {
ReportError(out);
return;
}
std::unique_ptr<DateFormat> fmt(
- new SimpleDateFormat(UnicodeString("z"), Locale::getEnglish(), ec));
+ new SimpleDateFormat(UnicodeString("z"), Locale::getEnglish(), ec));
if (U_FAILURE(ec)) {
ReportError(out);
return;
void TimeInstance::Time_isDST(const JsonValue& args, JsonObject& out) {
std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
+ new UnicodeString(args.get("timezone").to_str().c_str()));
UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
dateInMs -= _hourInMilliseconds;
UErrorCode ec = U_ZERO_ERROR;
std::unique_ptr<Calendar> cal(
- Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
+ Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
if (U_FAILURE(ec)) {
ReportError(out);
return;
void TimeInstance::Time_getDSTTransition(const JsonValue& args,
JsonObject& out) {
std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
+ new UnicodeString(args.get("timezone").to_str().c_str()));
std::string trans = args.get("trans").to_str();
UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
void TimeInstance::Time_toTimeString(const JsonValue& args, JsonObject& out) {
JsonValue val;
- if(!this->toStringByFormat(args, val, TimeInstance::TIME_FORMAT)) {
+ if (!this->toStringByFormat(args, val, TimeInstance::TIME_FORMAT)) {
ReportError(out);
return;
}
}
bool TimeInstance::toStringByFormat(const JsonValue& args, JsonValue& out,
- DateTimeFormatType format) {
+ DateTimeFormatType format) {
std::unique_ptr<UnicodeString> id(
- new UnicodeString(args.get("timezone").to_str().c_str()));
+ new UnicodeString(args.get("timezone").to_str().c_str()));
bool bLocale = args.get("locale").evaluate_as_boolean();
UDate dateInMs = strtod(args.get("value").to_str().c_str(), NULL);
- if (errno == ERANGE)
- return false;
+ if (errno == ERANGE) return false;
UErrorCode ec = U_ZERO_ERROR;
std::unique_ptr<Calendar> cal(
- Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
- if (U_FAILURE(ec))
- return false;
+ Calendar::createInstance(TimeZone::createTimeZone(*id), ec));
+ if (U_FAILURE(ec)) return false;
cal->setTime(dateInMs, ec);
- if (U_FAILURE(ec))
- return false;
+ if (U_FAILURE(ec)) return false;
- std::unique_ptr<DateFormat> fmt(
- new SimpleDateFormat(getDateTimeFormat(format, bLocale),
- (bLocale ? Locale::getDefault() : Locale::getEnglish()),
- ec));
- if (U_FAILURE(ec))
- return false;
+ std::unique_ptr<DateFormat> fmt(new SimpleDateFormat(
+ getDateTimeFormat(format, bLocale),
+ (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec));
+ if (U_FAILURE(ec)) return false;
UnicodeString uResult;
fmt->setCalendar(*cal);
fmt->format(cal->getTime(ec), uResult);
- if (U_FAILURE(ec))
- return false;
+ if (U_FAILURE(ec)) return false;
std::string result = "";
uResult.toUTF8String(result);
ReportSuccess(JsonValue(result), out);
}
-
UnicodeString TimeInstance::getDateTimeFormat(DateTimeFormatType type,
- bool bLocale) {
+ bool bLocale) {
UErrorCode ec = U_ZERO_ERROR;
std::unique_ptr<DateTimePatternGenerator> dateTimepattern(
- DateTimePatternGenerator::createInstance(
- (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec));
+ DateTimePatternGenerator::createInstance(
+ (bLocale ? Locale::getDefault() : Locale::getEnglish()), ec));
- if (U_FAILURE(ec))
- return "";
+ if (U_FAILURE(ec)) return "";
UnicodeString pattern;
if (type == DATE_FORMAT) {
pattern = dateTimepattern->getBestPattern(UDAT_YEAR_NUM_MONTH_DAY, ec);
} else {
std::string skeleton;
- if (type != TIME_FORMAT)
- skeleton = UDAT_YEAR_MONTH_WEEKDAY_DAY;
+ if (type != TIME_FORMAT) skeleton = UDAT_YEAR_MONTH_WEEKDAY_DAY;
#if defined(TIZEN)
int value = 0;
#endif
pattern = dateTimepattern->getBestPattern(
- *(new UnicodeString(skeleton.c_str())), ec);
- if (U_FAILURE(ec))
- return "";
+ *(new UnicodeString(skeleton.c_str())), ec);
+ if (U_FAILURE(ec)) return "";
- if (!bLocale)
- pattern += " 'GMT'Z v'";
+ if (!bLocale) pattern += " 'GMT'Z v'";
}
return pattern;
}
+/////////////////////////// TimeUtilListeners ////////////////////////////////
+
+class TimeUtilListeners {
+ public:
+ TimeUtilListeners();
+ ~TimeUtilListeners();
+
+ void RegisterVconfCallback(ListenerType type);
+ void UnregisterVconfCallback(ListenerType type);
+
+ std::string GetCurrentTimezone();
+ void SetCurrentTimezone(std::string& newTimezone);
+
+ private:
+ std::string current_timezone_;
+ bool is_time_listener_registered_;
+ bool is_timezone_listener_registered_;
+};
+
+TimeUtilListeners::TimeUtilListeners()
+ : current_timezone_(GetDefaultTimezone()),
+ is_time_listener_registered_(false),
+ is_timezone_listener_registered_(false) {
+ LoggerD("Entered");
+}
+
+TimeUtilListeners::~TimeUtilListeners() {
+ LoggerD("Entered");
+ if (is_time_listener_registered_ || is_timezone_listener_registered_) {
+ if (0 != vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
+ OnTimeChangedCallback)) {
+ LoggerE("Failed to unregister vconf callback");
+ }
+ }
+}
+
+void TimeUtilListeners::RegisterVconfCallback(ListenerType type) {
+ LoggerD("");
+ if (!is_time_listener_registered_ && !is_timezone_listener_registered_) {
+ LoggerD("registering listener on platform");
+ if (0 != vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
+ OnTimeChangedCallback, nullptr)) {
+ LoggerE("Failed to register vconf callback");
+ throw UnknownException("Failed to register vconf callback");
+ }
+ } else {
+ LoggerD("not registering listener on platform - already registered");
+ }
+ switch (type) {
+ case kTimeChange:
+ is_time_listener_registered_ = true;
+ LoggerD("time change listener registered");
+ break;
+ case kTimezoneChange:
+ is_timezone_listener_registered_ = true;
+ LoggerD("time zone change listener registered");
+ break;
+ default:
+ LoggerE("Unknown type of listener");
+ throw UnknownException("Unknown type of listener");
+ }
+}
+
+void TimeUtilListeners::UnregisterVconfCallback(ListenerType type) {
+ LoggerD("");
+ switch (type) {
+ case kTimeChange:
+ is_time_listener_registered_ = false;
+ LoggerD("time change listener unregistered");
+ break;
+ case kTimezoneChange:
+ is_timezone_listener_registered_ = false;
+ LoggerD("time zone change listener unregistered");
+ break;
+ default:
+ throw UnknownException("Unknown type of listener");
+ }
+ if (!is_time_listener_registered_ && !is_timezone_listener_registered_) {
+ LoggerD("unregistering listener on platform");
+ if (0 != vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
+ OnTimeChangedCallback)) {
+ LoggerE("Failed to unregister vconf callback");
+ }
+ }
+}
+
+std::string TimeUtilListeners::GetCurrentTimezone() {
+ return current_timezone_;
+}
+
+void TimeUtilListeners::SetCurrentTimezone(std::string& newTimezone) {
+ current_timezone_ = newTimezone;
+}
+
+static std::string GetDefaultTimezone() {
+ LoggerD("");
+ char buf[1024];
+ std::string result;
+ ssize_t len = readlink("/opt/etc/localtime", buf, sizeof(buf) - 1);
+ if (len != -1) {
+ buf[len] = '\0';
+ } else {
+ /* handle error condition */
+ return result;
+ }
+ result = std::string(buf + strlen("/usr/share/zoneinfo/"));
+
+ LoggerD("tzpath = %s", result.c_str());
+ return result;
+}
+
+/////////////////////////// TimeUtilListeners object ////////////////////////
+static TimeUtilListeners g_time_util_listeners_obj;
+
+static void PostMessage(const char* message) {
+ JsonValue result{JsonObject{}};
+ JsonObject& result_obj = result.get<JsonObject>();
+ result_obj.insert(std::make_pair("listenerId", message));
+ TimeInstance::GetInstance().PostMessage(result.serialize().c_str());
+}
+
+static void OnTimeChangedCallback(keynode_t* /*node*/, void* /*event_ptr*/) {
+ LoggerD("");
+ std::string defaultTimezone = GetDefaultTimezone();
+
+ if (g_time_util_listeners_obj.GetCurrentTimezone() != defaultTimezone) {
+ g_time_util_listeners_obj.SetCurrentTimezone(defaultTimezone);
+ PostMessage(kTimezoneListenerId);
+ }
+ PostMessage(kDateTimeListenerId);
+}
+
+void TimeInstance::Time_setDateTimeChangeListener(const JsonValue& /*args*/,
+ JsonObject& out) {
+ g_time_util_listeners_obj.RegisterVconfCallback(kTimeChange);
+ ReportSuccess(out);
+}
+
+void TimeInstance::Time_unsetDateTimeChangeListener(const JsonValue& /*args*/,
+ JsonObject& out) {
+ g_time_util_listeners_obj.UnregisterVconfCallback(kTimeChange);
+ ReportSuccess(out);
+}
+
+void TimeInstance::Time_setTimezoneChangeListener(const JsonValue& /*args*/,
+ JsonObject& out) {
+ g_time_util_listeners_obj.RegisterVconfCallback(kTimezoneChange);
+ ReportSuccess(out);
+}
+
+void TimeInstance::Time_unsetTimezoneChangeListener(const JsonValue& /*args*/,
+ JsonObject& out) {
+ g_time_util_listeners_obj.UnregisterVconfCallback(kTimezoneChange);
+ ReportSuccess(out);
+}
+
} // namespace time
} // namespace extension