Bug 790527 - When rebooting/powering off, go through normal gecko shutdown. r=bsmedberg,sr=cjones
authorGene Lian <clian@mozilla.com>
Wed, 26 Sep 2012 17:12:33 +0800
changeset 115370 d31d2479d685f203b45738dd92983b7eebd6f5f6
parent 115367 2c694d8bf7a59441faba5d6266862299fa354b03
child 115371 eda2891c545b3ecbe1bef496d63876c4bcacddc2
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, cjones
bugs790527
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 790527 - When rebooting/powering off, go through normal gecko shutdown. r=bsmedberg,sr=cjones
dom/power/PowerManagerService.cpp
dom/power/PowerManagerService.h
hal/Hal.cpp
hal/Hal.h
hal/sandbox/PHal.ipdl
hal/sandbox/SandboxHal.cpp
--- a/dom/power/PowerManagerService.cpp
+++ b/dom/power/PowerManagerService.cpp
@@ -1,18 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "mozilla/Hal.h"
 #include "mozilla/HalWakeLock.h"
 #include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Services.h"
 #include "nsIDOMWakeLockListener.h"
 #include "nsIDOMWindow.h"
+#include "nsIObserverService.h"
 #include "PowerManagerService.h"
 #include "WakeLock.h"
 
 namespace mozilla {
 namespace dom {
 namespace power {
 
 NS_IMPL_ISUPPORTS1(PowerManagerService, nsIPowerManagerService)
@@ -75,27 +77,47 @@ PowerManagerService::Notify(const hal::W
    */
   nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
 
   for (uint32_t i = 0; i < listeners.Length(); ++i) {
     listeners[i]->Callback(aWakeLockInfo.topic(), state);
   }
 }
 
+void
+PowerManagerService::SyncProfile()
+{
+  // FIXME/bug 793970: We need to start a watchdog thread to force gecko
+  // to really power off or reboot if the profile synchronizing hangs.
+  nsCOMPtr<nsIObserverService> obsServ = services::GetObserverService();
+  if (obsServ) {
+    NS_NAMED_LITERAL_STRING(context, "shutdown-persist");
+    obsServ->NotifyObservers(nullptr, "profile-change-net-teardown", context.get());
+    obsServ->NotifyObservers(nullptr, "profile-change-teardown", context.get());
+    obsServ->NotifyObservers(nullptr, "profile-before-change", context.get());
+  }
+}
+
 NS_IMETHODIMP
 PowerManagerService::Reboot()
 {
+  // To synchronize any unsaved user data before rebooting.
+  SyncProfile();
   hal::Reboot();
+  MOZ_NOT_REACHED();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PowerManagerService::PowerOff()
 {
+  // To synchronize any unsaved user data before powering off.
+  SyncProfile();
   hal::PowerOff();
+  MOZ_NOT_REACHED();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
 {
   if (mWakeLockListeners.Contains(aListener))
     return NS_OK;
--- a/dom/power/PowerManagerService.h
+++ b/dom/power/PowerManagerService.h
@@ -35,16 +35,18 @@ public:
 
 private:
 
   ~PowerManagerService();
 
   void ComputeWakeLockState(const hal::WakeLockInformation& aWakeLockInfo,
                             nsAString &aState);
 
+  void SyncProfile();
+
   static StaticRefPtr<PowerManagerService> sSingleton;
 
   nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mWakeLockListeners;
 };
 
 } // namespace power
 } // namespace dom
 } // namespace mozilla
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -61,16 +61,22 @@ AssertMainThread()
 }
 
 bool
 InSandbox()
 {
   return GeckoProcessType_Content == XRE_GetProcessType();
 }
 
+void
+AssertMainProcess()
+{
+  MOZ_ASSERT(GeckoProcessType_Default == XRE_GetProcessType());
+}
+
 bool
 WindowIsActive(nsIDOMWindow *window)
 {
   NS_ENSURE_TRUE(window, false);
 
   nsCOMPtr<nsIDOMDocument> doc;
   window->GetDocument(getter_AddRefs(doc));
   NS_ENSURE_TRUE(doc, false);
@@ -556,22 +562,24 @@ void
 NotifyNetworkChange(const NetworkInformation& aInfo)
 {
   sNetworkObservers.CacheInformation(aInfo);
   sNetworkObservers.BroadcastCachedInformation();
 }
 
 void Reboot()
 {
+  AssertMainProcess();
   AssertMainThread();
   PROXY_IF_SANDBOXED(Reboot());
 }
 
 void PowerOff()
 {
+  AssertMainProcess();
   AssertMainThread();
   PROXY_IF_SANDBOXED(PowerOff());
 }
 
 void
 RegisterWakeLockObserver(WakeLockObserver* aObserver)
 {
   AssertMainThread();
@@ -769,22 +777,17 @@ SetAlarm(int32_t aSeconds, int32_t aNano
   // It's pointless to program an alarm nothing is going to observe ...
   MOZ_ASSERT(sAlarmObserver);
   RETURN_PROXY_IF_SANDBOXED(SetAlarm(aSeconds, aNanoseconds));
 }
 
 void
 SetProcessPriority(int aPid, ProcessPriority aPriority)
 {
-  if (InSandbox()) {
-    hal_sandbox::SetProcessPriority(aPid, aPriority);
-  }
-  else {
-    hal_impl::SetProcessPriority(aPid, aPriority);
-  }
+  PROXY_IF_SANDBOXED(SetProcessPriority(aPid, aPriority));
 }
 
 static StaticAutoPtr<ObserverList<FMRadioOperationInformation> > sFMRadioObservers;
 
 static void
 InitializeFMRadioObserver()
 {
   if (!sFMRadioObservers) {
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -272,21 +272,25 @@ void UnregisterSystemTimeChangeObserver(
 /**
  * Notify of a change in the system cloeck or time zone.
  * @param aReason
  */
 void NotifySystemTimeChange(const hal::SystemTimeChange& aReason);
 
 /**
  * Reboot the device.
+ * 
+ * This API is currently only allowed to be used from the main process.
  */
 void Reboot();
 
 /**
  * Power off the device.
+ * 
+ * This API is currently only allowed to be used from the main process.
  */
 void PowerOff();
 
 /**
  * Enable wake lock notifications from the backend.
  *
  * This method is only used by WakeLockObserversManager.
  */
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -138,19 +138,16 @@ parent:
     EnableSystemTimeChangeNotifications();
     DisableSystemTimeChangeNotifications();
 
     sync SetLight(LightType light, LightConfiguration aConfig)
       returns (bool status);
     sync GetLight(LightType light)
       returns (LightConfiguration aConfig, bool status);
 
-    Reboot();
-    PowerOff();
-
     ModifyWakeLock(nsString aTopic, WakeLockControl aLockAdjust, WakeLockControl aHiddenAdjust);
     EnableWakeLockNotifications();
     DisableWakeLockNotifications();
     sync GetWakeLockInfo(nsString aTopic)
       returns (WakeLockInformation aWakeLockInfo);
 
     EnableScreenConfigurationNotifications();
     DisableScreenConfigurationNotifications();
--- a/hal/sandbox/SandboxHal.cpp
+++ b/hal/sandbox/SandboxHal.cpp
@@ -213,23 +213,23 @@ void
 DisableSystemTimeChangeNotifications()
 {
   Hal()->SendDisableSystemTimeChangeNotifications();
 }
 
 void
 Reboot()
 {
-  Hal()->SendReboot();
+  NS_RUNTIMEABORT("Reboot() can't be called from sandboxed contexts.");
 }
 
 void
 PowerOff()
 {
-  Hal()->SendPowerOff();
+  NS_RUNTIMEABORT("PowerOff() can't be called from sandboxed contexts.");
 }
 
 void
 EnableSensorNotifications(SensorType aSensor) {
   Hal()->SendEnableSensorNotifications(aSensor);
 }
 
 void
@@ -631,36 +631,16 @@ public:
   virtual bool
   RecvDisableSystemTimeChangeNotifications() MOZ_OVERRIDE
   {
     hal::UnregisterSystemTimeChangeObserver(this);
     return true;
   }
 
   virtual bool
-  RecvReboot() MOZ_OVERRIDE
-  {
-    if (!AssertAppProcessPermission(this, "power")) {
-      return false;
-    }
-    hal::Reboot();
-    return true;
-  }
-
-  virtual bool
-  RecvPowerOff() MOZ_OVERRIDE
-  {
-    if (!AssertAppProcessPermission(this, "power")) {
-      return false;
-    }
-    hal::PowerOff();
-    return true;
-  }
-
-  virtual bool
   RecvEnableSensorNotifications(const SensorType &aSensor) MOZ_OVERRIDE {
     // We currently allow any content to register device-sensor
     // listeners.
     hal::RegisterSensorObserver(aSensor, this);
     return true;
   }
    
   virtual bool