dom/time/TimeChangeObserver.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "TimeChangeObserver.h"
     7 #include "mozilla/Hal.h"
     8 #include "mozilla/Observer.h"
     9 #include "mozilla/HalTypes.h"
    10 #include "nsWeakPtr.h"
    11 #include "nsTObserverArray.h"
    12 #include "mozilla/ClearOnShutdown.h"
    13 #include "mozilla/Services.h"
    14 #include "mozilla/StaticPtr.h"
    15 #include "nsPIDOMWindow.h"
    16 #include "nsContentUtils.h"
    17 #include "nsIObserverService.h"
    18 #include "nsIDocument.h"
    20 using namespace mozilla;
    21 using namespace mozilla::hal;
    22 using namespace mozilla::services;
    24 class nsSystemTimeChangeObserver : public SystemClockChangeObserver,
    25                                    public SystemTimezoneChangeObserver
    26 {
    27   typedef nsTObserverArray<nsWeakPtr> ListenerArray;
    28 public:
    29   static nsSystemTimeChangeObserver* GetInstance();
    30   virtual ~nsSystemTimeChangeObserver();
    32   // Implementing hal::SystemClockChangeObserver::Notify()
    33   void Notify(const int64_t& aClockDeltaMS);
    35   // Implementing hal::SystemTimezoneChangeObserver::Notify()
    36   void Notify(
    37     const mozilla::hal::SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo);
    39   nsresult AddWindowListenerImpl(nsPIDOMWindow* aWindow);
    40   nsresult RemoveWindowListenerImpl(nsPIDOMWindow* aWindow);
    42 private:
    43   nsSystemTimeChangeObserver() { };
    44   ListenerArray mWindowListeners;
    45   void FireMozTimeChangeEvent();
    46 };
    48 StaticAutoPtr<nsSystemTimeChangeObserver> sObserver;
    50 nsSystemTimeChangeObserver* nsSystemTimeChangeObserver::GetInstance()
    51 {
    52   if (!sObserver) {
    53     sObserver = new nsSystemTimeChangeObserver();
    54     ClearOnShutdown(&sObserver);
    55   }
    56   return sObserver;
    57 }
    59 nsSystemTimeChangeObserver::~nsSystemTimeChangeObserver()
    60 {
    61   UnregisterSystemClockChangeObserver(this);
    62   UnregisterSystemTimezoneChangeObserver(this);
    63 }
    65 void
    66 nsSystemTimeChangeObserver::FireMozTimeChangeEvent()
    67 {
    68   ListenerArray::ForwardIterator iter(mWindowListeners);
    69   while (iter.HasMore()) {
    70     nsWeakPtr weakWindow = iter.GetNext();
    71     nsCOMPtr<nsPIDOMWindow> innerWindow = do_QueryReferent(weakWindow);
    72     nsCOMPtr<nsPIDOMWindow> outerWindow;
    73     nsCOMPtr<nsIDocument> document;
    74     if (!innerWindow ||
    75         !(document = innerWindow->GetExtantDoc()) ||
    76         !(outerWindow = innerWindow->GetOuterWindow())) {
    77       mWindowListeners.RemoveElement(weakWindow);
    78       continue;
    79     }
    81     nsContentUtils::DispatchTrustedEvent(document, outerWindow,
    82       NS_LITERAL_STRING("moztimechange"), /* bubbles = */ true,
    83       /* canceable = */ false);
    84   }
    85 }
    87 void
    88 nsSystemTimeChangeObserver::Notify(const int64_t& aClockDeltaMS)
    89 {
    90   // Notify observers that the system clock has been adjusted.
    91   nsCOMPtr<nsIObserverService> observerService = GetObserverService();
    92   if (observerService) {
    93     nsString dataStr;
    94     dataStr.AppendFloat(static_cast<double>(aClockDeltaMS));
    95     observerService->NotifyObservers(
    96       nullptr, "system-clock-change", dataStr.get());
    97   }
    99   FireMozTimeChangeEvent();
   100 }
   102 void
   103 nsSystemTimeChangeObserver::Notify(
   104   const SystemTimezoneChangeInformation& aSystemTimezoneChangeInfo)
   105 {
   106   FireMozTimeChangeEvent();
   107 }
   109 nsresult
   110 mozilla::time::AddWindowListener(nsPIDOMWindow* aWindow)
   111 {
   112   return nsSystemTimeChangeObserver::GetInstance()->AddWindowListenerImpl(aWindow);
   113 }
   115 nsresult
   116 nsSystemTimeChangeObserver::AddWindowListenerImpl(nsPIDOMWindow* aWindow)
   117 {
   118   if (!aWindow) {
   119     return NS_ERROR_ILLEGAL_VALUE;
   120   }
   122   if (aWindow->IsOuterWindow()) {
   123     aWindow = aWindow->GetCurrentInnerWindow();
   124     if (!aWindow) {
   125       return NS_ERROR_FAILURE;
   126     }
   127   }
   129   nsWeakPtr windowWeakRef = do_GetWeakReference(aWindow);
   130   NS_ASSERTION(windowWeakRef, "nsIDOMWindow implementations shuld support weak ref");
   132   if (mWindowListeners.IndexOf(windowWeakRef) !=
   133       ListenerArray::array_type::NoIndex) {
   134     return NS_OK;
   135   }
   137   if (mWindowListeners.IsEmpty()) {
   138     RegisterSystemClockChangeObserver(sObserver);
   139     RegisterSystemTimezoneChangeObserver(sObserver);
   140   }
   142   mWindowListeners.AppendElement(windowWeakRef);
   143   return NS_OK;
   144 }
   146 nsresult
   147 mozilla::time::RemoveWindowListener(nsPIDOMWindow* aWindow)
   148 {
   149   if (!sObserver) {
   150     return NS_OK;
   151   }
   153   return nsSystemTimeChangeObserver::GetInstance()->RemoveWindowListenerImpl(aWindow);
   154 }
   156 nsresult
   157 nsSystemTimeChangeObserver::RemoveWindowListenerImpl(nsPIDOMWindow* aWindow)
   158 {
   159   if (!aWindow) {
   160     return NS_OK;
   161   }
   163   if (aWindow->IsOuterWindow()) {
   164     aWindow = aWindow->GetCurrentInnerWindow();
   165     if (!aWindow) {
   166       return NS_ERROR_FAILURE;
   167     }
   168   }
   170   nsWeakPtr windowWeakRef = do_GetWeakReference(aWindow);
   171   mWindowListeners.RemoveElement(windowWeakRef);
   173   if (mWindowListeners.IsEmpty()) {
   174     UnregisterSystemClockChangeObserver(sObserver);
   175     UnregisterSystemTimezoneChangeObserver(sObserver);
   176   }
   178   return NS_OK;
   179 }

mercurial