File indexing completed on 2025-02-23 04:28:48
0001 /**************************************************************************************** 0002 * Copyright (c) 2008 Casey Link <unnamedrambler@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #ifndef MP3TUNESHARMONYDAEMON_H 0018 #define MP3TUNESHARMONYDAEMON_H 0019 0020 #include "Mp3tunesHarmonyDownload.h" 0021 #include "Mp3tunesHarmonyClient.h" 0022 0023 #include <QCoreApplication> 0024 #include <QObject> 0025 #include <QString> 0026 0027 extern "C" { 0028 // Get libmp3tunes declarations 0029 #include "../libmp3tunes/harmony.h" 0030 #include "../libmp3tunes/locker.h" 0031 #include <glib.h> 0032 #include <sys/statvfs.h> 0033 #include <errno.h> 0034 #include <stdio.h> 0035 #include <string.h> 0036 } 0037 0038 /** 0039 * A daemon that receives notifications from mp3tunes' 0040 * servers about new/changed tracks that can be synced. 0041 * 0042 * Because this classes implements libmp3tunes which uses 0043 * GLIB's c-style callbacks, all the callbacks must be static. 0044 * This requires some black magic on my part to keep the OO 0045 * facade intact. The solution is a global variable: theDaemon 0046 * declared after this class. Your code must \#define DEFINE_HARMONY 0047 * and instantiate a new Mp3tunesHarmonyDaemon for theDaemon. 0048 * @author Casey Link <unnamedrambler@gmail.com> 0049 */ 0050 class Mp3tunesHarmonyDaemon : public QCoreApplication 0051 { 0052 Q_OBJECT 0053 Q_CLASSINFO("D-Bus Interface", "org.kde.amarok.Mp3tunesHarmonyDaemon") 0054 0055 public: 0056 /** 0057 * For the first time run, before we have an email and pin to authenticate 0058 */ 0059 Mp3tunesHarmonyDaemon( QString identifier, int argc, char *argv[] ); 0060 /** 0061 * For subsequent logins 0062 */ 0063 Mp3tunesHarmonyDaemon( QString identifier, QString email, QString pin, int argc, char *argv[] ); 0064 ~Mp3tunesHarmonyDaemon(); 0065 0066 /** 0067 * Stats the daemon by initiating the connection Harmony connection. 0068 */ 0069 int init(); 0070 0071 /** 0072 * Sets the client type that the daemon will send signals to. 0073 */ 0074 void setClient( Mp3tunesHarmonyClient *client ); 0075 0076 /** 0077 * The possible states the daemon can be in. 0078 * Before init() it is DISCONNECTED 0079 */ 0080 enum HarmonyState { 0081 DISCONNECTED, 0082 CONNECTED, 0083 WAITING_FOR_PIN, 0084 WAITING_FOR_EMAIL 0085 }; 0086 0087 /* 0088 * Used by the static callbacks 0089 * DO NOT CALL THESE METHODS 0090 */ 0091 void setState( HarmonyState state ); 0092 void setError( const QString &error ); 0093 0094 /* 0095 * Used by the static callbacks 0096 * DO NOT CALL THESE METHODS 0097 */ 0098 void emitError(); 0099 void emitWaitingForEmail( const QString &pin ); 0100 void emitWaitingForPin(); 0101 void emitConnected(); 0102 void emitDisconnected(); 0103 void emitDownloadReady( const Mp3tunesHarmonyDownload &download ); 0104 void emitDownloadPending( const Mp3tunesHarmonyDownload &download ); 0105 0106 Q_SIGNALS: 0107 /* The actual signals that get emitted */ 0108 void waitingForEmail( const QString &pin ); 0109 void waitingForPin(); 0110 void connected(); 0111 void disconnected(); 0112 void errorSignal( const QString &error ); 0113 0114 /* signalDownloadReady 0115 * this signal is emitted when a track is ready to be downloaded. 0116 */ 0117 void downloadReady( const Mp3tunesHarmonyDownload &download ); 0118 0119 /* signalDownloadPending 0120 * this signal is emitted as soon as a download message is received. 0121 * it may or may not be ready. the library sends this signal before 0122 * adding the download to its own queue 0123 */ 0124 void downloadPending( const Mp3tunesHarmonyDownload &download ); 0125 public Q_SLOTS: 0126 /** 0127 * Returns the pin 0128 */ 0129 QString pin() const; 0130 0131 /** 0132 * Returns the Harmony Email used for authentication 0133 */ 0134 QString email() const; 0135 0136 /** 0137 * Returns the latest error message. 0138 */ 0139 QString error() const; 0140 0141 /** 0142 * Determines if the daemon is currently connected to the harmony servers. 0143 * @return true if the daemon is connected. 0144 * false if the daemon is not connected. 0145 */ 0146 bool daemonConnected(); 0147 0148 /** 0149 * Disconnects the daemon if it is connected. 0150 * @return true if the daemon is disconnected OR if the daemon was disconnected 0151 * false if the breaking the connect failed 0152 */ 0153 bool breakConnection(); 0154 0155 QString makeConnection(); 0156 0157 private: 0158 0159 /* Error signal handler. 0160 * 0161 * This signal is emitted whenever there is a user fixable error from inside the 0162 * library. Most of these errors are from inside of the Jabber library. 0163 * 0164 * Whenever this signal handler is called, harmony->error will be set to a valid 0165 * GError pointer. The message field of that structure will contain the error 0166 * and should be displayed to the user and the connection reset by calling 0167 * mp3tunes_harmony_disconnect and a reconnection user initiated. 0168 */ 0169 static void signalErrorHandler( MP3tunesHarmony* harmony, gpointer null_pointer ); 0170 0171 /* State change signal handler. 0172 * 0173 * This signal is emitted whenever the state of the connection changes during 0174 * the Harmony authentication process. The state variable will be set to one of 0175 * the values of harmony_state_t with the following meanings. 0176 * 0177 * MP3TUNES_HARMONY_STATE_DISCONNECTED: 0178 * The connection to the server has been disconnected. Occurs a couple of 0179 * times during the authentication process. Nothing to act on unless was 0180 * already in the CONNECTED state. 0181 * 0182 * MP3TUNES_HARMONY_STATE_CONNECTED: 0183 * The connection completed successfully. All to be done from here is to 0184 * associate the download handler if needed and wait for download messages. 0185 * 0186 * MP3TUNES_HARMONY_STATE_WAITING_FOR_PIN: 0187 * The client has authenticated and is waiting for the response to a 0188 * harmonyPin message. Unless there is a problem with the Conductor this 0189 * state should be left almost immediately and moved back into disconnected 0190 * before going to WAITING_FOR_EMAIL. Useful for having a progress message 0191 * during authentication. 0192 * 0193 * MP3TUNES_HARMONY_STATE_WAITING_FOR_EMAIL: 0194 * The client has authenticated and is waiting for a response to the 0195 * harmonyEmail message. In this state, the action to take is to display to 0196 * the user the pin, found by calling mp3tunes_harmony_get_pin, and request 0197 * for them to log into mp3tunes.com and have them add the pin to their 0198 * devices tab. Upon receiving the reply to this you will be authenticated. 0199 */ 0200 static void signalStateChangeHandler( MP3tunesHarmony* harmony, guint32 state, gpointer null_pointer ); 0201 0202 0203 /* signalDownloadReadyHandler 0204 * this signal is emitted when a track is ready to be downloaded. 0205 */ 0206 static void signalDownloadReadyHandler( MP3tunesHarmony* harmony, gpointer void_mp3tunes_harmony_download, gpointer null_pointer ); 0207 0208 /* signalDownloadPendingHandler 0209 * this signal is emitted as soon as a download message is received. 0210 * it may or may not be ready. the library sends this signal before 0211 * adding the download to its own queue 0212 */ 0213 static void signalDownloadPendingHandler( MP3tunesHarmony* harmony, gpointer void_mp3tunes_harmony_download, gpointer null_pointer ); 0214 0215 /** 0216 * Converts a QString into a char* 0217 */ 0218 char* convertToChar( const QString &source ) const; 0219 /** 0220 * Inits the D-Dbus interface. 0221 */ 0222 bool allAboardTheDBus(); 0223 0224 MP3tunesHarmony * m_harmony; 0225 QString m_identifier; // the initial identifier used for authentication 0226 QString m_email; //used for repeat authentication 0227 QString m_pin; //used for repeat authentication 0228 GError *m_gerr; // master GError 0229 0230 QString m_error; // error message to display to user 0231 bool m_started; // true if the connection has been established 0232 bool m_inited; // true if the daemon is ready to connect 0233 HarmonyState m_state; //current state of the harmony daemon 0234 Mp3tunesHarmonyClient *m_client; // the daemon client 0235 }; 0236 0237 0238 /* 0239 * The global variable used by the static callbacks. 0240 * G_CALLBACK() requires a pointer to a member function, 0241 * and because this is c++ that member function must be static. 0242 * However, since I want to edit non-static members in those 0243 * callbacks I created a workaround by defining a global variable, 0244 * 'theDaemon', which is an instantiation of a Mp3tunesHarmonyDaemon 0245 * and call mutators on it from the static callbacks. 0246 */ 0247 #ifdef DEFINE_HARMONY 0248 #define HARMONY 0249 #else 0250 #define HARMONY extern 0251 #endif 0252 0253 HARMONY Mp3tunesHarmonyDaemon* theDaemon; 0254 0255 #endif 0256