diff --git a/dom/time/nsIDOMTimeManager.idl b/dom/time/nsIDOMTimeManager.idl index 0a026caf1d16..af2f7eceaf46 100644 --- a/dom/time/nsIDOMTimeManager.idl +++ b/dom/time/nsIDOMTimeManager.idl @@ -16,5 +16,5 @@ interface nsIDOMMozTimeManager : nsISupports * - If |time| is a Date object, |set(time)| is equivalent to * |set(time.getTime())|. */ - void set(in jsval time); + [implicit_jscontext] void set(in jsval time); }; diff --git a/hal/Hal.cpp b/hal/Hal.cpp index d66909d8fa36..bdb58eb1e5e3 100644 --- a/hal/Hal.cpp +++ b/hal/Hal.cpp @@ -406,7 +406,39 @@ bool GetLight(LightType light, hal::LightConfiguration* aConfig) RETURN_PROXY_IF_SANDBOXED(GetLight(light, aConfig)); } +static StaticAutoPtr> sSystemTimeObserver; +static void +InitializeSystemTimeChangeObserver() +{ + if (!sSystemTimeObserver) { + sSystemTimeObserver = new ObserverList; + ClearOnShutdown(&sSystemTimeObserver); + } +} + +void +RegisterSystemTimeChangeObserver(SystemTimeObserver *aObserver) +{ + AssertMainThread(); + InitializeSystemTimeChangeObserver(); + sSystemTimeObserver->AddObserver(aObserver); +} + +void +UnregisterSystemTimeChangeObserver(SystemTimeObserver *aObserver) +{ + AssertMainThread(); + sSystemTimeObserver->RemoveObserver(aObserver); +} + +void +NotifySystemTimeChange(const hal::SystemTimeChange& aReason) +{ + InitializeSystemTimeChangeObserver(); + sSystemTimeObserver->Broadcast(aReason); +} + void AdjustSystemClock(int32_t aDeltaMilliseconds) { diff --git a/hal/Hal.h b/hal/Hal.h index 19f9178be865..afe066f12dda 100644 --- a/hal/Hal.h +++ b/hal/Hal.h @@ -50,6 +50,8 @@ class WindowIdentifier; extern PRLogModuleInfo *sHalLog; #define HAL_LOG(msg) PR_LOG(mozilla::hal::sHalLog, PR_LOG_DEBUG, msg) +typedef Observer SystemTimeObserver; + } // namespace hal namespace MOZ_HAL_NAMESPACE { @@ -255,6 +257,24 @@ void SetTimezone(const nsCString& aTimezoneSpec); */ nsCString GetTimezone(); +/** + * Register observer for system time changed notification. + * @param aObserver The observer that should be added. + */ +void RegisterSystemTimeChangeObserver(hal::SystemTimeObserver* aObserver); + +/** + * Unregister the observer for system time changed. + * @param aObserver The observer that should be removed. + */ +void UnregisterSystemTimeChangeObserver(hal::SystemTimeObserver* aObserver); + +/** + * Notify of a change in the system cloeck or time zone. + * @param aReason + */ +void NotifySystemTimeChange(const hal::SystemTimeChange& aReason); + /** * Reboot the device. */ diff --git a/hal/HalTypes.h b/hal/HalTypes.h index 65b0b85a93b1..e93147e02c6d 100644 --- a/hal/HalTypes.h +++ b/hal/HalTypes.h @@ -74,6 +74,13 @@ enum WakeLockControl { NUM_WAKE_LOCK }; +enum SystemTimeChange { + SYS_TIME_CHANGE_UNKNOWN = -1, + SYS_TIME_CHANGE_CLOCK, + SYS_TIME_CHANGE_TZ, + SYS_TIME_CHANGE_GUARD +}; + } // namespace hal } // namespace mozilla @@ -146,7 +153,16 @@ struct ParamTraits: mozilla::hal::NUM_PROCESS_PRIORITY> { }; - +/** + * SystemTimeChange serializer. + */ +template <> +struct ParamTraits + : public EnumSerializer +{}; + } // namespace IPC #endif // mozilla_hal_Types_h diff --git a/hal/gonk/GonkHal.cpp b/hal/gonk/GonkHal.cpp index 228d99249cbf..ea5ed339d785 100644 --- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -581,6 +581,10 @@ sys_clock_settime(clockid_t clk_id, const struct timespec *tp) void AdjustSystemClock(int32_t aDeltaMilliseconds) { + if (aDeltaMilliseconds == 0) { + return; + } + struct timespec now; // Preventing context switch before setting system clock @@ -600,16 +604,26 @@ AdjustSystemClock(int32_t aDeltaMilliseconds) now.tv_sec -= 1; } // we need to have root privilege. - sys_clock_settime(CLOCK_REALTIME, &now); + if (sys_clock_settime(CLOCK_REALTIME, &now) != 0) { + NS_ERROR("sys_clock_settime failed"); + return; + } + + hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_CLOCK); } void SetTimezone(const nsCString& aTimezoneSpec) -{ +{ + if (aTimezoneSpec.Equals(GetTimezone())) { + return; + } + property_set("persist.sys.timezone", aTimezoneSpec.get()); // this function is automatically called by the other time conversion // functions that depend on the timezone. To be safe, we call it manually. tzset(); + hal::NotifySystemTimeChange(hal::SYS_TIME_CHANGE_TZ); } nsCString diff --git a/hal/sandbox/PHal.ipdl b/hal/sandbox/PHal.ipdl index f8124936eb16..5b6fb70e1d2a 100644 --- a/hal/sandbox/PHal.ipdl +++ b/hal/sandbox/PHal.ipdl @@ -24,6 +24,7 @@ using mozilla::hal::SwitchDevice; using mozilla::hal::ProcessPriority; using nsIntRect; using PRTime; +using mozilla::hal::SystemTimeChange; namespace mozilla { @@ -86,6 +87,7 @@ child: NotifyWakeLockChange(WakeLockInformation aWakeLockInfo); NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation); NotifySwitchChange(SwitchEvent aEvent); + NotifySystemTimeChange(SystemTimeChange aReason); parent: Vibrate(uint32_t[] pattern, uint64_t[] id, PBrowser browser); diff --git a/hal/sandbox/SandboxHal.cpp b/hal/sandbox/SandboxHal.cpp index 0dd97f392799..0e8c97f67810 100644 --- a/hal/sandbox/SandboxHal.cpp +++ b/hal/sandbox/SandboxHal.cpp @@ -676,6 +676,11 @@ public: hal::SetProcessPriority(aPid, aPriority); return true; } + + void Notify(const SystemTimeChange& aReason) + { + unused << SendNotifySystemTimeChange(aReason); + } }; class HalChild : public PHalChild { @@ -712,6 +717,12 @@ public: hal::NotifySwitchChange(aEvent); return true; } + + virtual bool + RecvNotifySystemTimeChange(const SystemTimeChange& aReason) { + hal::NotifySystemTimeChange(aReason); + return true; + } }; bool