Ring Daemon
Loading...
Searching...
No Matches
manager.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
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 3 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, see <https://www.gnu.org/licenses/>.
16 */
17
18#pragma once
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include "account_factory.h"
25#include "call_factory.h"
26#include "preferences.h"
28#include "gittransport.h"
29
30#include <dhtnet/certstore.h>
31#include <asio/post.hpp>
32
33#include <algorithm>
34#include <atomic>
35#include <functional>
36#include <map>
37#include <memory>
38#include <string>
39#include <vector>
40
41namespace asio {
42class io_context;
43}
44
45namespace dhtnet {
46class ChannelSocket;
47class IceTransportFactory;
48} // namespace dhtnet
49
50namespace jami {
51namespace video {
52class SinkClient;
53class VideoGenerator;
54} // namespace video
55class RingBufferPool;
56struct VideoManager;
57class Conference;
58class AudioLoop;
59class JamiAccount;
60class SIPVoIPLink;
61class JamiPluginManager;
62
64// TODO LIBJAMI_PUBLIC only if tests
66{
67private:
68 std::mutex randMutex_;
69 std::mt19937_64 rand_;
70
71public:
72 // TODO LIBJAMI_PUBLIC only if tests
73 static LIBJAMI_TEST_EXPORT Manager& instance();
74
75 void setAutoAnswer(bool enable);
76
81
86
91
92#ifdef ENABLE_PLUGIN
96 PluginPreferences pluginPreferences;
97#endif
98
99#ifdef ENABLE_VIDEO
103 VideoPreferences videoPreferences;
104#endif
105
106 // Manager should not be accessed until initialized.
107 // FIXME this is an evil hack!
108 static std::atomic_bool initialized;
109
110#if TARGET_OS_IOS
111 static bool isIOSExtension;
112#endif
113
114 static bool syncOnRegister;
115
116 static bool autoLoad;
117
122 void init(const std::filesystem::path& config_file, libjami::InitFlag flags);
123
124 /*
125 * Terminate all threads and exit DBus loop
126 */
127 void finish() noexcept;
128
129 void monitor(bool continuous);
130
131 std::vector<std::map<std::string, std::string>> getConnectionList(const std::string& accountId,
132 const std::string& conversationId);
133 std::vector<std::map<std::string, std::string>> getChannelList(const std::string& accountId,
134 const std::string& connectionId);
135
141 std::shared_ptr<AudioLayer> getAudioDriver();
142
143 inline std::unique_ptr<AudioDeviceGuard> startAudioStream(AudioDeviceType stream)
144 {
145 return std::make_unique<AudioDeviceGuard>(*this, stream);
146 }
147
155 inline std::unique_ptr<AudioDeviceGuard> startCaptureStream(const std::string& captureDevice)
156 {
157 return std::make_unique<AudioDeviceGuard>(*this, captureDevice);
158 }
159
168 std::string outgoingCall(const std::string& accountId,
169 const std::string& callee,
170 const std::vector<libjami::MediaMap>& mediaList = {});
171
177 bool acceptCall(const std::string& accountId,
178 const std::string& callId,
179 const std::vector<libjami::MediaMap>& mediaList = {});
180 bool acceptCall(Call& call, const std::vector<libjami::MediaMap>& mediaList = {});
181
187 void incomingCall(const std::string& accountId, Call& call);
188
195 bool hangupCall(const std::string& accountId, const std::string& callId);
196
202 bool hangupConference(const std::string& accountId, const std::string& confId);
203
210 bool holdCall(const std::string& accountId, const std::string& callId);
211
218 bool resumeCall(const std::string& accountId, const std::string& callId);
219
226 bool transferCall(const std::string& accountId, const std::string& id, const std::string& to);
227
231 void transferSucceeded();
232
236 void transferFailed();
237
243 bool refuseCall(const std::string& accountId, const std::string& id);
244
249 bool holdConference(const std::string& accountId, const std::string& confId);
250
255 bool resumeConference(const std::string& accountId, const std::string& confId);
256
262 bool addSubCall(const std::string& accountId,
263 const std::string& callId,
264 const std::string& account2Id,
265 const std::string& confId);
266 bool addSubCall(Call& call, Conference& conference);
267 void bindCallToConference(Call& call, Conference& conf);
268
273 bool addMainParticipant(const std::string& accountId, const std::string& confId);
274
280 bool joinParticipant(const std::string& accountId,
281 const std::string& callId1,
282 const std::string& account2Id,
283 const std::string& callId2,
284 bool attached = true);
285
290 void createConfFromParticipantList(const std::string& accountId, const std::vector<std::string>&);
291
297 bool detachParticipant(const std::string& callId);
298
303 bool detachHost(const std::shared_ptr<Conference>& conf = {});
304
309 void removeParticipant(Call& call);
310
314 bool joinConference(const std::string& accountId,
315 const std::string& confId1,
316 const std::string& account2Id,
317 const std::string& confId2);
318
319 void addAudio(Call& call);
320
321 void removeAudio(Call& call);
322
326 void saveConfig();
327 void saveConfig(const std::shared_ptr<Account>& acc);
328
332 void playTone();
333
337 void playToneWithMessage();
338
342 void stopTone();
343
349 void peerAnsweredCall(Call& call);
350
356 void peerRingingCall(Call& call);
357
362 void peerHungupCall(Call& call);
363
370 void incomingMessage(const std::string& accountId,
371 const std::string& callId,
372 const std::string& from,
373 const std::map<std::string, std::string>& messages);
374
382 void sendCallTextMessage(const std::string& accountId,
383 const std::string& callID,
384 const std::map<std::string, std::string>& messages,
385 const std::string& from,
386 bool isMixed);
387
395 void sendRegister(const std::string& accountId, bool enable);
396
397 uint64_t sendTextMessage(const std::string& accountID,
398 const std::string& to,
399 const std::map<std::string, std::string>& payloads,
400 bool fromPlugin = false,
401 bool onlyConnected = false);
402
403 int getMessageStatus(uint64_t id) const;
404 int getMessageStatus(const std::string& accountID, uint64_t id) const;
405
410 std::vector<std::string> getAccountList() const;
411
415 void setAccountsOrder(const std::string& order);
416
422 std::map<std::string, std::string> getAccountDetails(const std::string& accountID) const;
423
429 std::map<std::string, std::string> getVolatileAccountDetails(const std::string& accountID) const;
430
435 std::vector<std::string> getCallList() const;
436
444 void setAccountDetails(const std::string& accountID, const std::map<std::string, std::string>& details);
445
446 void setAccountActive(const std::string& accountID, bool active, bool shutdownConnections);
447 void loadAccountAndConversation(const std::string& accountId, bool loadAll, const std::string& convId);
448
449 std::mt19937_64 getSeededRandomEngine();
450
455 std::string getNewAccountId();
456
463 std::string addAccount(const std::map<std::string, std::string>& details, const std::string& accountId = {});
464
465 void markAccountPending(const std::string& accountId);
466 void markAccountReady(const std::string& accountId);
467
474 void removeAccount(const std::string& accountID, bool flush = false);
475
476 void removeAccounts();
477
482 void setAudioPlugin(const std::string& audioPlugin);
483
489 void setAudioDevice(int index, AudioDeviceType streamType);
490
495 std::vector<std::string> getAudioOutputDeviceList();
496
501 std::vector<std::string> getAudioInputDeviceList();
502
507 std::vector<std::string> getCurrentAudioDevicesIndex();
508
514 int getAudioInputDeviceIndex(const std::string& name);
515 int getAudioOutputDeviceIndex(const std::string& name);
516
521 std::string getCurrentAudioOutputPlugin() const;
522
527 std::string getNoiseSuppressState() const;
528
533 void setNoiseSuppressState(const std::string& state);
534
540 std::string getEchoCancellationState() const;
541
546 void setEchoCancellationState(const std::string& state);
547
554
559 void setVoiceActivityDetectionState(bool state);
560
561 bool isAGCEnabled() const;
562 void setAGCState(bool enabled);
563
567 bool getIsAlwaysRecording() const;
568
573 void setIsAlwaysRecording(bool isAlwaysRec);
574
581 bool toggleRecordingCall(const std::string& accountId, const std::string& id);
582
587 bool startRecordedFilePlayback(const std::string&);
588
589 void recordingPlaybackSeek(const double value);
590
595
600 void setHistoryLimit(int days);
601
606 int getHistoryLimit() const;
607
613 void setRingingTimeout(std::chrono::seconds timeout);
614
620 std::chrono::seconds getRingingTimeout() const;
621
628 std::string getAudioManager() const;
629
634 bool setAudioManager(const std::string& api);
635
640 AudioFormat hardwareAudioFormatChanged(AudioFormat format);
641
648 AudioFormat audioFormatUsed(AudioFormat format);
649
654 void ringback();
655
659 void playRingtone(const std::string& accountID);
660
664 void congestion();
665
670 void playDtmf(char code);
671
675 void callBusy(Call& call);
676
680 void callFailure(Call& call);
681
686 std::shared_ptr<AudioLoop> getTelephoneTone();
687
692 std::shared_ptr<AudioLoop> getTelephoneFile();
693
698 bool incomingCallsWaiting();
699
704 std::shared_ptr<Call> getCurrentCall() const;
705
710 const std::string& getCurrentCallId() const;
711
717 bool isCurrentCall(const Call& call) const;
718
723 std::vector<std::string_view> loadAccountOrder() const;
724
728 int loadAccountMap(const YAML::Node& node);
729
734 std::shared_ptr<Call> getCallFromCallID(const std::string& callID) const;
735
739 RingBufferPool& getRingBufferPool();
740
745 bool hasCurrentCall() const;
746
752 template<class T = Account>
753 inline std::shared_ptr<T> getAccount(std::string_view accountId) const
754 {
755 return accountFactory.getAccount<T>(accountId);
756 }
757
762 template<class T = Account>
763 std::vector<std::shared_ptr<T>> getAllAccounts() const
764 {
765 const auto& account_order = loadAccountOrder();
766 const auto& all_accounts = accountFactory.getAllAccounts<T>();
767 std::vector<std::shared_ptr<T>> accountList;
768 accountList.reserve(all_accounts.size());
769 for (const auto& id : account_order) {
770 if (auto acc = accountFactory.getAccount<T>(id))
771 accountList.emplace_back(std::move(acc));
772 }
773 for (auto& account : all_accounts) {
774 if (std::find(accountList.begin(), accountList.end(), account) == accountList.end())
775 accountList.emplace_back(std::move(account));
776 }
777 return accountList;
778 }
779
780 template<class T = Account>
781 std::size_t accountCount() const
782 {
783 return accountFactory.accountCount<T>();
784 }
785
786 template<class T>
787 inline std::shared_ptr<T> findAccount(const std::function<bool(const std::shared_ptr<T>&)>& pred)
788 {
789 for (const auto& account : getAllAccounts<T>()) {
790 if (pred(account))
791 return account;
792 }
793 return {};
794 }
795
796 // only used by test framework
797 bool hasAccount(const std::string& accountID);
798
802 void registerAccounts();
803
807 void registerAccount(const std::string& accountID, const std::string& convId = {});
808
812 void unregisterAccounts();
813
822 std::shared_ptr<Call> newOutgoingCall(std::string_view toUrl,
823 const std::string& accountId,
824 const std::vector<libjami::MediaMap>& mediaList);
825
827
828 const std::shared_ptr<dhtnet::IceTransportFactory>& getIceTransportFactory();
829
830 std::shared_ptr<asio::io_context> ioContext() const;
831 std::shared_ptr<dhtnet::upnp::UPnPContext> upnpContext() const;
832
833 std::map<std::string, std::string> getNearbyPeers(const std::string& accountID);
834
835#ifdef ENABLE_VIDEO
844 std::shared_ptr<video::SinkClient> createSinkClient(const std::string& id = "", bool mixer = false);
845
854 void createSinkClients(const std::string& callId,
855 const ConfInfo& infos,
856 const std::vector<std::shared_ptr<video::VideoFrameActiveWriter>>& videoStreams,
857 std::map<std::string, std::shared_ptr<video::SinkClient>>& sinksMap,
858 const std::string& accountId = "");
859
866 std::shared_ptr<video::SinkClient> getSinkClient(const std::string& id);
867
868#endif // ENABLE_VIDEO
869 VideoManager* getVideoManager() const;
870
871 unsigned dhtLogLevel {0}; // default = disable
872 unsigned dhtnetLogLevel {0}; // default = disable
874
875 std::vector<libjami::Message> getLastMessages(const std::string& accountID, const uint64_t& base_timestamp);
876
877 SIPVoIPLink& sipVoIPLink() const;
878#ifdef ENABLE_PLUGIN
879 JamiPluginManager& getJamiPluginManager() const;
880#endif
888 std::shared_ptr<dhtnet::ChannelSocket> gitSocket(std::string_view accountId,
889 std::string_view deviceId,
890 std::string_view conversationId);
891
892 void setDefaultModerator(const std::string& accountID, const std::string& peerURI, bool state);
893 std::vector<std::string> getDefaultModerators(const std::string& accountID);
894 void enableLocalModerators(const std::string& accountID, bool state);
895 bool isLocalModeratorsEnabled(const std::string& accountID);
896 void setAllModerators(const std::string& accountID, bool allModerators);
897 bool isAllModerators(const std::string& accountID);
898
899 void insertGitTransport(git_smart_subtransport* tr, std::unique_ptr<P2PSubTransport>&& sub);
900 void eraseGitTransport(git_smart_subtransport* tr);
901
902 dhtnet::tls::CertificateStore& certStore(const std::string& accountId) const;
903
904private:
905 Manager();
906 ~Manager();
907 friend class AudioDeviceGuard;
908
909 // Data members
910 struct ManagerPimpl;
911 std::unique_ptr<ManagerPimpl> pimpl_;
912};
913
915{
916public:
918 AudioDeviceGuard(Manager& manager, const std::string& captureDevice);
920
921private:
922 Manager& manager_;
923 const AudioDeviceType type_;
924 const std::string captureDevice_;
925};
926
927// Helper to install a callback to be called once by the main event loop
928template<typename Callback>
929static void
931{
932 asio::post(*Manager::instance().ioContext(), [cb = std::forward<Callback>(cb)]() mutable {
933 try {
934 cb();
935 } catch (const std::exception& e) {
936 JAMI_ERROR("Exception running job: {}", e.what());
937 }
938 });
939}
940
941} // namespace jami
Main sound class.
This class provides an interface to functions exposed to the Plugin System interface for lrc and clie...
Manager (controller) of daemon.
Definition manager.h:66
std::vector< std::shared_ptr< T > > getAllAccounts() const
Get a list of account pointers of type T (baseclass Account)
Definition manager.h:763
static LIBJAMI_TEST_EXPORT Manager & instance()
Definition manager.cpp:694
std::shared_ptr< T > getAccount(std::string_view accountId) const
Get an account pointer, looks for account of type T.
Definition manager.h:753
CallFactory callFactory
Definition manager.h:826
std::unique_ptr< AudioDeviceGuard > startCaptureStream(const std::string &captureDevice)
Start a capture stream on the given device (eg.
Definition manager.h:155
static std::atomic_bool initialized
Definition manager.h:108
AccountFactory accountFactory
Definition manager.h:873
Preferences preferences
General preferences configuration.
Definition manager.h:80
static bool autoLoad
Definition manager.h:116
static bool syncOnRegister
Definition manager.h:114
VoipPreference voipPreferences
Voip related preferences.
Definition manager.h:85
std::shared_ptr< T > findAccount(const std::function< bool(const std::shared_ptr< T > &)> &pred)
Definition manager.h:787
AudioPreference audioPreference
Audio preferences.
Definition manager.h:90
void registerAccount(const std::string &accountID, const std::string &convId={})
Send registration for one account.
std::size_t accountCount() const
Definition manager.h:781
#define LIBJAMI_TEST_EXPORT
Definition def.h:49
#define JAMI_ERROR(formatstr,...)
Definition logger.h:243
Definition manager.h:41
void emitSignal(Args... args)
Definition jami_signal.h:64
AudioDeviceType
Definition audiolayer.h:57
static void runOnMainThread(Callback &&cb)
Definition manager.h:930
void setRingingTimeout(int32_t timeout)
void setAudioPlugin(const std::string &audioPlugin)
void setAccountDetails(const std::string &accountId, const std::map< std::string, std::string > &details)
void setHistoryLimit(int32_t days)
void setAccountsOrder(const std::string &order)
bool startRecordedFilePlayback(const std::string &filepath)
bool holdConference(const std::string &accountId, const std::string &confId)
bool setAudioManager(const std::string &api)
void loadAccountAndConversation(const std::string &accountId, bool loadAll, const std::string &convId)
int32_t getAudioOutputDeviceIndex(const std::string &name)
void setIsAlwaysRecording(bool rec)
int32_t getRingingTimeout()
void stopRecordedFilePlayback()
InitFlag
Definition jami.h:33
std::vector< std::string > getAccountList()
int32_t getAudioInputDeviceIndex(const std::string &name)
void setAccountActive(const std::string &accountId, bool enable, bool shutdownConnections)
std::string addAccount(const std::map< std::string, std::string > &details, const std::string &accountId)
std::string getCurrentAudioOutputPlugin()
bool getIsAlwaysRecording()
void sendRegister(const std::string &accountId, bool enable)
std::string getNoiseSuppressState()
int32_t getHistoryLimit()
bool addMainParticipant(const std::string &accountId, const std::string &confId)
void setNoiseSuppressState(const std::string &state)
std::vector< std::string > getAudioInputDeviceList()
std::vector< std::string > getCurrentAudioDevicesIndex()
void setVoiceActivityDetectionState(bool state)
void createConfFromParticipantList(const std::string &accountId, const std::vector< std::string > &participants)
bool detachParticipant(const std::string &, const std::string &callId)
std::string getEchoCancellationState()
bool getVoiceActivityDetectionState()
void removeAccount(const std::string &accountId)
bool joinConference(const std::string &accountId, const std::string &sel_confId, const std::string &account2Id, const std::string &drag_confId)
std::map< std::string, std::string > getAccountDetails(const std::string &accountId)
int getMessageStatus(uint64_t messageId)
std::vector< std::string > getAudioOutputDeviceList()
std::map< std::string, std::string > getVolatileAccountDetails(const std::string &accountId)
std::vector< std::string > getCallList()
void sendTextMessage(const std::string &accountId, const std::string &callId, const std::map< std::string, std::string > &messages, const std::string &from, bool isMixed)
bool joinParticipant(const std::string &accountId, const std::string &sel_callId, const std::string &account2Id, const std::string &drag_callId)
bool resumeConference(const std::string &accountId, const std::string &confId)
std::string getAudioManager()
void setEchoCancellationState(const std::string &state)