Bug 789973 - B2G system time: adjust system clock after receiving NITZ timestamp (part 1). r=jlebar
authorGene Lian <clian@mozilla.com>
Fri, 28 Sep 2012 14:02:28 +0800
changeset 112090 99bf6b597e44406f3973a04b5da84fd01ff8f771
parent 112089 5caa455ee5649bc5abb053da698053003755890b
child 112091 dacfa6d8c92ed5299b4be3b23a97dcfb1d258a33
push idunknown
push userunknown
push dateunknown
reviewersjlebar
bugs789973
milestone18.0a1
Bug 789973 - B2G system time: adjust system clock after receiving NITZ timestamp (part 1). r=jlebar
content/events/src/nsEventListenerManager.cpp
dom/time/Makefile.in
dom/time/TimeManager.cpp
dom/time/TimeManager.h
dom/time/TimeService.cpp
dom/time/TimeService.h
dom/time/nsITimeService.idl
layout/build/nsLayoutModule.cpp
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -49,17 +49,17 @@
 #include "nsDOMScriptObjectHolder.h"
 #include "nsDataHashtable.h"
 #include "nsCOMArray.h"
 #include "nsEventListenerService.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsJSEnvironment.h"
 #include "xpcpublic.h"
 #include "nsSandboxFlags.h"
-#include "TimeChangeObserver.h"
+#include "mozilla/dom/time/TimeChangeObserver.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::hal;
 
 #define EVENT_TYPE_EQUALS( ls, type, userType ) \
   (ls->mEventType == type && \
   (ls->mEventType != NS_USER_DEFINED_EVENT || ls->mTypeAtom == userType))
 
--- a/dom/time/Makefile.in
+++ b/dom/time/Makefile.in
@@ -4,33 +4,39 @@
 
 DEPTH            = ../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+MODULE           = dom
 LIBRARY_NAME     = dom_time_s
 XPIDL_MODULE     = dom_time
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
 FAIL_ON_WARNINGS := 1
 
 include $(topsrcdir)/dom/dom-config.mk
 
+EXPORTS_NAMESPACES = mozilla/dom/time
+
 CPPSRCS = \
   TimeManager.cpp \
+  TimeService.cpp \
   TimeChangeObserver.cpp \
   $(NULL)
 
-EXPORTS = \
+EXPORTS_mozilla/dom/time = \
+  TimeService.h \
   TimeChangeObserver.h \
   $(NULL)
 
 XPIDLSRCS = \
   nsIDOMNavigatorTime.idl \
   nsIDOMTimeManager.idl \
