mirror of
https://github.com/overte-org/overte.git
synced 2025-07-28 14:20:25 +02:00
Support platform independent sleep/wake notifications
This commit is contained in:
parent
03e3f38ff1
commit
dfd78a2662
9 changed files with 263 additions and 96 deletions
|
@ -58,6 +58,7 @@
|
||||||
|
|
||||||
#include <shared/FileUtils.h>
|
#include <shared/FileUtils.h>
|
||||||
#include <shared/QtHelpers.h>
|
#include <shared/QtHelpers.h>
|
||||||
|
#include <shared/PlatformHelper.h>
|
||||||
#include <shared/GlobalAppProperties.h>
|
#include <shared/GlobalAppProperties.h>
|
||||||
#include <StatTracker.h>
|
#include <StatTracker.h>
|
||||||
#include <Trace.h>
|
#include <Trace.h>
|
||||||
|
@ -257,10 +258,6 @@ extern "C" {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#include "MacHelper.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID)
|
#if defined(Q_OS_ANDROID)
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include "AndroidHelper.h"
|
#include "AndroidHelper.h"
|
||||||
|
@ -552,13 +549,6 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message->message == WM_POWERBROADCAST) {
|
|
||||||
if (message->wParam == PBT_APMRESUMEAUTOMATIC) {
|
|
||||||
qCInfo(interfaceapp) << "Waking up from sleep or hybernation.";
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<NodeList>().data(), "noteAwakening", Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message->message == WM_COPYDATA) {
|
if (message->message == WM_COPYDATA) {
|
||||||
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)(message->lParam);
|
COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)(message->lParam);
|
||||||
QUrl url = QUrl((const char*)(pcds->lpData));
|
QUrl url = QUrl((const char*)(pcds->lpData));
|
||||||
|
@ -964,9 +954,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<KeyboardScriptingInterface>();
|
DependencyManager::set<KeyboardScriptingInterface>();
|
||||||
DependencyManager::set<GrabManager>();
|
DependencyManager::set<GrabManager>();
|
||||||
DependencyManager::set<AvatarPackager>();
|
DependencyManager::set<AvatarPackager>();
|
||||||
#ifdef Q_OS_MAC
|
PlatformHelper::setup();
|
||||||
DependencyManager::set<MacHelper>();
|
|
||||||
#endif
|
QObject::connect(DependencyManager::get<PlatformHelper>().get(), &PlatformHelper::systemWillWake, [] {
|
||||||
|
QMetaObject::invokeMethod(DependencyManager::get<NodeList>().data(), "noteAwakening", Qt::QueuedConnection);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
QString setBookmarkValue = getCmdOption(argc, constArgv, "--setBookmark");
|
QString setBookmarkValue = getCmdOption(argc, constArgv, "--setBookmark");
|
||||||
if (!setBookmarkValue.isEmpty()) {
|
if (!setBookmarkValue.isEmpty()) {
|
||||||
|
@ -1172,6 +1165,17 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
deadlockWatchdogThread->setMainThreadID(QThread::currentThreadId());
|
deadlockWatchdogThread->setMainThreadID(QThread::currentThreadId());
|
||||||
deadlockWatchdogThread->start();
|
deadlockWatchdogThread->start();
|
||||||
|
|
||||||
|
// Pause the deadlock watchdog when we sleep, or it might
|
||||||
|
// trigger a false positive when we wake back up
|
||||||
|
auto platformHelper = DependencyManager::get<PlatformHelper>();
|
||||||
|
|
||||||
|
connect(platformHelper.get(), &PlatformHelper::systemWillSleep, [] {
|
||||||
|
DeadlockWatchdogThread::pause();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(platformHelper.get(), &PlatformHelper::systemWillWake, [] {
|
||||||
|
DeadlockWatchdogThread::resume();
|
||||||
|
});
|
||||||
|
|
||||||
// Main thread timer to keep the watchdog updated
|
// Main thread timer to keep the watchdog updated
|
||||||
QTimer* watchdogUpdateTimer = new QTimer(this);
|
QTimer* watchdogUpdateTimer = new QTimer(this);
|
||||||
|
@ -2869,9 +2873,7 @@ Application::~Application() {
|
||||||
_gameWorkload.shutdown();
|
_gameWorkload.shutdown();
|
||||||
|
|
||||||
DependencyManager::destroy<Preferences>();
|
DependencyManager::destroy<Preferences>();
|
||||||
#ifdef Q_OS_MAC
|
PlatformHelper::shutdown();
|
||||||
DependencyManager::destroy<MacHelper>();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_entityClipboard->eraseAllOctreeElements();
|
_entityClipboard->eraseAllOctreeElements();
|
||||||
_entityClipboard.reset();
|
_entityClipboard.reset();
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
//
|
|
||||||
// MacHelper.h
|
|
||||||
// interface/src
|
|
||||||
//
|
|
||||||
// Created by Howard Stearns
|
|
||||||
// Copyright 2019 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "InterfaceLogging.h"
|
|
||||||
#include "MacHelper.h"
|
|
||||||
#include <NodeList.h>
|
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
#include <IOKit/IOMessage.h>
|
|
||||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
|
||||||
|
|
||||||
// The type definitions in these variables come from IOKit, which includes a definition of Duration that conflicts with ours.
|
|
||||||
// So... we include these definitions here rather than in the .h, as the .h is included in Application.cpp which
|
|
||||||
// uses Duration.
|
|
||||||
static io_connect_t root_port;
|
|
||||||
static IONotificationPortRef notifyPortRef;
|
|
||||||
static io_object_t notifierObject;
|
|
||||||
static void* refCon;
|
|
||||||
|
|
||||||
static void sleepHandler(void* refCon, io_service_t service, natural_t messageType, void* messageArgument) {
|
|
||||||
if (messageType == kIOMessageSystemHasPoweredOn) {
|
|
||||||
qCInfo(interfaceapp) << "Waking up from sleep or hybernation.";
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<NodeList>().data(), "noteAwakening", Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MacHelper::MacHelper() {
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
root_port = IORegisterForSystemPower(refCon, ¬ifyPortRef, sleepHandler, ¬ifierObject);
|
|
||||||
if (root_port == 0) {
|
|
||||||
qCWarning(interfaceapp) << "IORegisterForSystemPower failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CFRunLoopAddSource(CFRunLoopGetCurrent(),
|
|
||||||
IONotificationPortGetRunLoopSource(notifyPortRef),
|
|
||||||
kCFRunLoopCommonModes);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
MacHelper::~MacHelper() {
|
|
||||||
#ifdef Q_OS_MAC
|
|
||||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
|
|
||||||
IONotificationPortGetRunLoopSource(notifyPortRef),
|
|
||||||
kCFRunLoopCommonModes);
|
|
||||||
IODeregisterForSystemPower(¬ifierObject);
|
|
||||||
IOServiceClose(root_port);
|
|
||||||
IONotificationPortDestroy(notifyPortRef);
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
//
|
|
||||||
// MacHelper.h
|
|
||||||
// interface/src
|
|
||||||
//
|
|
||||||
// Created by Howard Stearns
|
|
||||||
// Copyright 2019 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DependencyManager.h"
|
|
||||||
|
|
||||||
class MacHelper : public Dependency {
|
|
||||||
public:
|
|
||||||
MacHelper();
|
|
||||||
~MacHelper();
|
|
||||||
};
|
|
||||||
|
|
27
libraries/shared/src/shared/PlatformHelper.cpp
Normal file
27
libraries/shared/src/shared/PlatformHelper.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
#include "PlatformHelper.h"
|
||||||
|
|
||||||
|
void PlatformHelper::onSleep() {
|
||||||
|
if (_awake.exchange(false)) {
|
||||||
|
qInfo() << "Entering sleep or hibernation.";
|
||||||
|
emit systemWillSleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformHelper::onWake() {
|
||||||
|
if (!_awake.exchange(true)) {
|
||||||
|
qInfo() << "Waking up from sleep or hibernation.";
|
||||||
|
emit systemWillWake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlatformHelper::shutdown() {
|
||||||
|
DependencyManager::destroy<PlatformHelper>();
|
||||||
|
}
|
||||||
|
|
41
libraries/shared/src/shared/PlatformHelper.h
Normal file
41
libraries/shared/src/shared/PlatformHelper.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_shared_PlatformHelper_h
|
||||||
|
#define hifi_shared_PlatformHelper_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <QtCore/QtGlobal>
|
||||||
|
#include "../DependencyManager.h"
|
||||||
|
|
||||||
|
class PlatformHelper : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PlatformHelper() {}
|
||||||
|
virtual ~PlatformHelper() {}
|
||||||
|
|
||||||
|
void onSleep();
|
||||||
|
void onWake();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void systemWillSleep();
|
||||||
|
void systemWillWake();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Run the per-platform code to instantiate a platform-dependent PlatformHelper dependency object
|
||||||
|
static void setup();
|
||||||
|
// Run the per-platform code to cleanly shutdown a platform-dependent PlatformHelper dependency object
|
||||||
|
static void shutdown();
|
||||||
|
|
||||||
|
std::atomic<bool> _awake{ true };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
27
libraries/shared/src/shared/platform/AndroidHelper.cpp
Normal file
27
libraries/shared/src/shared/platform/AndroidHelper.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../PlatformHelper.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
|
|
||||||
|
// FIXME support sleep/wake notifications
|
||||||
|
class AndroidHelper : public PlatformHelper {
|
||||||
|
public:
|
||||||
|
AndroidHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~AndroidHelper() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void PlatformHelper::setup() {
|
||||||
|
DependencyManager::set<PlatformHelper, AndroidHelper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
27
libraries/shared/src/shared/platform/LinuxHelper.cpp
Normal file
27
libraries/shared/src/shared/platform/LinuxHelper.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../PlatformHelper.h"
|
||||||
|
|
||||||
|
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
|
||||||
|
|
||||||
|
// FIXME support sleep/wake notifications
|
||||||
|
class LinuxHelper : public PlatformHelper {
|
||||||
|
public:
|
||||||
|
LinuxHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
~LinuxHelper() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void PlatformHelper::setup() {
|
||||||
|
DependencyManager::set<PlatformHelper, LinuxHelper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
70
libraries/shared/src/shared/platform/MacHelper.cpp
Normal file
70
libraries/shared/src/shared/platform/MacHelper.cpp
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Based on interface/src/MacHelper.cpp, created by Howard Stearns
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../PlatformHelper.h"
|
||||||
|
|
||||||
|
#if !defined(Q_OS_ANDROID) && defined(Q_OS_MAC)
|
||||||
|
#include <IOKit/IOMessage.h>
|
||||||
|
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||||
|
|
||||||
|
class MacHelper : public PlatformHelper {
|
||||||
|
public:
|
||||||
|
MacHelper() {
|
||||||
|
_rootPort = IORegisterForSystemPower(this, &_notifyPortRef, serviceInterestCallback, &_notifierObject);
|
||||||
|
if (_rootPort == 0) {
|
||||||
|
qWarning() << "IORegisterForSystemPower failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CFRunLoopAddSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(_notifyPortRef), kCFRunLoopCommonModes);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MacHelper() {
|
||||||
|
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), IONotificationPortGetRunLoopSource(_notifyPortRef), kCFRunLoopCommonModes);
|
||||||
|
IODeregisterForSystemPower(&_notifierObject);
|
||||||
|
IOServiceClose(_rootPort);
|
||||||
|
IONotificationPortDestroy(_notifyPortRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onServiceMessage(io_service_t, natural_t messageType, void* messageArgument) {
|
||||||
|
switch (messageType) {
|
||||||
|
case kIOMessageSystemHasPoweredOn:
|
||||||
|
onWake();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kIOMessageSystemWillSleep:
|
||||||
|
onSleep();
|
||||||
|
// explicit fallthrough
|
||||||
|
|
||||||
|
// Per the documentation for kIOMessageSystemWillSleep and kIOMessageCanSystemSleep, the receiver MUST respond
|
||||||
|
// https://developer.apple.com/documentation/iokit/1557114-ioregisterforsystempower?language=objc
|
||||||
|
case kIOMessageCanSystemSleep:
|
||||||
|
IOAllowPowerChange(_rootPort, (long)messageArgument);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void serviceInterestCallback(void* refCon, io_service_t service, natural_t messageType, void* messageArgument) {
|
||||||
|
static_cast<MacHelper*>(refCon)->onServiceMessage(service, messageType, messageArgument);
|
||||||
|
}
|
||||||
|
|
||||||
|
io_connect_t _rootPort{ 0 };
|
||||||
|
IONotificationPortRef _notifyPortRef{};
|
||||||
|
io_object_t _notifierObject{};
|
||||||
|
};
|
||||||
|
|
||||||
|
void PlatformHelper::setup() {
|
||||||
|
DependencyManager::set<PlatformHelper, MacHelper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
52
libraries/shared/src/shared/platform/WinHelper.cpp
Normal file
52
libraries/shared/src/shared/platform/WinHelper.cpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2019/08/22
|
||||||
|
// Copyright 2013-2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "../PlatformHelper.h"
|
||||||
|
|
||||||
|
#if !defined(Q_OS_ANDROID) && defined(Q_OS_WIN)
|
||||||
|
|
||||||
|
#include <QtCore/QAbstractNativeEventFilter>
|
||||||
|
#include <QtCore/QAbstractEventDispatcher>
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
class WinHelper : public PlatformHelper, public QAbstractNativeEventFilter {
|
||||||
|
public:
|
||||||
|
WinHelper() {
|
||||||
|
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~WinHelper() {
|
||||||
|
auto eventDispatcher = QAbstractEventDispatcher::instance();
|
||||||
|
if (eventDispatcher) {
|
||||||
|
eventDispatcher->removeNativeEventFilter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nativeEventFilter(const QByteArray& eventType, void* message, long*) override {
|
||||||
|
MSG* msg = static_cast<MSG*>(message);
|
||||||
|
if (msg->message == WM_POWERBROADCAST) {
|
||||||
|
switch (msg->wParam) {
|
||||||
|
case PBT_APMRESUMEAUTOMATIC:
|
||||||
|
case PBT_APMRESUMESUSPEND:
|
||||||
|
onWake();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PBT_APMSUSPEND:
|
||||||
|
onSleep();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void PlatformHelper::setup() {
|
||||||
|
DependencyManager::set<PlatformHelper, WinHelper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue