Bug 1861709 replace AudioCallbackDriver::ThreadRunning() assertions that mean to...
[gecko.git] / widget / gtk / WakeLockListener.cpp
blobaed6e318b615ae23713d1e81213a07d315b54a06
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:expandtab:shiftwidth=2:tabstop=2:
3 */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "WakeLockListener.h"
9 #include "WidgetUtilsGtk.h"
10 #include "mozilla/ScopeExit.h"
12 #ifdef MOZ_ENABLE_DBUS
13 # include <gio/gio.h>
14 # include "AsyncDBus.h"
15 #endif
17 #if defined(MOZ_X11)
18 # include "prlink.h"
19 # include <gdk/gdk.h>
20 # include <gdk/gdkx.h>
21 # include "X11UndefineNone.h"
22 #endif
24 #if defined(MOZ_WAYLAND)
25 # include "mozilla/widget/nsWaylandDisplay.h"
26 # include "nsWindow.h"
27 # include "mozilla/dom/power/PowerManagerService.h"
28 #endif
30 #ifdef MOZ_ENABLE_DBUS
31 # define FREEDESKTOP_SCREENSAVER_TARGET "org.freedesktop.ScreenSaver"
32 # define FREEDESKTOP_SCREENSAVER_OBJECT "/ScreenSaver"
33 # define FREEDESKTOP_SCREENSAVER_INTERFACE "org.freedesktop.ScreenSaver"
35 # define FREEDESKTOP_POWER_TARGET "org.freedesktop.PowerManagement"
36 # define FREEDESKTOP_POWER_OBJECT "/org/freedesktop/PowerManagement/Inhibit"
37 # define FREEDESKTOP_POWER_INTERFACE "org.freedesktop.PowerManagement.Inhibit"
39 # define SESSION_MANAGER_TARGET "org.gnome.SessionManager"
40 # define SESSION_MANAGER_OBJECT "/org/gnome/SessionManager"
41 # define SESSION_MANAGER_INTERFACE "org.gnome.SessionManager"
43 # define DBUS_TIMEOUT (-1)
44 #endif
46 using namespace mozilla;
47 using namespace mozilla::widget;
49 NS_IMPL_ISUPPORTS(WakeLockListener, nsIDOMMozWakeLockListener)
51 StaticRefPtr<WakeLockListener> WakeLockListener::sSingleton;
53 #define WAKE_LOCK_LOG(...) \
54 MOZ_LOG(gLinuxWakeLockLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
55 static mozilla::LazyLogModule gLinuxWakeLockLog("LinuxWakeLock");
57 enum WakeLockType {
58 Initial = 0,
59 #if defined(MOZ_ENABLE_DBUS)
60 FreeDesktopScreensaver = 1,
61 FreeDesktopPower = 2,
62 GNOME = 3,
63 #endif
64 #if defined(MOZ_X11)
65 XScreenSaver = 4,
66 #endif
67 #if defined(MOZ_WAYLAND)
68 WaylandIdleInhibit = 5,
69 #endif
70 Unsupported = 6,
73 #ifdef MOZ_LOGGING
74 const char* WakeLockTypeNames[7] = {
75 "Initial", "FreeDesktopScreensaver", "FreeDesktopPower", "GNOME",
76 "XScreenSaver", "WaylandIdleInhibit", "Unsupported",
78 #endif
80 class WakeLockTopic {
81 public:
82 NS_INLINE_DECL_REFCOUNTING(WakeLockTopic)
84 explicit WakeLockTopic(const nsAString& aTopic) {
85 CopyUTF16toUTF8(aTopic, mTopic);
86 if (sWakeLockType == Initial) {
87 SwitchToNextWakeLockType();
91 nsresult InhibitScreensaver(void);
92 nsresult UninhibitScreensaver(void);
94 private:
95 bool SendInhibit();
96 bool SendUninhibit();
98 #if defined(MOZ_X11)
99 static bool CheckXScreenSaverSupport();
100 bool InhibitXScreenSaver(bool inhibit);
101 #endif
103 #if defined(MOZ_WAYLAND)
104 zwp_idle_inhibitor_v1* mWaylandInhibitor = nullptr;
105 static bool CheckWaylandIdleInhibitSupport();
106 bool InhibitWaylandIdle();
107 bool UninhibitWaylandIdle();
108 #endif
110 bool IsWakeLockTypeAvailable(int aWakeLockType);
111 bool SwitchToNextWakeLockType();
113 #ifdef MOZ_ENABLE_DBUS
114 void DBusPrepareCancellable();
115 void DBusInhibitScreensaver(const char* aName, const char* aPath,
116 const char* aCall, const char* aMethod,
117 RefPtr<GVariant> aArgs);
118 void DBusUninhibitScreensaver(const char* aName, const char* aPath,
119 const char* aCall, const char* aMethod);
121 void InhibitFreeDesktopScreensaver();
122 void InhibitFreeDesktopPower();
123 void InhibitGNOME();
125 void UninhibitFreeDesktopScreensaver();
126 void UninhibitFreeDesktopPower();
127 void UninhibitGNOME();
129 void DBusInhibitSucceeded(uint32_t aInhibitRequestID);
130 void DBusInhibitFailed(bool aFatal);
131 void DBusUninhibitSucceeded();
132 void DBusUninhibitFailed();
133 #endif
135 ~WakeLockTopic() {
136 WAKE_LOCK_LOG("WakeLockTopic::~WakeLockTopic() state %d", mInhibited);
137 if (mInhibited) {
138 UninhibitScreensaver();
142 // Why is screensaver inhibited
143 nsCString mTopic;
145 // Our desired state
146 bool mShouldInhibit = false;
148 // Our actual sate
149 bool mInhibited = false;
151 #ifdef MOZ_ENABLE_DBUS
152 // We're waiting for DBus reply (inhibit/uninhibit call).
153 bool mWaitingForDBusReply = false;
155 // mInhibitRequestID is received from success screen saver inhibit call
156 // and it's needed for screen saver enablement.
157 uint32_t mInhibitRequestID = 0;
158 #endif
160 static int sWakeLockType;
163 int WakeLockTopic::sWakeLockType = Initial;
165 #ifdef MOZ_ENABLE_DBUS
166 void WakeLockTopic::DBusInhibitSucceeded(uint32_t aInhibitRequestID) {
167 mWaitingForDBusReply = false;
168 mInhibitRequestID = aInhibitRequestID;
169 mInhibited = true;
171 WAKE_LOCK_LOG("WakeLockTopic::DBusInhibitSucceeded(), mInhibitRequestID %u",
172 mInhibitRequestID);
174 // Uninhibit was requested before inhibit request was finished.
175 // So ask for it now.
176 if (!mShouldInhibit) {
177 UninhibitScreensaver();
181 void WakeLockTopic::DBusInhibitFailed(bool aFatal) {
182 WAKE_LOCK_LOG("WakeLockTopic::DBusInhibitFailed(%d)", aFatal);
184 mWaitingForDBusReply = false;
185 mInhibitRequestID = 0;
187 // Non-recoverable DBus error. Switch to another wake lock type.
188 if (aFatal && SwitchToNextWakeLockType()) {
189 SendInhibit();
193 void WakeLockTopic::DBusUninhibitSucceeded() {
194 WAKE_LOCK_LOG("WakeLockTopic::DBusInhibitSucceeded()");
196 mWaitingForDBusReply = false;
197 mInhibitRequestID = 0;
198 mInhibited = false;
200 // Inhibit was requested before uninhibit request was finished.
201 // So ask for it now.
202 if (mShouldInhibit) {
203 InhibitScreensaver();
207 void WakeLockTopic::DBusUninhibitFailed() {
208 WAKE_LOCK_LOG("WakeLockTopic::DBusUninhibitFailed()");
209 mWaitingForDBusReply = false;
212 void WakeLockTopic::DBusInhibitScreensaver(const char* aName, const char* aPath,
213 const char* aCall,
214 const char* aMethod,
215 RefPtr<GVariant> aArgs) {
216 WAKE_LOCK_LOG("WakeLockTopic::DBusInhibitScreensaver() waiting %d",
217 mWaitingForDBusReply);
218 if (mWaitingForDBusReply) {
219 // g_cancellable_cancel(mCancellable);
221 mWaitingForDBusReply = true;
223 widget::CreateDBusProxyForBus(
224 G_BUS_TYPE_SESSION,
225 GDBusProxyFlags(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
226 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES),
227 /* aInterfaceInfo = */ nullptr, aName, aPath, aCall)
228 ->Then(
229 GetCurrentSerialEventTarget(), __func__,
230 [self = RefPtr{this}, args = RefPtr{aArgs},
231 aMethod](RefPtr<GDBusProxy>&& aProxy) {
232 WAKE_LOCK_LOG(
233 "WakeLockTopic::DBusInhibitScreensaver() proxy created");
234 DBusProxyCall(aProxy.get(), aMethod, args.get(),
235 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT)
236 ->Then(
237 GetCurrentSerialEventTarget(), __func__,
238 [s = RefPtr{self}](RefPtr<GVariant>&& aResult) {
239 if (!g_variant_is_of_type(aResult.get(),
240 G_VARIANT_TYPE_TUPLE) ||
241 g_variant_n_children(aResult.get()) != 1) {
242 WAKE_LOCK_LOG(
243 "WakeLockTopic::DBusInhibitScreensaver() wrong "
244 "reply type %s\n",
245 g_variant_get_type_string(aResult.get()));
246 s->DBusInhibitFailed(/* aFatal */ true);
247 return;
249 RefPtr<GVariant> variant = dont_AddRef(
250 g_variant_get_child_value(aResult.get(), 0));
251 if (!g_variant_is_of_type(variant,
252 G_VARIANT_TYPE_UINT32)) {
253 WAKE_LOCK_LOG(
254 "WakeLockTopic::DBusInhibitScreensaver() wrong "
255 "reply type %s\n",
256 g_variant_get_type_string(aResult.get()));
257 s->DBusInhibitFailed(/* aFatal */ true);
258 return;
260 s->DBusInhibitSucceeded(g_variant_get_uint32(variant));
262 [s = RefPtr{self}, aMethod](GUniquePtr<GError>&& aError) {
263 // Failed to send inhibit request over proxy.
264 // Switch to another wake lock type.
265 WAKE_LOCK_LOG(
266 "WakeLockTopic::DBusInhibitFailed() %s call failed : "
267 "%s\n",
268 aMethod, aError->message);
269 s->DBusInhibitFailed(/* aFatal */ true);
272 [self = RefPtr{this}](GUniquePtr<GError>&& aError) {
273 // We failed to create DBus proxy. Switch to another
274 // wake lock type.
275 WAKE_LOCK_LOG(
276 "WakeLockTopic::DBusInhibitScreensaver() Proxy creation "
277 "failed: %s\n",
278 aError->message);
279 self->DBusInhibitFailed(/* aFatal */ true);
283 void WakeLockTopic::DBusUninhibitScreensaver(const char* aName,
284 const char* aPath,
285 const char* aCall,
286 const char* aMethod) {
287 WAKE_LOCK_LOG(
288 "WakeLockTopic::DBusUninhibitScreensaver() waiting %d request id %u",
289 mWaitingForDBusReply, mInhibitRequestID);
291 if (mWaitingForDBusReply) {
292 return;
294 if (!mInhibitRequestID) {
295 // missing uninhibit token, just quit.
296 return;
298 mWaitingForDBusReply = true;
300 RefPtr<GVariant> variant =
301 dont_AddRef(g_variant_ref_sink(g_variant_new("(u)", mInhibitRequestID)));
302 widget::CreateDBusProxyForBus(
303 G_BUS_TYPE_SESSION,
304 GDBusProxyFlags(G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
305 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES),
306 /* aInterfaceInfo = */ nullptr, aName, aPath, aCall)
307 ->Then(
308 GetCurrentSerialEventTarget(), __func__,
309 [self = RefPtr{this}, args = RefPtr{variant},
310 aMethod](RefPtr<GDBusProxy>&& aProxy) {
311 WAKE_LOCK_LOG(
312 "WakeLockTopic::DBusUninhibitScreensaver() proxy created");
313 DBusProxyCall(aProxy.get(), aMethod, args.get(),
314 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT)
315 ->Then(
316 GetCurrentSerialEventTarget(), __func__,
317 [s = RefPtr{self}](RefPtr<GVariant>&& aResult) {
318 s->DBusUninhibitSucceeded();
320 [s = RefPtr{self}, aMethod](GUniquePtr<GError>&& aError) {
321 WAKE_LOCK_LOG(
322 "WakeLockTopic::DBusUninhibitFailed() %s call failed "
323 ": %s\n",
324 aMethod, aError->message);
325 s->DBusUninhibitFailed();
328 [self = RefPtr{this}](GUniquePtr<GError>&& aError) {
329 WAKE_LOCK_LOG(
330 "WakeLockTopic::DBusUninhibitFailed() Proxy creation failed: "
331 "%s\n",
332 aError->message);
333 self->DBusUninhibitFailed();
337 void WakeLockTopic::InhibitFreeDesktopScreensaver() {
338 WAKE_LOCK_LOG("InhibitFreeDesktopScreensaver()");
339 DBusInhibitScreensaver(FREEDESKTOP_SCREENSAVER_TARGET,
340 FREEDESKTOP_SCREENSAVER_OBJECT,
341 FREEDESKTOP_SCREENSAVER_INTERFACE, "Inhibit",
342 dont_AddRef(g_variant_ref_sink(g_variant_new(
343 "(ss)", g_get_prgname(), mTopic.get()))));
346 void WakeLockTopic::InhibitFreeDesktopPower() {
347 WAKE_LOCK_LOG("InhibitFreeDesktopPower()");
348 DBusInhibitScreensaver(FREEDESKTOP_POWER_TARGET, FREEDESKTOP_POWER_OBJECT,
349 FREEDESKTOP_POWER_INTERFACE, "Inhibit",
350 dont_AddRef(g_variant_ref_sink(g_variant_new(
351 "(ss)", g_get_prgname(), mTopic.get()))));
354 void WakeLockTopic::InhibitGNOME() {
355 WAKE_LOCK_LOG("InhibitGNOME()");
356 static const uint32_t xid = 0;
357 static const uint32_t flags = (1 << 3); // Inhibit idle
358 DBusInhibitScreensaver(
359 SESSION_MANAGER_TARGET, SESSION_MANAGER_OBJECT, SESSION_MANAGER_INTERFACE,
360 "Inhibit",
361 dont_AddRef(g_variant_ref_sink(
362 g_variant_new("(susu)", g_get_prgname(), xid, mTopic.get(), flags))));
365 void WakeLockTopic::UninhibitFreeDesktopScreensaver() {
366 WAKE_LOCK_LOG("UninhibitFreeDesktopScreensaver()");
367 DBusUninhibitScreensaver(FREEDESKTOP_SCREENSAVER_TARGET,
368 FREEDESKTOP_SCREENSAVER_OBJECT,
369 FREEDESKTOP_SCREENSAVER_INTERFACE, "UnInhibit");
372 void WakeLockTopic::UninhibitFreeDesktopPower() {
373 WAKE_LOCK_LOG("UninhibitFreeDesktopPower()");
374 DBusUninhibitScreensaver(FREEDESKTOP_POWER_TARGET, FREEDESKTOP_POWER_OBJECT,
375 FREEDESKTOP_POWER_INTERFACE, "UnInhibit");
378 void WakeLockTopic::UninhibitGNOME() {
379 WAKE_LOCK_LOG("UninhibitGNOME()");
380 DBusUninhibitScreensaver(SESSION_MANAGER_TARGET, SESSION_MANAGER_OBJECT,
381 SESSION_MANAGER_INTERFACE, "Uninhibit");
383 #endif
385 #if defined(MOZ_X11)
386 // TODO: Merge with Idle service?
387 typedef Bool (*_XScreenSaverQueryExtension_fn)(Display* dpy, int* event_base,
388 int* error_base);
389 typedef Bool (*_XScreenSaverQueryVersion_fn)(Display* dpy, int* major,
390 int* minor);
391 typedef void (*_XScreenSaverSuspend_fn)(Display* dpy, Bool suspend);
393 static PRLibrary* sXssLib = nullptr;
394 static _XScreenSaverQueryExtension_fn _XSSQueryExtension = nullptr;
395 static _XScreenSaverQueryVersion_fn _XSSQueryVersion = nullptr;
396 static _XScreenSaverSuspend_fn _XSSSuspend = nullptr;
398 /* static */
399 bool WakeLockTopic::CheckXScreenSaverSupport() {
400 if (!sXssLib) {
401 sXssLib = PR_LoadLibrary("libXss.so.1");
402 if (!sXssLib) {
403 return false;
407 _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)PR_FindFunctionSymbol(
408 sXssLib, "XScreenSaverQueryExtension");
409 _XSSQueryVersion = (_XScreenSaverQueryVersion_fn)PR_FindFunctionSymbol(
410 sXssLib, "XScreenSaverQueryVersion");
411 _XSSSuspend = (_XScreenSaverSuspend_fn)PR_FindFunctionSymbol(
412 sXssLib, "XScreenSaverSuspend");
413 if (!_XSSQueryExtension || !_XSSQueryVersion || !_XSSSuspend) {
414 return false;
417 GdkDisplay* gDisplay = gdk_display_get_default();
418 if (!GdkIsX11Display(gDisplay)) {
419 return false;
421 Display* display = GDK_DISPLAY_XDISPLAY(gDisplay);
423 int throwaway;
424 if (!_XSSQueryExtension(display, &throwaway, &throwaway)) return false;
426 int major, minor;
427 if (!_XSSQueryVersion(display, &major, &minor)) return false;
428 // Needs to be compatible with version 1.1
429 if (major != 1) return false;
430 if (minor < 1) return false;
432 WAKE_LOCK_LOG("XScreenSaver supported.");
433 return true;
436 /* static */
437 bool WakeLockTopic::InhibitXScreenSaver(bool inhibit) {
438 WAKE_LOCK_LOG("InhibitXScreenSaver %d", inhibit);
440 // Should only be called if CheckXScreenSaverSupport returns true.
441 // There's a couple of safety checks here nonetheless.
442 if (!_XSSSuspend) {
443 return false;
445 GdkDisplay* gDisplay = gdk_display_get_default();
446 if (!GdkIsX11Display(gDisplay)) {
447 return false;
449 Display* display = GDK_DISPLAY_XDISPLAY(gDisplay);
450 _XSSSuspend(display, inhibit);
452 WAKE_LOCK_LOG("InhibitXScreenSaver %d succeeded", inhibit);
453 mInhibited = inhibit;
454 return true;
456 #endif
458 #if defined(MOZ_WAYLAND)
459 /* static */
460 bool WakeLockTopic::CheckWaylandIdleInhibitSupport() {
461 nsWaylandDisplay* waylandDisplay = WaylandDisplayGet();
462 return waylandDisplay && waylandDisplay->GetIdleInhibitManager() != nullptr;
465 bool WakeLockTopic::InhibitWaylandIdle() {
466 WAKE_LOCK_LOG("InhibitWaylandIdle()");
468 nsWaylandDisplay* waylandDisplay = WaylandDisplayGet();
469 if (!waylandDisplay) {
470 return false;
473 nsWindow* focusedWindow = nsWindow::GetFocusedWindow();
474 if (!focusedWindow) {
475 return false;
478 UninhibitWaylandIdle();
480 MozContainerSurfaceLock lock(focusedWindow->GetMozContainer());
481 struct wl_surface* waylandSurface = lock.GetSurface();
482 if (waylandSurface) {
483 mWaylandInhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor(
484 waylandDisplay->GetIdleInhibitManager(), waylandSurface);
485 mInhibited = true;
488 WAKE_LOCK_LOG("InhibitWaylandIdle() %s",
489 !!mWaylandInhibitor ? "succeeded" : "failed");
490 return !!mWaylandInhibitor;
493 bool WakeLockTopic::UninhibitWaylandIdle() {
494 WAKE_LOCK_LOG("UninhibitWaylandIdle() mWaylandInhibitor %p",
495 mWaylandInhibitor);
497 mInhibited = false;
498 if (!mWaylandInhibitor) {
499 return false;
501 zwp_idle_inhibitor_v1_destroy(mWaylandInhibitor);
502 mWaylandInhibitor = nullptr;
503 return true;
505 #endif
507 bool WakeLockTopic::SendInhibit() {
508 WAKE_LOCK_LOG("WakeLockTopic::SendInhibit() WakeLockType %s",
509 WakeLockTypeNames[sWakeLockType]);
510 MOZ_ASSERT(sWakeLockType != Initial);
512 switch (sWakeLockType) {
513 #if defined(MOZ_ENABLE_DBUS)
514 case FreeDesktopScreensaver:
515 InhibitFreeDesktopScreensaver();
516 break;
517 case FreeDesktopPower:
518 InhibitFreeDesktopPower();
519 break;
520 case GNOME:
521 InhibitGNOME();
522 break;
523 #endif
524 #if defined(MOZ_X11)
525 case XScreenSaver:
526 return InhibitXScreenSaver(true);
527 #endif
528 #if defined(MOZ_WAYLAND)
529 case WaylandIdleInhibit:
530 return InhibitWaylandIdle();
531 #endif
532 default:
533 return false;
535 return true;
538 bool WakeLockTopic::SendUninhibit() {
539 WAKE_LOCK_LOG("WakeLockTopic::SendUninhibit() WakeLockType %s",
540 WakeLockTypeNames[sWakeLockType]);
541 MOZ_ASSERT(sWakeLockType != Initial);
542 switch (sWakeLockType) {
543 #if defined(MOZ_ENABLE_DBUS)
544 case FreeDesktopScreensaver:
545 UninhibitFreeDesktopScreensaver();
546 break;
547 case FreeDesktopPower:
548 UninhibitFreeDesktopPower();
549 break;
550 case GNOME:
551 UninhibitGNOME();
552 break;
553 #endif
554 #if defined(MOZ_X11)
555 case XScreenSaver:
556 return InhibitXScreenSaver(false);
557 #endif
558 #if defined(MOZ_WAYLAND)
559 case WaylandIdleInhibit:
560 return UninhibitWaylandIdle();
561 #endif
562 default:
563 return false;
565 return true;
568 nsresult WakeLockTopic::InhibitScreensaver() {
569 WAKE_LOCK_LOG("WakeLockTopic::InhibitScreensaver() state %d", mInhibited);
571 if (mInhibited) {
572 // Screensaver is inhibited. Nothing to do here.
573 return NS_OK;
575 mShouldInhibit = true;
577 // Iterate through wake lock types in case of failure.
578 while (!SendInhibit() && SwitchToNextWakeLockType()) {
582 return (sWakeLockType != Unsupported) ? NS_OK : NS_ERROR_FAILURE;
585 nsresult WakeLockTopic::UninhibitScreensaver() {
586 WAKE_LOCK_LOG("WakeLockTopic::UninhibitScreensaver() state %d", mInhibited);
588 if (!mInhibited) {
589 // Screensaver isn't inhibited. Nothing to do here.
590 return NS_OK;
592 mShouldInhibit = false;
594 // Don't switch wake lock type in case of failure.
595 // We need to use the same lock/unlock type.
596 return SendUninhibit() ? NS_OK : NS_ERROR_FAILURE;
599 bool WakeLockTopic::IsWakeLockTypeAvailable(int aWakeLockType) {
600 switch (aWakeLockType) {
601 #if defined(MOZ_ENABLE_DBUS)
602 case FreeDesktopScreensaver:
603 case FreeDesktopPower:
604 case GNOME:
605 return true;
606 #endif
607 #if defined(MOZ_X11)
608 case XScreenSaver:
609 if (!GdkIsX11Display()) {
610 return false;
612 if (!CheckXScreenSaverSupport()) {
613 WAKE_LOCK_LOG(" XScreenSaverSupport is missing!");
614 return false;
616 return true;
617 #endif
618 #if defined(MOZ_WAYLAND)
619 case WaylandIdleInhibit:
620 if (!GdkIsWaylandDisplay()) {
621 return false;
623 if (!CheckWaylandIdleInhibitSupport()) {
624 WAKE_LOCK_LOG(" WaylandIdleInhibitSupport is missing!");
625 return false;
627 return true;
628 #endif
629 default:
630 return false;
634 bool WakeLockTopic::SwitchToNextWakeLockType() {
635 WAKE_LOCK_LOG("WakeLockTopic::SwitchToNextWakeLockType() WakeLockType %s",
636 WakeLockTypeNames[sWakeLockType]);
638 if (sWakeLockType == Unsupported) {
639 return false;
642 #ifdef MOZ_LOGGING
643 auto printWakeLocktype = MakeScopeExit([&] {
644 WAKE_LOCK_LOG(" switched to WakeLockType %s",
645 WakeLockTypeNames[sWakeLockType]);
647 #endif
649 while (sWakeLockType != Unsupported) {
650 sWakeLockType++;
651 if (IsWakeLockTypeAvailable(sWakeLockType)) {
652 return true;
655 return false;
658 /* static */
659 WakeLockListener* WakeLockListener::GetSingleton(bool aCreate) {
660 if (!sSingleton && aCreate) {
661 sSingleton = new WakeLockListener();
663 return sSingleton;
666 /* static */
667 void WakeLockListener::Shutdown() {
668 WAKE_LOCK_LOG("WakeLockListener::Shutdown()");
669 sSingleton = nullptr;
672 nsresult WakeLockListener::Callback(const nsAString& topic,
673 const nsAString& state) {
674 if (!topic.Equals(u"screen"_ns) && !topic.Equals(u"video-playing"_ns) &&
675 !topic.Equals(u"autoscroll"_ns)) {
676 return NS_OK;
679 WAKE_LOCK_LOG("WakeLockListener %s state %s",
680 NS_ConvertUTF16toUTF8(topic).get(),
681 NS_ConvertUTF16toUTF8(state).get());
683 RefPtr<WakeLockTopic>* topicLock =
684 mTopics.GetOrInsertNew(topic, MakeRefPtr<WakeLockTopic>(topic));
686 // Treat "locked-background" the same as "unlocked" on desktop linux.
687 bool shouldLock = state.EqualsLiteral("locked-foreground");
688 WAKE_LOCK_LOG("shouldLock %d", shouldLock);
690 return shouldLock ? topicLock->get()->InhibitScreensaver()
691 : topicLock->get()->UninhibitScreensaver();