Bug 1756635 - Make GTK wake lock lifetime more similar to other desktop platforms. r=stransky

This matches what macOS and Windows do, and should clean up the wake
lock stuff early enough to not hit this issue.

Differential Revision: https://phabricator.services.mozilla.com/D194376
This commit is contained in:
Emilio Cobos Álvarez
2023-11-22 14:28:35 +00:00
parent e33f24436a
commit e39219f2c3
5 changed files with 46 additions and 52 deletions

View File

@@ -24,7 +24,6 @@
#if defined(MOZ_WAYLAND) #if defined(MOZ_WAYLAND)
# include "mozilla/widget/nsWaylandDisplay.h" # include "mozilla/widget/nsWaylandDisplay.h"
# include "nsWindow.h" # include "nsWindow.h"
# include "mozilla/dom/power/PowerManagerService.h"
#endif #endif
#ifdef MOZ_ENABLE_DBUS #ifdef MOZ_ENABLE_DBUS
@@ -48,8 +47,6 @@ using namespace mozilla::widget;
NS_IMPL_ISUPPORTS(WakeLockListener, nsIDOMMozWakeLockListener) NS_IMPL_ISUPPORTS(WakeLockListener, nsIDOMMozWakeLockListener)
StaticRefPtr<WakeLockListener> WakeLockListener::sSingleton;
#define WAKE_LOCK_LOG(str, ...) \ #define WAKE_LOCK_LOG(str, ...) \
MOZ_LOG(gLinuxWakeLockLog, mozilla::LogLevel::Debug, \ MOZ_LOG(gLinuxWakeLockLog, mozilla::LogLevel::Debug, \
("[%p] " str, this, ##__VA_ARGS__)) ("[%p] " str, this, ##__VA_ARGS__))
@@ -716,21 +713,6 @@ bool WakeLockTopic::SwitchToNextWakeLockType() {
return false; return false;
} }
/* static */
WakeLockListener* WakeLockListener::GetSingleton(bool aCreate) {
if (!sSingleton && aCreate) {
sSingleton = new WakeLockListener();
}
return sSingleton;
}
/* static */
void WakeLockListener::Shutdown() {
MOZ_LOG(gLinuxWakeLockLog, mozilla::LogLevel::Debug,
("WakeLockListener::Shutdown()"));
sSingleton = nullptr;
}
nsresult WakeLockListener::Callback(const nsAString& topic, nsresult WakeLockListener::Callback(const nsAString& topic,
const nsAString& state) { const nsAString& state) {
if (!topic.Equals(u"screen"_ns) && !topic.Equals(u"video-playing"_ns) && if (!topic.Equals(u"screen"_ns) && !topic.Equals(u"video-playing"_ns) &&

View File

@@ -8,18 +8,11 @@
#ifndef __WakeLockListener_h__ #ifndef __WakeLockListener_h__
#define __WakeLockListener_h__ #define __WakeLockListener_h__
#include <unistd.h>
#include "mozilla/StaticPtr.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsRefPtrHashtable.h" #include "nsRefPtrHashtable.h"
#include "nsIDOMWakeLockListener.h" #include "nsIDOMWakeLockListener.h"
#ifdef MOZ_ENABLE_DBUS
# include "mozilla/DBusHelpers.h"
#endif
class WakeLockTopic; class WakeLockTopic;
/** /**
@@ -30,17 +23,11 @@ class WakeLockListener final : public nsIDOMMozWakeLockListener {
public: public:
NS_DECL_ISUPPORTS; NS_DECL_ISUPPORTS;
static WakeLockListener* GetSingleton(bool aCreate = true); nsresult Callback(const nsAString& topic, const nsAString& state) override;
static void Shutdown();
virtual nsresult Callback(const nsAString& topic,
const nsAString& state) override;
private: private:
~WakeLockListener() = default; ~WakeLockListener() = default;
static mozilla::StaticRefPtr<WakeLockListener> sSingleton;
// Map of topic names to |WakeLockTopic|s. // Map of topic names to |WakeLockTopic|s.
// We assume a small, finite-sized set of topics. // We assume a small, finite-sized set of topics.
nsRefPtrHashtable<nsStringHashKey, WakeLockTopic> mTopics; nsRefPtrHashtable<nsStringHashKey, WakeLockTopic> mTopics;

View File

@@ -267,6 +267,29 @@ void nsAppShell::StartDBusListening() {
reinterpret_cast<GAsyncReadyCallback>(DBusConnectClientResponse), this); reinterpret_cast<GAsyncReadyCallback>(DBusConnectClientResponse), this);
} }
mozilla::StaticRefPtr<WakeLockListener> sWakeLockListener;
static void AddScreenWakeLockListener() {
nsCOMPtr<nsIPowerManagerService> powerManager =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
if (powerManager) {
sWakeLockListener = new WakeLockListener();
powerManager->AddWakeLockListener(sWakeLockListener);
} else {
NS_WARNING(
"Failed to retrieve PowerManagerService, wakelocks will be broken!");
}
}
static void RemoveScreenWakeLockListener() {
nsCOMPtr<nsIPowerManagerService> powerManager =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
if (powerManager) {
powerManager->RemoveWakeLockListener(sWakeLockListener);
sWakeLockListener = nullptr;
}
}
void nsAppShell::StopDBusListening() { void nsAppShell::StopDBusListening() {
if (mLogin1Proxy) { if (mLogin1Proxy) {
g_signal_handlers_disconnect_matched(mLogin1Proxy, G_SIGNAL_MATCH_DATA, 0, g_signal_handlers_disconnect_matched(mLogin1Proxy, G_SIGNAL_MATCH_DATA, 0,
@@ -293,22 +316,11 @@ void nsAppShell::StopDBusListening() {
nsresult nsAppShell::Init() { nsresult nsAppShell::Init() {
mozilla::hal::Init(); mozilla::hal::Init();
if (XRE_IsParentProcess()) {
nsCOMPtr<nsIPowerManagerService> powerManagerService =
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
if (powerManagerService) {
powerManagerService->AddWakeLockListener(
WakeLockListener::GetSingleton());
} else {
NS_WARNING(
"Failed to retrieve PowerManagerService, wakelocks will be broken!");
}
#ifdef MOZ_ENABLE_DBUS #ifdef MOZ_ENABLE_DBUS
if (XRE_IsParentProcess()) {
StartDBusListening(); StartDBusListening();
#endif
} }
#endif
if (!sPollFunc) { if (!sPollFunc) {
sPollFunc = g_main_context_get_poll_func(nullptr); sPollFunc = g_main_context_get_poll_func(nullptr);
@@ -408,6 +420,19 @@ failed:
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
NS_IMETHODIMP nsAppShell::Run() {
if (XRE_IsParentProcess()) {
AddScreenWakeLockListener();
}
nsresult rv = nsBaseAppShell::Run();
if (XRE_IsParentProcess()) {
RemoveScreenWakeLockListener();
}
return rv;
}
void nsAppShell::ScheduleNativeEventCallback() { void nsAppShell::ScheduleNativeEventCallback() {
unsigned char buf[] = {NOTIFY_TOKEN}; unsigned char buf[] = {NOTIFY_TOKEN};
Unused << write(mPipeFDs[1], buf, 1); Unused << write(mPipeFDs[1], buf, 1);

View File

@@ -15,16 +15,17 @@
#endif #endif
#include <glib.h> #include <glib.h>
#include "nsBaseAppShell.h" #include "nsBaseAppShell.h"
#include "nsCOMPtr.h"
class nsAppShell : public nsBaseAppShell { class nsAppShell : public nsBaseAppShell {
public: public:
nsAppShell() : mTag(0) { mPipeFDs[0] = mPipeFDs[1] = 0; } nsAppShell() = default;
// nsBaseAppShell overrides: // nsBaseAppShell overrides:
nsresult Init(); nsresult Init();
virtual void ScheduleNativeEventCallback() override; NS_IMETHOD Run() override;
virtual bool ProcessNextNativeEvent(bool mayWait) override;
void ScheduleNativeEventCallback() override;
bool ProcessNextNativeEvent(bool mayWait) override;
#ifdef MOZ_ENABLE_DBUS #ifdef MOZ_ENABLE_DBUS
void StartDBusListening(); void StartDBusListening();
@@ -48,8 +49,8 @@ class nsAppShell : public nsBaseAppShell {
static gboolean EventProcessorCallback(GIOChannel* source, static gboolean EventProcessorCallback(GIOChannel* source,
GIOCondition condition, gpointer data); GIOCondition condition, gpointer data);
int mPipeFDs[2]; int mPipeFDs[2] = {0, 0};
unsigned mTag; unsigned mTag = 0;
#ifdef MOZ_ENABLE_DBUS #ifdef MOZ_ENABLE_DBUS
RefPtr<GDBusProxy> mLogin1Proxy; RefPtr<GDBusProxy> mLogin1Proxy;

View File

@@ -64,5 +64,4 @@ void nsWidgetGtk2ModuleDtor() {
KeymapWrapper::Shutdown(); KeymapWrapper::Shutdown();
nsGTKToolkit::Shutdown(); nsGTKToolkit::Shutdown();
nsAppShellShutdown(); nsAppShellShutdown();
WakeLockListener::Shutdown();
} }