RingD.h 15 KB
Newer Older
1
/**************************************************************************
atraczyk's avatar
atraczyk committed
2
* Copyright (C) 2016 by Savoir-faire Linux                                *
3 4
* Author: Jger Nicolas <nicolas.jager@savoirfairelinux.com>              *
* Author: Traczyk Andreas <traczyk.andreas@savoirfairelinux.com>          *
atraczyk's avatar
atraczyk committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18
*                                                                         *
* This program is free software; you can redistribute it and/or modify    *
* it under the terms of the GNU General Public License as published by    *
* the Free Software Foundation; either version 3 of the License, or       *
* (at your option) any later version.                                     *
*                                                                         *
* This program is distributed in the hope that it will be useful,         *
* but WITHOUT ANY WARRANTY; without even the implied warranty of          *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
* GNU General Public License for more details.                            *
*                                                                         *
* You should have received a copy of the GNU General Public License       *
* along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
**************************************************************************/
19
#include <dring.h>
atraczyk's avatar
atraczyk committed
20

atraczyk's avatar
atraczyk committed
21
#include "Ringtone.h"
22
#include "Utils.h"
atraczyk's avatar
atraczyk committed
23

atraczyk's avatar
atraczyk committed
24 25
using namespace concurrency;

atraczyk's avatar
atraczyk committed
26 27
using namespace Windows::UI::Notifications;
using namespace Windows::Data::Xml::Dom;
28
using namespace Windows::UI::ViewManagement;
atraczyk's avatar
atraczyk committed
29

