diff options
Diffstat (limited to 'dom/time')
-rw-r--r-- | dom/time/DateCacheCleaner.cpp | 53 | ||||
-rw-r--r-- | dom/time/DateCacheCleaner.h | 19 | ||||
-rw-r--r-- | dom/time/TimeChangeObserver.cpp | 166 | ||||
-rw-r--r-- | dom/time/TimeChangeObserver.h | 23 | ||||
-rw-r--r-- | dom/time/TimeManager.cpp | 51 | ||||
-rw-r--r-- | dom/time/TimeManager.h | 62 | ||||
-rw-r--r-- | dom/time/TimeService.cpp | 40 | ||||
-rw-r--r-- | dom/time/TimeService.h | 38 | ||||
-rw-r--r-- | dom/time/moz.build | 29 | ||||
-rw-r--r-- | dom/time/nsITimeService.idl | 20 |
10 files changed, 501 insertions, 0 deletions
diff --git a/dom/time/DateCacheCleaner.cpp b/dom/time/DateCacheCleaner.cpp new file mode 100644 index 000000000..a55f8cb26 --- /dev/null +++ b/dom/time/DateCacheCleaner.cpp @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "DateCacheCleaner.h" + +#include "js/Date.h" +#include "mozilla/dom/ScriptSettings.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Hal.h" +#include "mozilla/StaticPtr.h" + +using namespace mozilla::hal; + +namespace mozilla { +namespace dom { +namespace time { + +class DateCacheCleaner : public SystemTimezoneChangeObserver +{ +public: + DateCacheCleaner() + { + RegisterSystemTimezoneChangeObserver(this); + } + + ~DateCacheCleaner() + { + UnregisterSystemTimezoneChangeObserver(this); + } + void Notify(const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) + { + JS::ResetTimeZone(); + } + +}; + +StaticAutoPtr<DateCacheCleaner> sDateCacheCleaner; + +void +InitializeDateCacheCleaner() +{ + if (!sDateCacheCleaner) { + sDateCacheCleaner = new DateCacheCleaner(); + ClearOnShutdown(&sDateCacheCleaner); + } +} + +} // namespace time +} // namespace dom +} // namespace mozilla diff --git a/dom/time/DateCacheCleaner.h b/dom/time/DateCacheCleaner.h new file mode 100644 index 000000000..5d734b2c4 --- /dev/null +++ b/dom/time/DateCacheCleaner.h @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +/* + * InitializeDateCacheCleaner registers DateCacheCleaner to + * SystemTimeChangeObserver. When time zone is changed, DateCacheCleaner calls + * JS::ResetTimeZone to update the time zone information. + */ + +namespace mozilla { +namespace dom { +namespace time { +void InitializeDateCacheCleaner(); +} //namespace time +} //namespace dom +} //namespace mozilla diff --git a/dom/time/TimeChangeObserver.cpp b/dom/time/TimeChangeObserver.cpp new file mode 100644 index 000000000..8d002cfcd --- /dev/null +++ b/dom/time/TimeChangeObserver.cpp @@ -0,0 +1,166 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "TimeChangeObserver.h" +#include "mozilla/Hal.h" +#include "mozilla/Observer.h" +#include "mozilla/HalTypes.h" +#include "nsWeakPtr.h" +#include "nsTObserverArray.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Services.h" +#include "mozilla/StaticPtr.h" +#include "nsPIDOMWindow.h" +#include "nsContentUtils.h" +#include "nsIObserverService.h" +#include "nsIDocument.h" + +using namespace mozilla; +using namespace mozilla::hal; +using namespace mozilla::services; + +class nsSystemTimeChangeObserver : public SystemClockChangeObserver, + public SystemTimezoneChangeObserver +{ + typedef nsTObserverArray<nsWeakPtr> ListenerArray; +public: + static nsSystemTimeChangeObserver* GetInstance(); + virtual ~nsSystemTimeChangeObserver(); + + // Implementing hal::SystemClockChangeObserver::Notify() + void Notify(const int64_t& aClockDeltaMS); + + // Implementing hal::SystemTimezoneChangeObserver::Notify() + void Notify( + const mozilla::hal::SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo); + + nsresult AddWindowListenerImpl(nsPIDOMWindowInner* aWindow); + nsresult RemoveWindowListenerImpl(nsPIDOMWindowInner* aWindow); + +private: + nsSystemTimeChangeObserver() { }; + ListenerArray mWindowListeners; + void FireMozTimeChangeEvent(); +}; + +StaticAutoPtr<nsSystemTimeChangeObserver> sObserver; + +nsSystemTimeChangeObserver* nsSystemTimeChangeObserver::GetInstance() +{ + if (!sObserver) { + sObserver = new nsSystemTimeChangeObserver(); + ClearOnShutdown(&sObserver); + } + return sObserver; +} + +nsSystemTimeChangeObserver::~nsSystemTimeChangeObserver() +{ + UnregisterSystemClockChangeObserver(this); + UnregisterSystemTimezoneChangeObserver(this); +} + +void +nsSystemTimeChangeObserver::FireMozTimeChangeEvent() +{ + ListenerArray::ForwardIterator iter(mWindowListeners); + while (iter.HasMore()) { + nsWeakPtr weakWindow = iter.GetNext(); + nsCOMPtr<nsPIDOMWindowInner> innerWindow = do_QueryReferent(weakWindow); + nsCOMPtr<nsPIDOMWindowOuter> outerWindow; + nsCOMPtr<nsIDocument> document; + if (!innerWindow || + !(document = innerWindow->GetExtantDoc()) || + !(outerWindow = innerWindow->GetOuterWindow())) { + mWindowListeners.RemoveElement(weakWindow); + continue; + } + + nsContentUtils::DispatchTrustedEvent(document, outerWindow, + NS_LITERAL_STRING("moztimechange"), /* bubbles = */ true, + /* canceable = */ false); + } +} + +void +nsSystemTimeChangeObserver::Notify(const int64_t& aClockDeltaMS) +{ + // Notify observers that the system clock has been adjusted. + nsCOMPtr<nsIObserverService> observerService = GetObserverService(); + if (observerService) { + nsString dataStr; + dataStr.AppendFloat(static_cast<double>(aClockDeltaMS)); + observerService->NotifyObservers( + nullptr, "system-clock-change", dataStr.get()); + } + + FireMozTimeChangeEvent(); +} + +void +nsSystemTimeChangeObserver::Notify( + const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo) +{ + FireMozTimeChangeEvent(); +} + +nsresult +mozilla::time::AddWindowListener(nsPIDOMWindowInner* aWindow) +{ + return nsSystemTimeChangeObserver::GetInstance()->AddWindowListenerImpl(aWindow); +} + +nsresult +nsSystemTimeChangeObserver::AddWindowListenerImpl(nsPIDOMWindowInner* aWindow) +{ + if (!aWindow) { + return NS_ERROR_ILLEGAL_VALUE; + } + + nsWeakPtr windowWeakRef = do_GetWeakReference(aWindow); + NS_ASSERTION(windowWeakRef, "nsIDOMWindow implementations shuld support weak ref"); + + if (mWindowListeners.IndexOf(windowWeakRef) != + ListenerArray::array_type::NoIndex) { + return NS_OK; + } + + if (mWindowListeners.IsEmpty()) { + RegisterSystemClockChangeObserver(sObserver); + RegisterSystemTimezoneChangeObserver(sObserver); + } + + mWindowListeners.AppendElement(windowWeakRef); + return NS_OK; +} + +nsresult +mozilla::time::RemoveWindowListener(nsPIDOMWindowInner* aWindow) +{ + if (!sObserver) { + return NS_OK; + } + + return nsSystemTimeChangeObserver::GetInstance()->RemoveWindowListenerImpl(aWindow); +} + +nsresult +nsSystemTimeChangeObserver::RemoveWindowListenerImpl(nsPIDOMWindowInner* aWindow) +{ + if (!aWindow) { + return NS_OK; + } + + nsWeakPtr windowWeakRef = do_GetWeakReference(aWindow); + mWindowListeners.RemoveElement(windowWeakRef); + + if (mWindowListeners.IsEmpty()) { + UnregisterSystemClockChangeObserver(sObserver); + UnregisterSystemTimezoneChangeObserver(sObserver); + } + + return NS_OK; +} diff --git a/dom/time/TimeChangeObserver.h b/dom/time/TimeChangeObserver.h new file mode 100644 index 000000000..65945cbff --- /dev/null +++ b/dom/time/TimeChangeObserver.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef _mozilla_time_change_observer_h_ +#define _mozilla_time_change_observer_h_ + +#include "nscore.h" + +class nsPIDOMWindowInner; + +namespace mozilla { +namespace time { + +nsresult AddWindowListener(nsPIDOMWindowInner* aWindow); +nsresult RemoveWindowListener(nsPIDOMWindowInner* aWindow); + +} // namespace time +} // namespace mozilla + +#endif //_mozilla_time_change_observer_h_ diff --git a/dom/time/TimeManager.cpp b/dom/time/TimeManager.cpp new file mode 100644 index 000000000..0fb7f1623 --- /dev/null +++ b/dom/time/TimeManager.cpp @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "TimeManager.h" + +#include "mozilla/dom/Date.h" +#include "mozilla/dom/MozTimeManagerBinding.h" +#include "nsITimeService.h" +#include "nsServiceManagerUtils.h" + +namespace mozilla { +namespace dom { +namespace time { + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TimeManager) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(TimeManager) +NS_IMPL_CYCLE_COLLECTING_RELEASE(TimeManager) + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TimeManager, mWindow) + +JSObject* +TimeManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) +{ + return MozTimeManagerBinding::Wrap(aCx, this, aGivenProto); +} + +void +TimeManager::Set(Date& aDate) +{ + Set(aDate.ToDouble()); +} + +void +TimeManager::Set(double aTime) +{ + nsCOMPtr<nsITimeService> timeService = do_GetService(TIMESERVICE_CONTRACTID); + if (timeService) { + timeService->Set(aTime); + } +} + +} // namespace time +} // namespace dom +} // namespace mozilla diff --git a/dom/time/TimeManager.h b/dom/time/TimeManager.h new file mode 100644 index 000000000..8c58342b9 --- /dev/null +++ b/dom/time/TimeManager.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_dom_time_TimeManager_h +#define mozilla_dom_time_TimeManager_h + +#include "mozilla/Attributes.h" +#include "nsISupports.h" +#include "nsPIDOMWindow.h" +#include "nsWrapperCache.h" + +namespace mozilla { +namespace dom { + +class Date; + +namespace time { + +class TimeManager final : public nsISupports + , public nsWrapperCache +{ +public: + static bool PrefEnabled(JSContext* aCx, JSObject* aGlobal) + { +#ifdef MOZ_TIME_MANAGER + return true; +#else + return false; +#endif + } + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TimeManager) + + explicit TimeManager(nsPIDOMWindowInner* aWindow) + : mWindow(aWindow) + { + } + + nsPIDOMWindowInner* GetParentObject() const + { + return mWindow; + } + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; + + void Set(Date& aDate); + void Set(double aTime); + +private: + ~TimeManager() {} + + nsCOMPtr<nsPIDOMWindowInner> mWindow; +}; + +} // namespace time +} // namespace dom +} // namespace mozilla + +#endif //mozilla_dom_time_TimeManager_h diff --git a/dom/time/TimeService.cpp b/dom/time/TimeService.cpp new file mode 100644 index 000000000..edbd97d51 --- /dev/null +++ b/dom/time/TimeService.cpp @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/basictypes.h" +#include "jsapi.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/Hal.h" +#include "TimeService.h" + +namespace mozilla { +namespace dom { +namespace time { + +NS_IMPL_ISUPPORTS(TimeService, nsITimeService) + +/* static */ StaticRefPtr<TimeService> TimeService::sSingleton; + +/* static */ already_AddRefed<TimeService> +TimeService::GetInstance() +{ + if (!sSingleton) { + sSingleton = new TimeService(); + ClearOnShutdown(&sSingleton); + } + RefPtr<TimeService> service = sSingleton.get(); + return service.forget(); +} + +NS_IMETHODIMP +TimeService::Set(int64_t aTimeInMS) { + hal::AdjustSystemClock(aTimeInMS - (JS_Now() / PR_USEC_PER_MSEC)); + return NS_OK; +} + +} // namespace time +} // namespace dom +} // namespace mozilla diff --git a/dom/time/TimeService.h b/dom/time/TimeService.h new file mode 100644 index 000000000..4c802cf05 --- /dev/null +++ b/dom/time/TimeService.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_dom_time_TimeService_h +#define mozilla_dom_time_TimeService_h + +#include "mozilla/StaticPtr.h" +#include "nsITimeService.h" + +namespace mozilla { +namespace dom { +namespace time { + +/** + * This class implements a service which lets us modify the system clock time. + */ +class TimeService : public nsITimeService +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSITIMESERVICE + + static already_AddRefed<TimeService> GetInstance(); + +private: + virtual ~TimeService() {}; + + static StaticRefPtr<TimeService> sSingleton; +}; + +} // namespace time +} // namespace dom +} // namespace mozilla + +#endif //mozilla_dom_time_TimeService_h diff --git a/dom/time/moz.build b/dom/time/moz.build new file mode 100644 index 000000000..f6ef682c6 --- /dev/null +++ b/dom/time/moz.build @@ -0,0 +1,29 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +XPIDL_SOURCES += [ + 'nsITimeService.idl', +] + +XPIDL_MODULE = 'dom_time' + +EXPORTS.mozilla.dom.time += [ + 'DateCacheCleaner.h', + 'TimeChangeObserver.h', + 'TimeManager.h', + 'TimeService.h', +] + +UNIFIED_SOURCES += [ + 'DateCacheCleaner.cpp', + 'TimeChangeObserver.cpp', + 'TimeManager.cpp', + 'TimeService.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' diff --git a/dom/time/nsITimeService.idl b/dom/time/nsITimeService.idl new file mode 100644 index 000000000..2bba628e9 --- /dev/null +++ b/dom/time/nsITimeService.idl @@ -0,0 +1,20 @@ +/* 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 "nsISupports.idl" + +%{C++ +#define NS_TIMESERVICE_CID { 0x80d6f9cc, 0xf16d, 0x40c3, { 0xa5, 0x2e, 0xc4, 0xe6, 0x56, 0xe3, 0x65, 0xb4 } } +#define TIMESERVICE_CONTRACTID "@mozilla.org/time/timeservice;1" +%} + +[scriptable, builtinclass, uuid(1fc7fde2-0090-11e2-bdd6-0fea4b9f41f8)] +interface nsITimeService : nsISupports +{ + /* Set the system time. + * + * The |aTimeInMS| argument is the time in milliseconds since the epoch. + */ + void set(in int64_t aTimeInMS); +}; |