23 #include <TelepathyQt/AccountManager>
24 #include <TelepathyQt/SimpleCallObserver>
25 #include <TelepathyQt/PendingOperation>
26 #include <TelepathyQt/PendingReady>
27 #include <TelepathyQt/PendingAccount>
34 class TelepathyCallMonitor :
public QObject
38 TelepathyCallMonitor(
const Tp::AccountPtr& account):
40 mCallObserver(Tp::SimpleCallObserver::create(mAccount)) {
41 connect(mCallObserver.data(), SIGNAL(callStarted(Tp::CallChannelPtr)), SIGNAL(offHook()));
42 connect(mCallObserver.data(), SIGNAL(callEnded(Tp::CallChannelPtr,QString,QString)), SIGNAL(onHook()));
43 connect(mCallObserver.data(), SIGNAL(streamedMediaCallStarted(Tp::StreamedMediaChannelPtr)), SIGNAL(offHook()));
44 connect(mCallObserver.data(), SIGNAL(streamedMediaCallEnded(Tp::StreamedMediaChannelPtr,QString,QString)), SIGNAL(onHook()));
52 Tp::AccountPtr mAccount;
53 Tp::SimpleCallObserverPtr mCallObserver;
57 class TelepathyBridge :
public QObject
65 QTimer::singleShot(0,
this, SLOT(accountManagerSetup()));
69 for (std::list<TelepathyCallMonitor*>::iterator it = mCallMonitors.begin();
70 it != mCallMonitors.end();
77 std::lock_guard<std::mutex> l(cb_lock);
82 void accountManagerSetup() {
83 mAccountManager = Tp::AccountManager::create();
84 connect(mAccountManager->becomeReady(),
85 SIGNAL(finished(Tp::PendingOperation*)),
86 SLOT(accountManagerReady(Tp::PendingOperation*)));
89 void accountManagerReady(Tp::PendingOperation* operation) {
90 if (operation->isError()) {
91 std::cerr <<
"TelepathyBridge: Operation failed (accountManagerReady)" << std::endl;
92 QTimer::singleShot(1000,
this, SLOT(accountManagerSetup()));
96 Q_FOREACH(
const Tp::AccountPtr& account, mAccountManager->allAccounts()) {
97 connect(account->becomeReady(Tp::Account::FeatureCapabilities),
98 SIGNAL(finished(Tp::PendingOperation*)),
99 SLOT(accountReady(Tp::PendingOperation*)));
102 connect(mAccountManager.data(), SIGNAL(newAccount(Tp::AccountPtr)), SLOT(newAccount(Tp::AccountPtr)));
105 void newAccount(
const Tp::AccountPtr& account)
107 connect(account->becomeReady(Tp::Account::FeatureCapabilities),
108 SIGNAL(finished(Tp::PendingOperation*)),
109 SLOT(accountReady(Tp::PendingOperation*)));
112 void accountReady(Tp::PendingOperation* operation) {
113 if (operation->isError()) {
114 std::cerr <<
"TelepathyAccount: Operation failed (accountReady)" << std::endl;
118 Tp::PendingReady* pendingReady = qobject_cast<Tp::PendingReady*>(operation);
119 if (pendingReady == 0) {
120 std::cerr <<
"Rejecting account because could not understand ready status" << std::endl;
124 checkAndAddAccount(Tp::AccountPtr::qObjectCast(pendingReady->proxy()));
129 std::lock_guard<std::mutex> l(cb_lock);
136 std::lock_guard<std::mutex> l(cb_lock);
143 std::function<void (CallMonitor::State)> cb;
144 Tp::AccountManagerPtr mAccountManager;
145 std::list<TelepathyCallMonitor*> mCallMonitors;
147 void checkAndAddAccount(
const Tp::AccountPtr& account)
149 Tp::ConnectionCapabilities caps = account->capabilities();
152 if (caps.audioCalls() || caps.videoCalls() || caps.videoCallsWithAudio() || caps.streamedMediaCalls()) {
153 auto tcm =
new TelepathyCallMonitor(account);
154 connect(tcm, SIGNAL(offHook()), SLOT(offHook()));
155 connect(tcm, SIGNAL(onHook()), SLOT(onHook()));
156 mCallMonitors.push_back(tcm);
167 std::thread([
this]() {
170 mBridge =
new TelepathyBridge();
174 }
catch(
const std::system_error& error) {
175 std::cerr <<
"exception(std::system_error) in CallMonitor thread start" << error.what() << std::endl;
177 std::cerr <<
"exception(...) in CallMonitor thread start" << std::endl;
205 #include "call_monitor.moc"
void destroy()
Destroys the Qt core world and quits its event loop.
void build_and_run(int argc, char **argv, const std::function< void()> &ready)
Sets up the Qt core world and executes its event loop. Blocks until destroy() is called.
void on_change(const std::function< void(CallMonitor::State)> &func)
TelepathyBridge * mBridge
std::future< void > enter_with_task(const std::function< void()> &task)
Enters the Qt core world and schedules the given task for execution.