atraczyk's avatar
atraczyk committed
30 31
namespace RingClientUWP
{
atraczyk's avatar
atraczyk committed
32

33
public enum class StartingStatus { NORMAL, REGISTERING_ON_THIS_PC, REGISTERING_THIS_DEVICE };
atraczyk's avatar
atraczyk committed
34

35
/* delegates */
atraczyk's avatar
atraczyk committed
36
delegate void IncomingCall(String^ accountId, String^ callId, String^ from);
Nicolas Jager's avatar
Nicolas Jager committed
37
delegate void StateChange(String^ callId, CallStatus state, int code);
38
delegate void IncomingAccountMessage(String^ accountId, String^ from, String^ payload);
39
delegate void CallPlaced(String^ callId);
40
delegate void IncomingMessage(String^ callId, String^ payload);
41
delegate void DevicesListRefreshed(Map<String^, String^>^ deviceMap);
42
delegate void ExportOnRingEnded(String^ accountId, String^ pin);
43
delegate void SummonWizard();
44
delegate void AccountUpdated(Account^ account);
45
delegate void IncomingVideoMuted(String^ callId, bool state);
46
delegate void RegisteredNameFound(LookupStatus status, const std::string& accountId, const std::string& address, const std::string& name);
47
delegate void FinishCaptureDeviceEnumeration();
48
delegate void RegistrationStateErrorGeneric(const std::string& accountId);
49 50 51 52
delegate void RegistrationStateRegistered(const std::string& accountId);
delegate void RegistrationStateUnregistered(const std::string& accountId);
delegate void RegistrationStateTrying(const std::string& accountId);
delegate void SetOverlayStatusText(String^ statusText, String^ color);
53
delegate void CallsListRecieved(const std::vector<std::string>& callsList);
54
delegate void AudioMuted(const std::string& callId, bool state);
55
delegate void VideoMuted(const std::string& callId, bool state);
Nicolas Jager's avatar
Nicolas Jager committed
56
delegate void NameRegistred(bool status);
57
delegate void FullScreenToggled(bool state);
58 59 60 61 62
delegate void WindowResized(float width, float height);
delegate void NetworkChanged();
delegate void MessageDataLoaded();
delegate void UpdateSmartInfo(const std::map<std::string, std::string>& info);
delegate void MessageStatusUpdated(String^ messageId, int status);
Nicolas Jager's avatar
Nicolas Jager committed
63
delegate void VolatileDetailsChanged(const std::string& accountId, const std::map<std::string, std::string>& details);
64 65 66
delegate void NewBuddyNotification(const std::string& accountId, const std::string& uri, int status);
delegate void VCardUpdated(Contact^ owner);
delegate void ShareRequested();
67

68 69
using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>;
using namespace std::placeholders;
atraczyk's avatar
atraczyk committed
70 71 72 73 74

public ref class RingD sealed
{
public:
    /* properties */
75 76
    static property RingD^ instance {
        RingD^ get() {
atraczyk's avatar
atraczyk committed
77 78 79 80 81
            static RingD^ instance_ = ref new RingD();
            return instance_;
        }
    }

82 83
    property bool daemonInitialized {
        bool get() {
84 85 86 87
            return daemonInitialized_;
        }
    }

88 89
    property bool daemonRunning {
        bool get() {
atraczyk's avatar
atraczyk committed
90 91 92
            return daemonRunning_;
        }
    }
93

94 95 96 97 98 99 100 101 102 103
    property bool _hasInternet {
        bool get() {
            return hasInternet_;
        }
    }

    property bool isInWizard;

    property bool isFullScreen {
        bool get() {
104 105 106 107
            return ApplicationView::GetForCurrentView()->IsFullScreenMode;
        }
    }

108 109
    property bool isOnXBox {
        bool get() {
110 111 112 113 114 115
            auto dev = Utils::toString(Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily);
            std::transform(dev.begin(), dev.end(), dev.begin(), ::tolower);
            return !dev.compare("windows.xbox");
        }
    }

116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
    property bool isInBackground {
        bool get() {
            return isInBackground_;
        }
        void set(bool value) {
            isInBackground_ = value;
            connectivityChanged();
        }
    }

    property bool isInvisible {
        bool get() {
            return isInvisible_;
        }
        void set(bool value) {
            isInvisible_ = value;
        }
    }

    property Ringtone^ ringtone {
        Ringtone^ get() {
            return ringtone_;
        }
    }

    property MainPage^ mainPage {
        MainPage^ get() {
            auto frame = dynamic_cast<Windows::UI::Xaml::Controls::Frame^>(Window::Current->Content);
            return dynamic_cast<RingClientUWP::MainPage^>(frame->Content);
        }
    }

148
    property StartingStatus _startingStatus;
atraczyk's avatar
atraczyk committed
149

150 151 152 153
    property bool isCtrlPressed;
    property bool isShiftPressed;

    /* functions */
154
    void cancelOutGoingCall2(String^ callId); // marche
155 156
    void raiseWindowResized(float width, float height);
    void raiseShareRequested();
157

158 159 160 161 162 163 164 165 166
internal: // why this property has to be internal and not public ?
    property Vector<String^>^ _callIdsList
    {
        Vector<String^>^ get()
        {
            return callIdsList_;
        }
    }

167
    std::map<String^, std::function<void(String^ username)>> unpoppedToasts;
168

169 170
    using AccountDetails = std::map<std::string, std::string>;
    using AccountDetailsBlob = std::map<std::string, AccountDetails>;
atraczyk's avatar
atraczyk committed
171
    /* functions */
172
    std::string getLocalFolder();
173 174
    void registerCallbacks();
    void initDaemon(int flags);
atraczyk's avatar
atraczyk committed
175
    void startDaemon();
176 177
    void init();
    void deinit();
178 179 180
    AccountDetailsBlob getAllAccountDetails();
    void parseAccountDetails(const AccountDetailsBlob& allAccountDetails);
    void subscribeBuddies();
181
    void sendAccountTextMessage(String^ message);
182
    void sendSIPTextMessage(String^ message);
183
    void sendSIPTextMessageVCF(std::string callID, std::map<std::string, std::string> message);
Nicolas Jager's avatar
Nicolas Jager committed
184
    void createRINGAccount(String^ alias, String^ archivePassword, bool upnp, String^ registeredName = "");
185
    void createSIPAccount(String^ alias, String^ sipPassword, String^ sipHostname, String^ sipusername);
186 187
    void refuseIncommingCall(String^ call);
    void acceptIncommingCall(String^ call);
Nicolas Jager's avatar
Nicolas Jager committed
188
    void placeCall(Contact^ contact);
189 190
    void pauseCall(const std::string& callId);
    void unPauseCall(const std::string& callId);
191
    CallStatus translateCallStatus(String^ state);
192
    String^ getUserName();
193 194 195
    void startSmartInfo(int refresh);
    void stopSmartInfo();
    void handleIncomingMessage( const std::string& callId,
196 197 198
                                const std::string& accountId,
                                const std::string& from,
                                const std::map<std::string, std::string>& payloads);
199

200 201 202
    void toggleFullScreen();
    void setWindowedMode();
    void setFullScreenMode();
203 204
    void connectivityChanged();
    void onStateChange(Platform::String ^callId, RingClientUWP::CallStatus state, int code);
205
    void hangUpCall2(String^ callId);
206 207
    void pauseCall(String ^ callId);
    void unPauseCall(String ^ callId);
208
    void getKnownDevices(String^ accountId);
209
    void askToExportOnRing(String^ accountId, String^ password);
210
    void eraseCacheFolder();
211
    void updateAccount(String^ accountId);
212
    void deleteAccount(String^ accountId);
213
    void registerThisDevice(String^ pin, String^ archivePassword);
214 215 216
    void getCallsList();
    void killCall(String^ callId);
    void switchDebug();
217
    void muteVideo(String^ callId, bool muted);
218
    void muteAudio(const std::string& callId, bool muted);
219
    void subscribeBuddy(const std::string& accountId, const std::string& uri, bool flag);
Nicolas Jager's avatar
Nicolas Jager committed
220 221 222
    void registerName(String^ accountId, String^ password, String^ username);
    void registerName_new(const std::string& accountId, const std::string& password, const std::string& username);
    std::map<std::string, std::string> getVolatileAccountDetails(Account^ account);
223 224
    void lookUpName(const std::string& accountId, String^ name);
    void lookUpAddress(const std::string& accountId, String^ address);
Nicolas Jager's avatar
Nicolas Jager committed
225
    std::string registeredName(Account^ account);
226 227 228 229 230 231 232 233 234 235 236 237 238 239
    void removeContact(const std::string & accountId, const std::string& uri);
    void sendContactRequest(const std::string& accountId, const std::string& uri, const std::string& payload);
    void raiseMessageDataLoaded();
    void raiseVCardUpdated(Contact^ contact);
    void revokeDevice(const std::string& accountId, const std::string& password, const std::string& deviceId);
    void showLoadingOverlay(String^ text, String^ color);
    void hideLoadingOverlay(String^ text, String^ color, int delayInMilliseconds = 2000);
    void OnaccountAdded();
    void OnaccountUpdated();
    void OnaccountDeleted();

    void ShowCallToast(bool background, String^ callId, String^ name = nullptr);
    void ShowIMToast(bool background, String^ from, String^ payload, String^ name = nullptr);
    void HideToast(ToastNotification^ toast);
atraczyk's avatar
atraczyk committed
240 241

    /* TODO : move members */
242
    String ^ currentCallId; // to save ongoing call id during visibility change
atraczyk's avatar
atraczyk committed
243 244 245 246

    /* events */
    event IncomingCall^ incomingCall;
    event StateChange^ stateChange;
247
    event IncomingAccountMessage^ incomingAccountMessage;
248
    event IncomingMessage^ incomingMessage;
249
    event CallPlaced^ callPlaced;
250 251
    event DevicesListRefreshed^ devicesListRefreshed;
    event ExportOnRingEnded^ exportOnRingEnded;
252
    event SummonWizard^ summonWizard;
253
    event AccountUpdated^ accountUpdated;
254
    event IncomingVideoMuted^ incomingVideoMuted;
Nicolas Jager's avatar
Nicolas Jager committed
255
    event RegisteredNameFound^ registeredNameFound;
256
    event FinishCaptureDeviceEnumeration^ finishCaptureDeviceEnumeration;
257 258
    event RegistrationStateErrorGeneric^ registrationStateErrorGeneric;
    event RegistrationStateRegistered^ registrationStateRegistered;
259 260 261
    event RegistrationStateUnregistered^ registrationStateUnregistered;
    event RegistrationStateTrying^ registrationStateTrying;
    event SetOverlayStatusText^ setOverlayStatusText;
262
    event CallsListRecieved^ callsListRecieved; // est implemente a la base pour regler le probleme du boutton d'appel qui est present lorsqu'un appel est en cours, mais il n'est pas utilise. Voir si ca peut servir a autre chose
263
    event AudioMuted^ audioMuted;
264
    event VideoMuted^ videoMuted;
Nicolas Jager's avatar
Nicolas Jager committed
265
    event NameRegistred^ nameRegistred;
266 267
    event FullScreenToggled^ fullScreenToggled;
    event WindowResized^ windowResized;
268 269 270 271
    event NetworkChanged^ networkChanged;
    event MessageDataLoaded^ messageDataLoaded;
    event UpdateSmartInfo^ updateSmartInfo;
    event MessageStatusUpdated^ messageStatusUpdated;
Nicolas Jager's avatar
Nicolas Jager committed
272
    event VolatileDetailsChanged^ volatileDetailsChanged;
273 274 275
    event NewBuddyNotification^ newBuddyNotification;
    event VCardUpdated^ vCardUpdated;
    event ShareRequested^ shareRequested;
atraczyk's avatar
atraczyk committed
276 277 278

private:
    /* sub classes */
279 280 281
    enum class Request {
        None,
        AddRingAccount,
282 283
        AddSIPAccount,
        RefuseIncommingCall,
Nicolas Jager's avatar
Nicolas Jager committed
284
        AcceptIncommingCall,
285
        CancelOutGoingCall,
286
        PlaceCall,
287
        HangUpCall,
288 289
        PauseCall,
        UnPauseCall,
290
        RegisterDevice,
291
        GetKnownDevices,
292
        ExportOnRing,
293
        UpdateAccount,
294 295 296 297
        DeleteAccount,
        GetCallsList,
        KillCall,
        switchDebug,
Nicolas Jager's avatar
Nicolas Jager committed
298
        MuteVideo,
299
        MuteAudio,
Nicolas Jager's avatar
Nicolas Jager committed
300 301
        LookUpName,
        LookUpAddress,
302 303 304 305 306 307 308 309
        SendContactRequest,
        AcceptContactRequest,
        DiscardContactRequest,
        RegisterName,
        RemoveContact,
        RevokeDevice,
        SubscribeBuddy,
        SendSIPMessage
310
    };
311 312 313

    Vector<String^>^ callIdsList_;

atraczyk's avatar
atraczyk committed
314 315
    ref class Task
    {
316
    internal:
317 318 319
        Task(Request r) {
            request = r;
        }
320
        Task(Request r, String^ c) {
321 322 323
            request = r;
            _callId = c;
        }
324 325 326 327 328
        Task(Request r, String^ p, String^ P) {
            request = r;
            _pin = p;
            _password = P;
        }
atraczyk's avatar
atraczyk committed
329 330
    public:
        property Request request;
331
        property String^ _alias;
332
        property String^ _callId;
333
        property String^ _pin;
334
        property String^ _password; // refacto : is it safe ? are tasks destroy quickly after been used ?
335
        property String^ _accountId;
336 337 338 339
        property bool _upnp;
        property String^ _sipPassword;
        property String^ _sipHostname;
        property String^ _sipUsername;
340
        property bool _muted;
Nicolas Jager's avatar
Nicolas Jager committed
341 342 343 344 345
        property String^ _registeredName; // public username
        property String^ _address; // ringId

    internal:
        std::string _accountId_new;
346 347
        std::string _payload;
        std::map<std::string, std::string> _payload2;
Nicolas Jager's avatar
Nicolas Jager committed
348 349
        std::string _password_new;
        std::string _publicUsername_new;
350 351
        std::string _callid_new;
        std::string _ringId_new;
352
        std::string _deviceId;
353
        bool _audioMuted_new;
atraczyk's avatar
atraczyk committed
354 355 356 357
    };

    /* functions */
    RingD(); // singleton
358

atraczyk's avatar
atraczyk committed
359
    void dequeueTasks();
360 361
    void InternetConnectionChanged(Platform::Object^ sender);
    //CallStatus translateCallStatus(String^ state);
atraczyk's avatar
atraczyk committed
362 363

    /* members */
364 365
    Windows::UI::Core::CoreDispatcher^ dispatcher;

366 367 368 369 370 371 372
    bool hasInternet_;
    bool isAddingDevice     = false;
    bool isAddingAccount    = false;
    bool isUpdatingAccount  = false;
    bool isDeletingAccount  = false;
    bool isInBackground_    = false;
    bool isInvisible_       = false;
373
    bool daemonInitialized_ = false;
374 375 376 377 378 379
    bool daemonRunning_     = false;
    bool editModeOn_        = false;
    bool debugModeOn_       = true;
    bool callToastPopped_   = false;

    std::string localFolder_;
atraczyk's avatar
atraczyk committed
380
    std::queue<Task^> tasksList_;
381
    StartingStatus startingStatus_ = StartingStatus::NORMAL;
atraczyk's avatar
atraczyk committed
382
    Ringtone^ ringtone_;
383

384 385 386 387
    ToastNotification^ toastText;
    ToastNotification^ toastCall;
    Windows::UI::Notifications::ToastNotifier^ toaster;

388
    std::map<std::string, SharedCallback> callHandlers;
389 390 391
    std::map<std::string, SharedCallback> configurationHandlers;
    std::map<std::string, SharedCallback> presenceHandlers;
    std::map<std::string, SharedCallback> videoHandlers;
atraczyk's avatar
atraczyk committed
392
};
Nicolas Jager's avatar
Nicolas Jager committed
393
}