dom/power/PowerManagerService.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "mozilla/dom/ContentParent.h"
     7 #include "mozilla/Hal.h"
     8 #include "mozilla/HalWakeLock.h"
     9 #include "mozilla/ClearOnShutdown.h"
    10 #include "mozilla/Preferences.h"
    11 #include "mozilla/Services.h"
    12 #include "nsIDOMWakeLockListener.h"
    13 #include "nsIDOMWindow.h"
    14 #include "nsIObserverService.h"
    15 #include "PowerManagerService.h"
    16 #include "WakeLock.h"
    18 // For _exit().
    19 #ifdef XP_WIN
    20 #include <process.h>
    21 #else
    22 #include <unistd.h>
    23 #endif
    25 #ifdef ANDROID
    26 #include <android/log.h>
    27 extern "C" char* PrintJSStack();
    28 static void LogFunctionAndJSStack(const char* funcname) {
    29   char *jsstack = PrintJSStack();
    30   __android_log_print(ANDROID_LOG_INFO, "PowerManagerService", \
    31                       "Call to %s. The JS stack is:\n%s\n",
    32                       funcname,
    33                       jsstack ? jsstack : "<no JS stack>");
    34 }
    35 // bug 839452
    36 #define LOG_FUNCTION_AND_JS_STACK() \
    37   LogFunctionAndJSStack(__PRETTY_FUNCTION__);
    38 #else
    39 #define LOG_FUNCTION_AND_JS_STACK()
    40 #endif
    42 namespace mozilla {
    43 namespace dom {
    44 namespace power {
    46 using namespace hal;
    48 NS_IMPL_ISUPPORTS(PowerManagerService, nsIPowerManagerService)
    50 /* static */ StaticRefPtr<PowerManagerService> PowerManagerService::sSingleton;
    52 /* static */ already_AddRefed<PowerManagerService>
    53 PowerManagerService::GetInstance()
    54 {
    55   if (!sSingleton) {
    56     sSingleton = new PowerManagerService();
    57     sSingleton->Init();
    58     ClearOnShutdown(&sSingleton);
    59   }
    61   nsRefPtr<PowerManagerService> service = sSingleton.get();
    62   return service.forget();
    63 }
    65 void
    66 PowerManagerService::Init()
    67 {
    68   RegisterWakeLockObserver(this);
    70   // NB: default to *enabling* the watchdog even when the pref is
    71   // absent, in case the profile might be damaged and we need to
    72   // restart to repair it.
    73   mWatchdogTimeoutSecs =
    74     Preferences::GetInt("shutdown.watchdog.timeoutSecs", 5);
    75 }
    77 PowerManagerService::~PowerManagerService()
    78 {
    79   UnregisterWakeLockObserver(this);
    80 }
    82 void
    83 PowerManagerService::ComputeWakeLockState(const WakeLockInformation& aWakeLockInfo,
    84                                           nsAString &aState)
    85 {
    86   WakeLockState state = hal::ComputeWakeLockState(aWakeLockInfo.numLocks(),
    87                                                   aWakeLockInfo.numHidden());
    88   switch (state) {
    89   case WAKE_LOCK_STATE_UNLOCKED:
    90     aState.AssignLiteral("unlocked");
    91     break;
    92   case WAKE_LOCK_STATE_HIDDEN:
    93     aState.AssignLiteral("locked-background");
    94     break;
    95   case WAKE_LOCK_STATE_VISIBLE:
    96     aState.AssignLiteral("locked-foreground");
    97     break;
    98   }
    99 }
   101 void
   102 PowerManagerService::Notify(const WakeLockInformation& aWakeLockInfo)
   103 {
   104   nsAutoString state;
   105   ComputeWakeLockState(aWakeLockInfo, state);
   107   /**
   108    * Copy the listeners list before we walk through the callbacks
   109    * because the callbacks may install new listeners. We expect no
   110    * more than one listener per window, so it shouldn't be too long.
   111    */
   112   nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
   114   for (uint32_t i = 0; i < listeners.Length(); ++i) {
   115     listeners[i]->Callback(aWakeLockInfo.topic(), state);
   116   }
   117 }
   119 void
   120 PowerManagerService::SyncProfile()
   121 {
   122   nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
   123   if (obsServ) {
   124     NS_NAMED_LITERAL_STRING(context, "shutdown-persist");
   125     obsServ->NotifyObservers(nullptr, "profile-change-net-teardown", context.get());
   126     obsServ->NotifyObservers(nullptr, "profile-change-teardown", context.get());
   127     obsServ->NotifyObservers(nullptr, "profile-before-change", context.get());
   128     obsServ->NotifyObservers(nullptr, "profile-before-change2", context.get());
   129   }
   130 }
   132 NS_IMETHODIMP
   133 PowerManagerService::Reboot()
   134 {
   135   LOG_FUNCTION_AND_JS_STACK() // bug 839452
   137   StartForceQuitWatchdog(eHalShutdownMode_Reboot, mWatchdogTimeoutSecs);
   138   // To synchronize any unsaved user data before rebooting.
   139   SyncProfile();
   140   hal::Reboot();
   141   MOZ_CRASH("hal::Reboot() shouldn't return");
   142 }
   144 NS_IMETHODIMP
   145 PowerManagerService::PowerOff()
   146 {
   147   LOG_FUNCTION_AND_JS_STACK() // bug 839452
   149   StartForceQuitWatchdog(eHalShutdownMode_PowerOff, mWatchdogTimeoutSecs);
   150   // To synchronize any unsaved user data before powering off.
   151   SyncProfile();
   152   hal::PowerOff();
   153   MOZ_CRASH("hal::PowerOff() shouldn't return");
   154 }
   156 NS_IMETHODIMP
   157 PowerManagerService::Restart()
   158 {
   159   LOG_FUNCTION_AND_JS_STACK() // bug 839452
   161   // FIXME/bug 796826 this implementation is currently gonk-specific,
   162   // because it relies on the Gonk to initialize the Gecko processes to
   163   // restart B2G. It's better to do it here to have a real "restart".
   164   StartForceQuitWatchdog(eHalShutdownMode_Restart, mWatchdogTimeoutSecs);
   165   // Ensure all content processes are dead before we continue
   166   // restarting.  This code is used to restart to apply updates, and
   167   // if we don't join all the subprocesses, race conditions can cause
   168   // them to see an inconsistent view of the application directory.
   169   ContentParent::JoinAllSubprocesses();
   171   // To synchronize any unsaved user data before restarting.
   172   SyncProfile();
   173 #ifdef XP_UNIX
   174   sync();
   175 #endif
   176   _exit(0);
   177   MOZ_CRASH("_exit() shouldn't return");
   178 }
   180 NS_IMETHODIMP
   181 PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
   182 {
   183   if (mWakeLockListeners.Contains(aListener))
   184     return NS_OK;
   186   mWakeLockListeners.AppendElement(aListener);
   187   return NS_OK;
   188 }
   190 NS_IMETHODIMP
   191 PowerManagerService::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
   192 {
   193   mWakeLockListeners.RemoveElement(aListener);
   194   return NS_OK;
   195 }
   197 NS_IMETHODIMP
   198 PowerManagerService::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
   199 {
   200   WakeLockInformation info;
   201   GetWakeLockInfo(aTopic, &info);
   203   ComputeWakeLockState(info, aState);
   205   return NS_OK;
   206 }
   208 already_AddRefed<WakeLock>
   209 PowerManagerService::NewWakeLock(const nsAString& aTopic,
   210                                  nsIDOMWindow* aWindow,
   211                                  mozilla::ErrorResult& aRv)
   212 {
   213   nsRefPtr<WakeLock> wakelock = new WakeLock();
   214   aRv = wakelock->Init(aTopic, aWindow);
   215   if (aRv.Failed()) {
   216     return nullptr;
   217   }
   219   return wakelock.forget();
   220 }
   222 NS_IMETHODIMP
   223 PowerManagerService::NewWakeLock(const nsAString &aTopic,
   224                                  nsIDOMWindow *aWindow,
   225                                  nsISupports **aWakeLock)
   226 {
   227   mozilla::ErrorResult rv;
   228   nsRefPtr<WakeLock> wakelock = NewWakeLock(aTopic, aWindow, rv);
   229   if (rv.Failed()) {
   230     return rv.ErrorCode();
   231   }
   233   nsCOMPtr<nsIDOMEventListener> eventListener = wakelock.get();
   234   eventListener.forget(aWakeLock);
   235   return NS_OK;
   236 }
   238 already_AddRefed<WakeLock>
   239 PowerManagerService::NewWakeLockOnBehalfOfProcess(const nsAString& aTopic,
   240                                                   ContentParent* aContentParent)
   241 {
   242   nsRefPtr<WakeLock> wakelock = new WakeLock();
   243   nsresult rv = wakelock->Init(aTopic, aContentParent);
   244   NS_ENSURE_SUCCESS(rv, nullptr);
   245   return wakelock.forget();
   246 }
   248 } // power
   249 } // dom
   250 } // mozilla

mercurial