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