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 ceca5d67cf
commit 8bdab429d2
5 changed files with 46 additions and 52 deletions

View File

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

View File

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

View File

@ -267,6 +267,29 @@ void nsAppShell::StartDBusListening() {
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() {
if (mLogin1Proxy) {
g_signal_handlers_disconnect_matched(mLogin1Proxy, G_SIGNAL_MATCH_DATA, 0,
@ -293,22 +316,11 @@ void nsAppShell::StopDBusListening() {
nsresult nsAppShell::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
if (XRE_IsParentProcess()) {
StartDBusListening();
#endif
}
#endif
if (!sPollFunc) {
sPollFunc = g_main_context_get_poll_func(nullptr);
@ -408,6 +420,19 @@ failed:
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() {
unsigned char buf[] = {NOTIFY_TOKEN};
Unused << write(mPipeFDs[1], buf, 1);

View File

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

View File

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