1 //===========================================
2 //  Lumina desktop source code
3 //  Copyright (c) 2017, Ken Moore
4 //  Available under the 3-clause BSD license
5 //  See the LICENSE file for full details
6 //===========================================
7 //  This is the main interface for any OS-specific system calls
8 //    To port Lumina to a different operating system, just create a file
9 //    called "OSInterface-<Operating System>.cpp"
10 //===========================================
11 #ifndef _LUMINA_LIBRARY_OS_INTERFACE_H
12 #define _LUMINA_LIBRARY_OS_INTERFACE_H
13 
14 #include <QString>
15 #include <QStringList>
16 #include <QList>
17 #include <QObject>
18 #include <QVariant>
19 #include <QHash>
20 #include <QTimer>
21 #include <QFile>
22 #include <QDir>
23 #include <QVariant>
24 
25 #include <QIODevice>
26 #include <QFileSystemWatcher>
27 #include <QNetworkAccessManager>
28 #include <QNetworkReply>
29 #include <QSslError>
30 #include <QHostInfo>
31 #include <QHostAddress>
32 #include <QNetworkConfiguration>
33 #include <QNetworkInterface>
34 
35 //Lumina Utils class
36 //#include <LUtils.h>
37 
38 class OSInterface : public QObject{
39 	Q_OBJECT
40 	// == QML ACCESSIBLE PROPERTIES ==
41 	//Battery
42 	Q_PROPERTY( float batteryCharge READ batteryCharge NOTIFY batteryChanged)
43 	Q_PROPERTY( bool batteryCharging READ batteryCharging NOTIFY batteryChanged)
44 	Q_PROPERTY( QString batteryRemaining READ batteryRemaining NOTIFY batteryChanged)
45 	Q_PROPERTY( QString batteryIcon READ batteryIcon NOTIFY batteryChanged)
46 	Q_PROPERTY( QString batteryStatus READ batteryStatus NOTIFY batteryChanged)
47 	//Volume
48 	Q_PROPERTY( int volume READ volume WRITE setVolume NOTIFY volumeChanged)
49 	Q_PROPERTY( QString volumeIcon READ volumeIcon NOTIFY volumeChanged)
50 	//Network
51 	Q_PROPERTY( bool networkAvailable READ networkAvailable NOTIFY networkStatusChanged)
52 	Q_PROPERTY( QString networkType READ networkType NOTIFY networkStatusChanged)
53 	Q_PROPERTY( float networkStrength READ networkStrength NOTIFY networkStatusChanged)
54 	Q_PROPERTY( QString networkHostname READ networkHostname NOTIFY networkStatusChanged)
55 	Q_PROPERTY( QStringList networkAddress READ networkAddress NOTIFY networkStatusChanged)
56 	Q_PROPERTY( QString networkIcon READ networkIcon NOTIFY networkStatusChanged);
57 	Q_PROPERTY( QString networkStatus READ networkStatus NOTIFY networkStatusChanged);
58 	//Media
59 	Q_PROPERTY( QStringList mediaShortcuts READ mediaShortcuts NOTIFY mediaShortcutsChanged)
60 	//Updates
61 	Q_PROPERTY( QString updateStatus READ updateStatus NOTIFY updateStatusChanged)
62 	Q_PROPERTY( QString updateIcon READ updateIcon NOTIFY updateStatusChanged)
63 	Q_PROPERTY( bool updateInfoAvailable READ updateInfoAvailable NOTIFY updateStatusChanged)
64 
65 	//Power options
66 	Q_PROPERTY( bool canReboot READ canReboot NOTIFY powerAvailableChanged)
67 	Q_PROPERTY( bool canShutdown READ canShutdown NOTIFY powerAvailableChanged)
68 	Q_PROPERTY( bool canSuspend READ canSuspend NOTIFY powerAvailableChanged)
69 	//Brightness
70 	Q_PROPERTY( int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged)
71 
72 public:
73 	// ================
74 	// SEMI-VIRTUAL FUNCTIONS - NEED TO BE DEFINED IN THE OS-SPECIFIC FILES
75 	// ================
76 	//Start/stop interface watchers/notifications
77 	void start();
78 	void stop();
79 	bool isRunning(); //status of the object - whether it has been started yet
80 
81 	// = Battery =
82 	Q_INVOKABLE bool batteryAvailable();
83 	Q_INVOKABLE float batteryCharge();
84 	Q_INVOKABLE bool batteryCharging();
85 	Q_INVOKABLE QString batteryRemaining();
86 	Q_INVOKABLE QString batteryIcon();
87 	Q_INVOKABLE QString batteryStatus();
88 
89 	// = Volume =
90 	Q_INVOKABLE bool volumeSupported();
91 	Q_INVOKABLE int volume();
92 	Q_INVOKABLE void setVolume(int);
93 	Q_INVOKABLE QString volumeIcon();
94 
95 	// = Network Information =
96 	Q_INVOKABLE bool networkAvailable();
97 	Q_INVOKABLE QString networkType(); //"wifi", "wired", "cell", "cell-2G", "cell-3G", "cell-4G"
98 	Q_INVOKABLE float networkStrength(); //percentage. ("wired" type should always be 100%)
99 	Q_INVOKABLE QString networkIcon();
100 	Q_INVOKABLE QString networkHostname();
101 	Q_INVOKABLE QStringList networkAddress();
102 	Q_INVOKABLE QString networkStatus(); //combines a bunch of the above info into a single string
103 
104 	// = Network Modification =
105 	Q_INVOKABLE bool hasNetworkManager();
106 	Q_INVOKABLE QString networkManagerUtility(); //binary name or *.desktop filename (if registered on the system)
107 
108 	// = Media Shortcuts =
109 	Q_INVOKABLE QStringList mediaDirectories(); //directory where XDG shortcuts are placed for interacting with media (local/remote)
110 	Q_INVOKABLE QStringList mediaShortcuts(); //List of currently-available XDG shortcut file paths
111 
112 	// = Updates =
113 	Q_INVOKABLE bool updatesSupported(); //is thie subsystem supported for the OS?
114 	Q_INVOKABLE QString updateStatus();	//Current status ["","available","running","finished"]
115 	Q_INVOKABLE bool updateInfoAvailable();
116 	Q_INVOKABLE QString updateIcon();
117 	Q_INVOKABLE QString updateStatusInfo(); //Extra information corresponding to the current status
118 	Q_INVOKABLE QString updateDetails();	//Information about any available updates
119 	Q_INVOKABLE QString updateLog();		//Information about any currently-running update
120 	Q_INVOKABLE QString updateResults();	//Information about any finished update
121 	Q_INVOKABLE void startUpdates();
122 	Q_INVOKABLE bool updateOnlyOnReboot(); //Should the startUpdates function be called only when rebooting the system?
123 	Q_INVOKABLE bool updateCausesReboot(); //Does the update power-cycle the system?
124 	Q_INVOKABLE QDateTime lastUpdate();	//The date/time of the previous updates
125 	Q_INVOKABLE QString lastUpdateResults(); //Information about the previously-finished update
126 
127 	// = System Power =
128 	Q_INVOKABLE bool canReboot();
129 	Q_INVOKABLE void startReboot();
130 	Q_INVOKABLE bool canShutdown();
131 	Q_INVOKABLE void startShutdown();
132 	Q_INVOKABLE bool canSuspend();
133 	Q_INVOKABLE void startSuspend();
134 
135 	// = Screen Brightness =
136 	Q_INVOKABLE bool brightnessSupported(); //is this subsystem available for the OS?
137 	Q_INVOKABLE int brightness(); //percentage: 0-100 with -1 for errors
138 	Q_INVOKABLE void setBrightness(int);
139 
140 	// = System Status Monitoring
141 	Q_INVOKABLE bool cpuSupported(); //is this subsystem available for the OS?
142 	Q_INVOKABLE QList<int> cpuPercentage(); // (one per CPU) percentage: 0-100 with -1 for errors
143 	Q_INVOKABLE QStringList cpuTemperatures(); // (one per CPU) Temperature of CPU ("50C" for example)
144 
145 	Q_INVOKABLE bool memorySupported(); //is this subsystem available for the OS?
146 	Q_INVOKABLE int memoryUsedPercentage(); //percentage: 0-100 with -1 for errors
147 	Q_INVOKABLE QString memoryTotal(); //human-readable form - does not tend to change within a session
148 	Q_INVOKABLE QStringList diskIO(); //Returns list of current read/write stats for each device
149 
150 	Q_INVOKABLE bool diskSupported(); //is this subsystem available for the OS?
151 	Q_INVOKABLE int fileSystemPercentage(QString dir); //percentage of capacity used: 0-100 with -1 for errors
152 	Q_INVOKABLE QString fileSystemCapacity(QString dir); //human-readable form - total capacity
153 
154 	// = OS-Specific Utilities =
155 	Q_INVOKABLE bool hasControlPanel();
156 	Q_INVOKABLE QString controlPanelShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
157 	Q_INVOKABLE bool hasAudioMixer();
158 	Q_INVOKABLE QString audioMixerShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
159 	Q_INVOKABLE bool hasAppStore();
160 	Q_INVOKABLE QString appStoreShortcut(); //relative *.desktop shortcut name (Example: "some_utility.desktop")
161 
162 
163 	// = DIRECT OS INTERACTIONS = (properties above are cached/gated)
164 	// = Battery =
165 	bool OS_batteryAvailable();
166 	float OS_batteryCharge();
167 	bool OS_batteryCharging();
168 	double OS_batterySecondsLeft();
169 	// = Volume =
170 	bool OS_volumeSupported();
171 	int OS_volume();
172 	bool OS_setVolume(int);
173 	// = Network Information =
174 	QString OS_networkTypeFromDeviceName(QString name);
175 	float OS_networkStrengthFromDeviceName(QString name);
176 	// = Media Shortcuts =
177 	QStringList OS_mediaDirectories();
178 	// = Updates =
179 	bool OS_updatesSupported();
180 	bool OS_updatesAvailable();
181 	QString OS_updateDetails();
182 	bool OS_updatesRunning();
183 	QString OS_updateLog();
184 	bool OS_updatesFinished();
185 	QString OS_updateResults();
186 	void OS_startUpdates();
187 	bool OS_updateOnlyOnReboot();
188 	bool OS_updateCausesReboot();
189 	QDateTime OS_lastUpdate();
190 	QString OS_lastUpdateResults();
191 	// = System Power =
192 	bool OS_canReboot();
193 	void OS_startReboot();
194 	bool OS_canShutdown();
195 	void OS_startShutdown();
196 	bool OS_canSuspend();
197 	void OS_startSuspend();
198 	// = Screen Brightness =
199 	bool OS_brightnessSupported();
200 	int OS_brightness();
201 	bool OS_setBrightness(int);
202 	// = System Status Monitoring
203 	bool OS_cpuSupported();
204 	QList<int> OS_cpuPercentage();
205 	QStringList OS_cpuTemperatures();
206 	bool OS_memorySupported();
207 	int OS_memoryUsedPercentage();
208 	QString OS_memoryTotal();
209 	QStringList OS_diskIO();
210 	bool OS_diskSupported();
211 	int OS_fileSystemPercentage(QString dir);
212 	QString OS_fileSystemCapacity(QString dir);
213 
214 private slots:
215 	// ================
216 	// SEMI-VIRTUAL FUNCTIONS - NEED TO BE DEFINED IN THE OS-SPECIFIC FILES
217 	// ================
218 
219 	//FileSystemWatcher slots
220 	void watcherFileChanged(QString);
221 	void watcherDirChanged(QString);
222 	//IO Device slots
223 	void iodeviceReadyRead();
224 	void iodeviceAboutToClose();
225 	//NetworkAccessManager slots
226 	void netRequestFinished(QNetworkReply*);
227 	void netSslErrors(QNetworkReply*, const QList<QSslError>&);
228 	//Timer slots
229 	void NetworkTimerUpdate();
230 	void BatteryTimerUpdate();
231 	void UpdateTimerUpdate();
232 	void BrightnessTimerUpdate();
233 	void VolumeTimerUpdate();
234 	void CpuTimerUpdate();
235 	void MemTimerUpdate();
236 	void DiskTimerUpdate();
237 
238 signals:
239 	void batteryChanged();
240 	void volumeChanged();
241 	void networkStatusChanged();
242 	void mediaShortcutsChanged();
243 	void updateStatusChanged();
244 	void powerAvailableChanged();
245 	void brightnessChanged();
246 
247 	//Internal alert signals
248 	void BatteryFullAlert();
249 	void BatteryEmptyAlert();
250 
251 private:
252 	//Internal persistant data storage, OS-specific usage implementation
253 	QHash< QString, QVariant> INFO;
254 	bool _started;
255 
256 	// ============
257 	// Internal possibilities for watching the system (OS-Specific usage/implementation)
258 	// ============
259 	//File System Watcher
260 	QFileSystemWatcher *watcher;
261 	//IO Device (QLocalSocket, QTcpConnection, QFile, etc)
262 	QIODevice *iodevice;
263 	//Network Access Manager (check network connectivity, etc)
264 	QNetworkAccessManager *netman;
265 	//Timer for regular probes/updates
266 	QTimer *networkTimer, *batteryTimer, *updateTimer, *brightnessTimer, *volumeTimer, *cpuTimer, *memTimer, *diskTimer;
267 
268 	// Internal implifications for connecting the various watcher objects to their respective slots
269 	// (OS-agnostic - defined in the "OSInterface_private.cpp" file)
270 	void connectWatcher(); //setup the internal connections *only*
271 	void connectIodevice(); //setup the internal connections *only*
272 	void connectNetman(); //setup the internal connections *only*
273 
274 	//Internal simplification routines
275 	bool verifyAppOrBin(QString chk);
276 	QString runProcess(int &retcode, QString command, QStringList arguments, QString workdir = "", QStringList env = QStringList());
277 	int runCmd(QString command, QStringList args = QStringList());
278 	QStringList getCmdOutput(QString command, QStringList args = QStringList());
279 	bool findInDirectory(QString file, QString dirpath, bool recursive=true);
280 	QString readFile(QString path);
281 
282 	// External Media Management (if system uses *.desktop shortcuts only)
283 	void setupMediaWatcher();
284 	bool handleMediaDirChange(QString dir); //returns true if directory was handled
285 	QStringList autoHandledMediaFiles();
286 
287 	// Timer-based setups
288 	void setupNetworkManager(int update_ms, int delay_ms);
289 	void setupBatteryMonitor(int update_ms, int delay_ms);
290 	void setupUpdateMonitor(int update_ms, int delay_ms);
291 	void setupBrightnessMonitor(int update_ms, int delay_ms);
292 	void setupVolumeMonitor(int update_ms, int delay_ms);
293 	void setupCpuMonitor(int update_ms, int delay_ms);
294 	void setupMemoryMonitor(int update_ms, int delay_ms);
295 	void setupDiskMonitor(int update_ms, int delay_ms);
296 
297 	// Timer-based monitor update routines (NOTE: these are all run in a separate thread!!)
298 	void syncNetworkInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
299 	void syncBatteryInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
300 	void syncUpdateInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
301 	void syncBrightnessInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
302 	void syncVolumeInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
303 	void syncCpuInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
304 	void syncMemoryInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
305 	void syncDiskInfo(OSInterface *os, QHash<QString, QVariant> *hash, QTimer *timer);
306 
307 public:
308 	OSInterface(QObject *parent = 0);
309 	~OSInterface();
310 
311 	static OSInterface* instance(); //Get the currently-active instance of this class (or make a new one)
312 	static void RegisterType(); //Register this object for QML access
313 };
314 #endif
315