1 /***************************************************************************
2 * Copyright (C) 2016 by Jan Grulich <jgrulich@redhat.com> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
18 ***************************************************************************/
19
20 #include "wirelesspowersaving.h"
21
22 #include "wirelesspowersavingadaptor.h"
23
24 #include <powerdevilcore.h>
25 #include <powerdevil_debug.h>
26
27 #include <KConfigGroup>
28
29 #include <NetworkManagerQt/Manager>
30
31
32 namespace PowerDevil {
33 namespace BundledActions {
34
WirelessPowerSaving(QObject * parent)35 WirelessPowerSaving::WirelessPowerSaving(QObject* parent)
36 : Action(parent)
37 , m_btManager(new BluezQt::Manager())
38 , m_currentProfileWifiOption(BundledActions::WirelessPowerSaving::TurnOff)
39 , m_currentProfileWwanOption(BundledActions::WirelessPowerSaving::TurnOff)
40 , m_currentProfileBtOption(BundledActions::WirelessPowerSaving::TurnOff)
41 , m_lastProfileWifiOption(BundledActions::WirelessPowerSaving::TurnOff)
42 , m_lastProfileWwanOption(BundledActions::WirelessPowerSaving::TurnOff)
43 , m_lastProfileBtOption(BundledActions::WirelessPowerSaving::TurnOff)
44 , m_lastWifiState(false)
45 , m_lastWwanState(false)
46 , m_lastBtState(false)
47 {
48 // DBus
49 new WirelessPowerSavingAdaptor(this);
50
51 setRequiredPolicies(PowerDevil::PolicyAgent::None);
52 }
53
onProfileUnload()54 void WirelessPowerSaving::onProfileUnload()
55 {
56 if (m_lastWifiState && m_currentProfileWifiOption == BundledActions::WirelessPowerSaving::TurnOff) {
57 setWirelessEnabled(true);
58 } else if (!m_lastWifiState && m_currentProfileWifiOption == BundledActions::WirelessPowerSaving::TurnOn) {
59 setWirelessEnabled(false);
60 }
61
62 if (m_lastWwanState && m_currentProfileWwanOption == BundledActions::WirelessPowerSaving::TurnOff) {
63 setMobileBroadbandEnabled(true);
64 } else if (!m_lastWwanState && m_currentProfileWwanOption == BundledActions::WirelessPowerSaving::TurnOn) {
65 setMobileBroadbandEnabled(false);
66 }
67
68 if (m_lastBtState && m_currentProfileBtOption == BundledActions::WirelessPowerSaving::TurnOff) {
69 setBluetoothEnabled(true);
70 } else if (!m_lastBtState && m_currentProfileBtOption == BundledActions::WirelessPowerSaving::TurnOn) {
71 setBluetoothEnabled(false);
72 }
73 }
74
onWakeupFromIdle()75 void WirelessPowerSaving::onWakeupFromIdle()
76 {
77 // Nothing to do
78 }
79
onIdleTimeout(int msec)80 void WirelessPowerSaving::onIdleTimeout(int msec)
81 {
82 Q_UNUSED(msec);
83 // Nothing to do
84 }
85
onProfileLoad()86 void WirelessPowerSaving::onProfileLoad()
87 {
88 qCDebug(POWERDEVIL) << m_currentProfile << m_lastProfile;
89
90 if (((m_currentProfile == QLatin1String("Battery") && m_lastProfile == QLatin1String("AC")) ||
91 (m_currentProfile == QLatin1String("LowBattery") && (m_lastProfile == QLatin1String("AC") || m_lastProfile == QLatin1String("Battery")))) &&
92 (((m_lastProfileWifiOption == BundledActions::WirelessPowerSaving::TurnOff && m_currentProfileWifiOption == BundledActions::WirelessPowerSaving::TurnOn) || m_currentProfileWifiOption == NoAction) &&
93 ((m_lastProfileWwanOption == BundledActions::WirelessPowerSaving::TurnOff && m_currentProfileWwanOption == BundledActions::WirelessPowerSaving::TurnOn) || m_currentProfileWwanOption == NoAction) &&
94 ((m_lastProfileBtOption == BundledActions::WirelessPowerSaving::TurnOff && m_currentProfileBtOption == BundledActions::WirelessPowerSaving::TurnOn) || m_currentProfileBtOption == NoAction))) {
95 // We don't want to change anything here
96 qCDebug(POWERDEVIL) << "Not changing anything, the current profile is more conservative";
97 } else {
98 QVariantMap args{
99 {{QLatin1String("wifiOption"), QVariant::fromValue((uint)m_currentProfileWifiOption)},
100 {QLatin1String("wwanOption"), QVariant::fromValue((uint)m_currentProfileWwanOption)},
101 {QLatin1String("btOption"), QVariant::fromValue((uint)m_currentProfileBtOption)}}
102 };
103
104 trigger(args);
105 }
106 }
107
triggerImpl(const QVariantMap & args)108 void WirelessPowerSaving::triggerImpl(const QVariantMap& args)
109 {
110 const PowerSavingOption wifiOption = (PowerSavingOption)args.value(QLatin1String("wifiOption")).toUInt();
111 const PowerSavingOption wwanOption = (PowerSavingOption)args.value(QLatin1String("wwanOption")).toUInt();
112 const PowerSavingOption btOption = (PowerSavingOption)args.value(QLatin1String("btOption")).toUInt();
113
114 if (wifiOption == BundledActions::WirelessPowerSaving::TurnOff) {
115 setWirelessEnabled(false);
116 } else if (wifiOption == BundledActions::WirelessPowerSaving::TurnOn) {
117 setWirelessEnabled(true);
118 }
119
120 if (wwanOption == BundledActions::WirelessPowerSaving::TurnOff) {
121 setMobileBroadbandEnabled(false);
122 } else if (wwanOption == BundledActions::WirelessPowerSaving::TurnOn) {
123 setMobileBroadbandEnabled(true);
124 }
125
126 if (btOption == BundledActions::WirelessPowerSaving::TurnOff) {
127 setBluetoothEnabled(false);
128 } else if (btOption == BundledActions::WirelessPowerSaving::TurnOn) {
129 setBluetoothEnabled(true);
130 }
131 }
132
isSupported()133 bool WirelessPowerSaving::isSupported()
134 {
135 /* Check if we can enable/disable bluetooth ???
136 * This would require to check if we can read/write from/to /dev/rfkill. Maybe Rfkill class from bluez-qt
137 * can be used for this, but it seems to be private class
138 */
139
140 NMStringMap permissions = NetworkManager::permissions();
141 bool changeWifiAllowed = false;
142 bool changeWwanAllowed = false;
143 for (auto it = permissions.constBegin(); it != permissions.constEnd(); ++it) {
144 if (it.key() == QLatin1String("org.freedesktop.NetworkManager.enable-disable-wifi")) {
145 changeWifiAllowed = it.value() == QLatin1String("yes");
146 } else if (it.key() == QLatin1String("org.freedesktop.NetworkManager.enable-disable-wwan")) {
147 changeWwanAllowed = it.value() == QLatin1String("yes");
148 }
149 }
150
151 return changeWifiAllowed || changeWwanAllowed;
152 }
153
loadAction(const KConfigGroup & config)154 bool WirelessPowerSaving::loadAction(const KConfigGroup& config)
155 {
156 // Handle profile changes
157 m_lastProfile = m_currentProfile;
158 m_currentProfile = config.parent().name();
159
160 qCDebug(POWERDEVIL) << "Profiles: " << m_currentProfile << m_lastProfile;
161
162 m_lastProfileWifiOption = m_currentProfileWifiOption;
163 m_lastProfileWwanOption = m_currentProfileWwanOption;
164 m_lastProfileBtOption = m_currentProfileBtOption;
165
166 if (config.hasKey("wifiOption")) {
167 m_currentProfileWifiOption = (PowerSavingOption)config.readEntry<uint>("wifiOption", 0);
168 }
169
170 if (config.hasKey("wwanOption")) {
171 m_currentProfileWwanOption = (PowerSavingOption)config.readEntry<uint>("wwanOption", 0);
172 }
173
174 if (config.hasKey("btOption")) {
175 m_currentProfileBtOption = (PowerSavingOption)config.readEntry<uint>("btOption", 0);
176 }
177
178
179 m_lastWifiState = NetworkManager::isWirelessEnabled();
180 m_lastWwanState = NetworkManager::isWwanEnabled();
181 m_lastBtState = !m_btManager->isBluetoothBlocked();
182
183 return true;
184 }
185
setBluetoothEnabled(bool enabled)186 void WirelessPowerSaving::setBluetoothEnabled(bool enabled)
187 {
188 m_btManager->setBluetoothBlocked(!enabled);
189 }
190
setMobileBroadbandEnabled(bool enabled)191 void WirelessPowerSaving::setMobileBroadbandEnabled(bool enabled)
192 {
193 NetworkManager::setWwanEnabled(enabled);
194 }
195
setWirelessEnabled(bool enabled)196 void WirelessPowerSaving::setWirelessEnabled(bool enabled)
197 {
198 NetworkManager::setWirelessEnabled(enabled);
199 }
200
201 }
202
203 }
204