1 /*
2 SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org>
3 SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@redhat.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "device.h"
9 #include "freedesktop_interface.h"
10 #include "kscreen_daemon_debug.h"
11
12 Device *Device::m_instance = nullptr;
13
self()14 Device *Device::self()
15 {
16 if (!Device::m_instance) {
17 m_instance = new Device();
18 }
19
20 return m_instance;
21 }
22
destroy()23 void Device::destroy()
24 {
25 delete m_instance;
26 m_instance = nullptr;
27 }
28
Device(QObject * parent)29 Device::Device(QObject *parent)
30 : QObject(parent)
31 , m_isReady(false)
32 , m_isLaptop(false)
33 , m_isLidClosed(false)
34 , m_isDocked(false)
35 {
36 m_freedesktop = new OrgFreedesktopDBusPropertiesInterface(QStringLiteral("org.freedesktop.UPower"),
37 QStringLiteral("/org/freedesktop/UPower"),
38 QDBusConnection::systemBus(),
39 this);
40 if (!m_freedesktop->isValid()) {
41 qCWarning(KSCREEN_KDED) << "UPower not available, lid detection won't work";
42 qCDebug(KSCREEN_KDED) << m_freedesktop->lastError().message();
43 } else {
44 QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.UPower"),
45 QStringLiteral("/org/freedesktop/UPower"),
46 QStringLiteral("org.freedesktop.DBus.Properties"),
47 QStringLiteral("PropertiesChanged"),
48 this,
49 SLOT(changed()));
50 fetchIsLaptop();
51 }
52
53 m_suspendSession = new QDBusInterface(QStringLiteral("org.kde.Solid.PowerManagement"),
54 QStringLiteral("/org/kde/Solid/PowerManagement/Actions/SuspendSession"),
55 QStringLiteral("org.kde.Solid.PowerManagement.Actions.SuspendSession"),
56 QDBusConnection::sessionBus(),
57 this);
58 if (m_suspendSession->isValid()) {
59 connect(m_suspendSession, SIGNAL(resumingFromSuspend()), this, SIGNAL(resumingFromSuspend()));
60 connect(m_suspendSession, SIGNAL(aboutToSuspend()), this, SIGNAL(aboutToSuspend()));
61 } else {
62 qCWarning(KSCREEN_KDED) << "PowerDevil SuspendSession action not available!";
63 qCDebug(KSCREEN_KDED) << m_suspendSession->lastError().message();
64 }
65
66 fetchIsLaptop();
67 }
68
~Device()69 Device::~Device()
70 {
71 }
72
changed()73 void Device::changed()
74 {
75 fetchLidIsClosed();
76 }
77
setReady()78 void Device::setReady()
79 {
80 if (m_isReady) {
81 return;
82 }
83
84 m_isReady = true;
85 Q_EMIT ready();
86 }
87
isReady() const88 bool Device::isReady() const
89 {
90 return m_isReady;
91 }
92
isLaptop() const93 bool Device::isLaptop() const
94 {
95 return m_isLaptop;
96 }
97
isLidClosed() const98 bool Device::isLidClosed() const
99 {
100 return m_isLidClosed;
101 }
102
isDocked() const103 bool Device::isDocked() const
104 {
105 return m_isDocked;
106 }
107
fetchIsLaptop()108 void Device::fetchIsLaptop()
109 {
110 QDBusPendingReply<QVariant> res = m_freedesktop->Get(QStringLiteral("org.freedesktop.UPower"), QStringLiteral("LidIsPresent"));
111 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(res);
112 connect(watcher, &QDBusPendingCallWatcher::finished, this, &Device::isLaptopFetched);
113 }
114
isLaptopFetched(QDBusPendingCallWatcher * watcher)115 void Device::isLaptopFetched(QDBusPendingCallWatcher *watcher)
116 {
117 const QDBusPendingReply<QVariant> reply = *watcher;
118 if (reply.isError()) {
119 qCDebug(KSCREEN_KDED) << "Couldn't get if the device is a laptop: " << reply.error().message();
120 return;
121 }
122
123 m_isLaptop = reply.value().toBool();
124 watcher->deleteLater();
125
126 if (!m_isLaptop) {
127 setReady();
128 return;
129 }
130
131 fetchLidIsClosed();
132 }
133
fetchLidIsClosed()134 void Device::fetchLidIsClosed()
135 {
136 QDBusPendingReply<QVariant> res = m_freedesktop->Get(QStringLiteral("org.freedesktop.UPower"), QStringLiteral("LidIsClosed"));
137 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(res);
138 connect(watcher, &QDBusPendingCallWatcher::finished, this, &Device::isLidClosedFetched);
139 }
140
isLidClosedFetched(QDBusPendingCallWatcher * watcher)141 void Device::isLidClosedFetched(QDBusPendingCallWatcher *watcher)
142 {
143 const QDBusPendingReply<QVariant> reply = *watcher;
144 if (reply.isError()) {
145 qCDebug(KSCREEN_KDED) << "Couldn't get if the laptop has the lid closed: " << reply.error().message();
146 return;
147 }
148
149 if (reply.argumentAt<0>() != m_isLidClosed) {
150 m_isLidClosed = reply.value().toBool();
151 if (m_isReady) {
152 Q_EMIT lidClosedChanged(m_isLidClosed);
153 ;
154 }
155 }
156 watcher->deleteLater();
157
158 fetchIsDocked();
159 }
160
fetchIsDocked()161 void Device::fetchIsDocked()
162 {
163 setReady();
164 }
165