+  nsITimeService.idl \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
--- a/dom/time/TimeManager.cpp
+++ b/dom/time/TimeManager.cpp
@@ -1,21 +1,17 @@
 /* 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 "jsapi.h"
-#include "mozilla/Hal.h"
-#include "nsDOMEvent.h"
-#include "nsDOMEventTargetHelper.h"
 #include "nsIDOMClassInfo.h"
-#include "prtime.h"
+#include "nsITimeService.h"
 #include "TimeManager.h"
 
-using namespace mozilla::hal;
-
 DOMCI_DATA(MozTimeManager, mozilla::dom::time::TimeManager)
 
 namespace mozilla {
 namespace dom {
 namespace time {
 
 NS_INTERFACE_MAP_BEGIN(TimeManager)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMozTimeManager)
@@ -23,17 +19,16 @@ NS_INTERFACE_MAP_BEGIN(TimeManager)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozTimeManager)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(TimeManager)
 NS_IMPL_RELEASE(TimeManager)
 
 nsresult
 TimeManager::Set(const JS::Value& date, JSContext* ctx) {
-  double nowMSec = JS_Now() / 1000;
   double dateMSec;
 
   if (date.isObject()) {
     JSObject* dateObj = JSVAL_TO_OBJECT(date);
 
     if (JS_ObjectIsDate(ctx, dateObj) && js_DateIsValid(ctx, dateObj)) {
       dateMSec = js_DateGetMsecSinceEpoch(ctx, dateObj);
     }
@@ -43,15 +38,18 @@ TimeManager::Set(const JS::Value& date, 
       return NS_ERROR_INVALID_ARG;
     }
   } else if (date.isNumber()) {
     dateMSec = date.toNumber();
   } else {
     return NS_ERROR_INVALID_ARG;
   }
 
-  hal::AdjustSystemClock(dateMSec - nowMSec);
+  nsCOMPtr<nsITimeService> timeService = do_GetService(TIMESERVICE_CONTRACTID);
+  if (timeService) {
+    return timeService->Set(dateMSec);
+  }
   return NS_OK;
 }
 
 } // namespace time
 } // namespace dom
 } // namespace mozilla
--- a/dom/time/TimeManager.h
+++ b/dom/time/TimeManager.h
@@ -1,28 +1,22 @@
 /* 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/HalTypes.h"
 #include "nsIDOMTimeManager.h"
-#include "mozilla/Observer.h"
 #include "mozilla/Attributes.h"
 
-class nsPIDOMWindow;
-
 namespace mozilla {
-
-typedef Observer<hal::SystemTimeChange> SystemTimeObserver;
-
 namespace dom {
 namespace time {
+
 class TimeManager MOZ_FINAL : public nsIDOMMozTimeManager
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMMOZTIMEMANAGER
 };
 
 } // namespace time
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeService.cpp
@@ -0,0 +1,38 @@
+/* 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_ISUPPORTS1(TimeService, nsITimeService)
+
+/* static */ StaticRefPtr<TimeService> TimeService::sSingleton;
+
+/* static */ already_AddRefed<TimeService>
+TimeService::GetInstance()
+{
+  if (!sSingleton) {
+    sSingleton = new TimeService();
+    ClearOnShutdown(&sSingleton);
+  }
+  nsRefPtr<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
new file mode 100644
--- /dev/null
+++ b/dom/time/TimeService.h
@@ -0,0 +1,35 @@
+/* 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
+
+  virtual ~TimeService() {};
+  static already_AddRefed<TimeService> GetInstance();
+
+private:
+  static StaticRefPtr<TimeService> sSingleton;
+};
+
+} // namespace time
+} // namespace dom
+} // namespace mozilla
+
+#endif //mozilla_dom_time_TimeService_h
new file mode 100644
--- /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);
+};
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -236,26 +236,27 @@ static void Shutdown();
 #include "mozilla/dom/sms/SmsRequestManager.h"
 #include "mozilla/dom/sms/SmsServicesFactory.h"
 #include "nsIPowerManagerService.h"
 #include "nsIAlarmHalService.h"
 #include "nsMixedContentBlocker.h"
 
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/alarm/AlarmHalService.h"
+#include "mozilla/dom/time/TimeService.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::dom::file;
 using namespace mozilla::dom::sms;
 using mozilla::dom::alarm::AlarmHalService;
 using mozilla::dom::indexedDB::IndexedDatabaseManager;
 using mozilla::dom::power::PowerManagerService;
 using mozilla::dom::TCPSocketChild;
-
+using mozilla::dom::time::TimeService;
 
 // Transformiix
 /* 5d5d92cd-6bf8-11d9-bf4a-000a95dc234c */
 #define TRANSFORMIIX_NODESET_CID \
 { 0x5d5d92cd, 0x6bf8, 0x11d9, { 0xbf, 0x4a, 0x0, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
 
 #define TRANSFORMIIX_NODESET_CONTRACTID \
 "@mozilla.org/transformiix-nodeset;1"
@@ -310,16 +311,18 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHapticF
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(ThirdPartyUtil, Init)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsService, SmsServicesFactory::CreateSmsService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISmsDatabaseService, SmsServicesFactory::CreateSmsDatabaseService)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIPowerManagerService,
                                          PowerManagerService::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(SmsRequestManager)
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIAlarmHalService,
                                          AlarmHalService::GetInstance)
+NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITimeService,
+                                         TimeService::GetInstance)
 
 //-----------------------------------------------------------------------------
 
 // Per bug 209804, it is necessary to observe the "xpcom-shutdown" event and
 // perform shutdown of the layout modules at that time instead of waiting for
 // our module destructor to run.  If we do not do this, then we risk holding
 // references to objects in other component libraries that have already been
 // shutdown (and possibly unloaded if 60709 is ever fixed).
@@ -823,16 +826,17 @@ NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CI
 #endif
 NS_DEFINE_NAMED_CID(SMS_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_DATABASE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(SMS_REQUEST_MANAGER_CID);
 NS_DEFINE_NAMED_CID(NS_POWERMANAGERSERVICE_CID);
 NS_DEFINE_NAMED_CID(OSFILECONSTANTSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_ALARMHALSERVICE_CID);
 NS_DEFINE_NAMED_CID(TCPSOCKETCHILD_CID);
+NS_DEFINE_NAMED_CID(NS_TIMESERVICE_CID);
 
 static nsresult
 CreateWindowCommandTableConstructor(nsISupports *aOuter,
                                     REFNSIID aIID, void **aResult)
 {
   nsresult rv;
   nsCOMPtr<nsIControllerCommandTable> commandTable =
       do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
@@ -1102,16 +1106,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_DOMMUTATIONOBSERVER_CID, false, NULL, nsDOMMutationObserverConstructor },
   { &kSMS_SERVICE_CID, false, NULL, nsISmsServiceConstructor },
   { &kSMS_DATABASE_SERVICE_CID, false, NULL, nsISmsDatabaseServiceConstructor },
   { &kSMS_REQUEST_MANAGER_CID, false, NULL, SmsRequestManagerConstructor },
   { &kNS_POWERMANAGERSERVICE_CID, false, NULL, nsIPowerManagerServiceConstructor },
   { &kOSFILECONSTANTSSERVICE_CID, true, NULL, OSFileConstantsServiceConstructor },
   { &kNS_ALARMHALSERVICE_CID, false, NULL, nsIAlarmHalServiceConstructor },
   { &kTCPSOCKETCHILD_CID, false, NULL, TCPSocketChildConstructor },
+  { &kNS_TIMESERVICE_CID, false, NULL, nsITimeServiceConstructor },
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
   XPCONNECT_CONTRACTS
   { "@mozilla.org/layout/xul-boxobject;1", &kNS_BOXOBJECT_CID },
 #ifdef MOZ_XUL
   { "@mozilla.org/layout/xul-boxobject-listbox;1", &kNS_LISTBOXOBJECT_CID },
@@ -1246,16 +1251,17 @@ static const mozilla::Module::ContractID
   { NS_DOMMUTATIONOBSERVER_CONTRACTID, &kNS_DOMMUTATIONOBSERVER_CID },
   { SMS_SERVICE_CONTRACTID, &kSMS_SERVICE_CID },
   { SMS_DATABASE_SERVICE_CONTRACTID, &kSMS_DATABASE_SERVICE_CID },
   { SMS_REQUEST_MANAGER_CONTRACTID, &kSMS_REQUEST_MANAGER_CID },
   { POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID },
   { OSFILECONSTANTSSERVICE_CONTRACTID, &kOSFILECONSTANTSSERVICE_CID },
   { ALARMHALSERVICE_CONTRACTID, &kNS_ALARMHALSERVICE_CID },
   { "@mozilla.org/tcp-socket-child;1", &kTCPSOCKETCHILD_CID },
+  { TIMESERVICE_CONTRACTID, &kNS_TIMESERVICE_CID },
   { NULL }
 };
 
 static const mozilla::Module::CategoryEntry kLayoutCategories[] = {
   XPCONNECT_CATEGORIES
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY, "Image", NS_HTMLIMGELEMENT_CONTRACTID },
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_PROTO_ALIAS_CATEGORY, "Image", "HTMLImageElement" },
   { JAVASCRIPT_GLOBAL_CONSTRUCTOR_CATEGORY, "Option", NS_HTMLOPTIONELEMENT_CONTRACTID },