summaryrefslogtreecommitdiffstats
path: root/dom/time
diff options
context:
space:
mode:
Diffstat (limited to 'dom/time')
-rw-r--r--dom/time/DateCacheCleaner.cpp53
-rw-r--r--dom/time/DateCacheCleaner.h19
-rw-r--r--dom/time/TimeChangeObserver.cpp166
-rw-r--r--dom/time/TimeChangeObserver.h23
-rw-r--r--dom/time/TimeManager.cpp51
-rw-r--r--dom/time/TimeManager.h62
-rw-r--r--dom/time/TimeService.cpp40
-rw-r--r--dom/time/TimeService.h38
-rw-r--r--dom/time/moz.build29
-rw-r--r--dom/time/nsITimeService.idl20
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);
+};