diff options
Diffstat (limited to 'dom/system/gonk/TimeZoneSettingObserver.cpp')
-rw-r--r-- | dom/system/gonk/TimeZoneSettingObserver.cpp | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/dom/system/gonk/TimeZoneSettingObserver.cpp b/dom/system/gonk/TimeZoneSettingObserver.cpp deleted file mode 100644 index 512f79908..000000000 --- a/dom/system/gonk/TimeZoneSettingObserver.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "base/message_loop.h" -#include "jsapi.h" -#include "mozilla/dom/ScriptSettings.h" -#include "mozilla/Attributes.h" -#include "mozilla/ClearOnShutdown.h" -#include "mozilla/Hal.h" -#include "mozilla/Services.h" -#include "mozilla/StaticPtr.h" -#include "nsCOMPtr.h" -#include "nsDebug.h" -#include "nsIObserver.h" -#include "nsIObserverService.h" -#include "nsISettingsService.h" -#include "nsJSUtils.h" -#include "nsServiceManagerUtils.h" -#include "nsString.h" -#include "TimeZoneSettingObserver.h" -#include "xpcpublic.h" -#include "nsContentUtils.h" -#include "nsPrintfCString.h" -#include "mozilla/dom/BindingUtils.h" -#include "mozilla/dom/SettingChangeNotificationBinding.h" - -#undef LOG -#undef ERR -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Time Zone Setting" , ## args) -#define ERR(args...) __android_log_print(ANDROID_LOG_ERROR, "Time Zone Setting" , ## args) - -#define TIME_TIMEZONE "time.timezone" -#define MOZSETTINGS_CHANGED "mozsettings-changed" - -using namespace mozilla; -using namespace mozilla::dom; - -namespace { - -class TimeZoneSettingObserver : public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - TimeZoneSettingObserver(); - static nsresult SetTimeZone(const JS::Value &aValue, JSContext *aContext); - -protected: - virtual ~TimeZoneSettingObserver(); -}; - -class TimeZoneSettingCb final : public nsISettingsServiceCallback -{ -public: - NS_DECL_ISUPPORTS - - TimeZoneSettingCb() {} - - NS_IMETHOD Handle(const nsAString &aName, JS::Handle<JS::Value> aResult) { - - JSContext *cx = nsContentUtils::GetCurrentJSContext(); - NS_ENSURE_TRUE(cx, NS_OK); - - // If we don't have time.timezone value in the settings, we need - // to initialize the settings based on the current system timezone - // to make settings consistent with system. This usually happens - // at the very first boot. After that, settings must have a value. - if (aResult.isNull()) { - // Get the current system time zone offset. Note that we need to - // convert the value to a UTC representation in the format of - // "UTC{+,-}hh:mm", so that the Gaia end can know how to interpret. - // E.g., -480 is "UTC+08:00"; 630 is "UTC-10:30". - int32_t timeZoneOffset = hal::GetTimezoneOffset(); - nsPrintfCString curTimeZone("UTC%+03d:%02d", - -timeZoneOffset / 60, - abs(timeZoneOffset) % 60); - - // Convert it to a JS string. - NS_ConvertUTF8toUTF16 utf16Str(curTimeZone); - - JS::Rooted<JSString*> jsStr(cx, JS_NewUCStringCopyN(cx, - utf16Str.get(), - utf16Str.Length())); - if (!jsStr) { - return NS_ERROR_OUT_OF_MEMORY; - } - - // Set the settings based on the current system timezone. - nsCOMPtr<nsISettingsServiceLock> lock; - nsCOMPtr<nsISettingsService> settingsService = - do_GetService("@mozilla.org/settingsService;1"); - if (!settingsService) { - ERR("Failed to get settingsLock service!"); - return NS_OK; - } - settingsService->CreateLock(nullptr, getter_AddRefs(lock)); - JS::Rooted<JS::Value> value(cx, JS::StringValue(jsStr)); - lock->Set(TIME_TIMEZONE, value, nullptr, nullptr); - return NS_OK; - } - - // Set the system timezone based on the current settings. - if (aResult.isString()) { - return TimeZoneSettingObserver::SetTimeZone(aResult, cx); - } - - return NS_OK; - } - - NS_IMETHOD HandleError(const nsAString &aName) { - ERR("TimeZoneSettingCb::HandleError: %s\n", NS_LossyConvertUTF16toASCII(aName).get()); - return NS_OK; - } - -protected: - ~TimeZoneSettingCb() {} -}; - -NS_IMPL_ISUPPORTS(TimeZoneSettingCb, nsISettingsServiceCallback) - -TimeZoneSettingObserver::TimeZoneSettingObserver() -{ - // Setup an observer to watch changes to the setting. - nsCOMPtr<nsIObserverService> observerService = services::GetObserverService(); - if (!observerService) { - ERR("GetObserverService failed"); - return; - } - nsresult rv; - rv = observerService->AddObserver(this, MOZSETTINGS_CHANGED, false); - if (NS_FAILED(rv)) { - ERR("AddObserver failed"); - return; - } - - // Read the 'time.timezone' setting in order to start with a known - // value at boot time. The handle() will be called after reading. - nsCOMPtr<nsISettingsServiceLock> lock; - nsCOMPtr<nsISettingsService> settingsService = - do_GetService("@mozilla.org/settingsService;1"); - if (!settingsService) { - ERR("Failed to get settingsLock service!"); - return; - } - settingsService->CreateLock(nullptr, getter_AddRefs(lock)); - nsCOMPtr<nsISettingsServiceCallback> callback = new TimeZoneSettingCb(); - lock->Get(TIME_TIMEZONE, callback); -} - -nsresult TimeZoneSettingObserver::SetTimeZone(const JS::Value &aValue, JSContext *aContext) -{ - // Convert the JS value to a nsCString type. - // The value should be a JS string like "America/Chicago" or "UTC-05:00". - nsAutoJSString valueStr; - if (!valueStr.init(aContext, aValue.toString())) { - ERR("Failed to convert JS value to nsCString"); - return NS_ERROR_FAILURE; - } - NS_ConvertUTF16toUTF8 newTimezone(valueStr); - - // Hal expects opposite sign from general notations, - // so we need to flip it. - if (newTimezone.Find(NS_LITERAL_CSTRING("UTC+")) == 0) { - if (!newTimezone.SetCharAt('-', 3)) { - return NS_ERROR_FAILURE; - } - } else if (newTimezone.Find(NS_LITERAL_CSTRING("UTC-")) == 0) { - if (!newTimezone.SetCharAt('+', 3)) { - return NS_ERROR_FAILURE; - } - } - - // Set the timezone only when the system timezone is not identical. - nsCString curTimezone = hal::GetTimezone(); - if (!curTimezone.Equals(newTimezone)) { - hal::SetTimezone(newTimezone); - } - - return NS_OK; -} - -TimeZoneSettingObserver::~TimeZoneSettingObserver() -{ - nsCOMPtr<nsIObserverService> observerService = services::GetObserverService(); - if (observerService) { - observerService->RemoveObserver(this, MOZSETTINGS_CHANGED); - } -} - -NS_IMPL_ISUPPORTS(TimeZoneSettingObserver, nsIObserver) - -NS_IMETHODIMP -TimeZoneSettingObserver::Observe(nsISupports *aSubject, - const char *aTopic, - const char16_t *aData) -{ - if (strcmp(aTopic, MOZSETTINGS_CHANGED) != 0) { - return NS_OK; - } - - // Note that this function gets called for any and all settings changes, - // so we need to carefully check if we have the one we're interested in. - // - // The string that we're interested in will be a JSON string that looks like: - // {"key":"time.timezone","value":"America/Chicago"} or - // {"key":"time.timezone","value":"UTC-05:00"} - - AutoSafeJSContext cx; - RootedDictionary<SettingChangeNotification> setting(cx); - if (!WrappedJSToDictionary(cx, aSubject, setting)) { - return NS_OK; - } - if (!setting.mKey.EqualsASCII(TIME_TIMEZONE)) { - return NS_OK; - } - if (!setting.mValue.isString()) { - return NS_OK; - } - - // Set the system timezone. - return SetTimeZone(setting.mValue, cx); -} - -} // namespace - -static mozilla::StaticRefPtr<TimeZoneSettingObserver> sTimeZoneSettingObserver; -namespace mozilla { -namespace system { -void -InitializeTimeZoneSettingObserver() -{ - sTimeZoneSettingObserver = new TimeZoneSettingObserver(); - ClearOnShutdown(&sTimeZoneSettingObserver); -} - -} // namespace system -} // namespace mozilla |