From c25d6dfa2961db34a37a51e8049cfbfb2955d645 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Sun, 29 Oct 2023 18:38:18 +1100 Subject: [PATCH 01/12] Added media player callbacks --- modules/phone-bluetooth/telephonymanager.cpp | 80 +++++++++++++++++++- modules/phone-bluetooth/telephonymanager.h | 13 +++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 8363ac3..385f03c 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -6,7 +6,7 @@ Q_LOGGING_CATEGORY(HEADUNIT, "telephony") Q_LOGGING_CATEGORY(OFONO, "telephony [qoFono]") Q_LOGGING_CATEGORY(BLUEZ, "telephony [BluezQt]") TelephonyManager::TelephonyManager(QObject *parent) : QObject(parent), - m_bluez_manager(this), m_obexManager(this), m_ofonoManagerClass(this), m_phonebookModel(this), m_callHistoryModel(this) + m_bluez_manager(this), m_obexManager(this), m_ofonoManagerClass(this), m_phonebookModel(this), m_callHistoryModel(this), m_mediaTrackTimer(this) { m_contactsFolder = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/contacts"; @@ -20,6 +20,8 @@ TelephonyManager::TelephonyManager(QObject *parent) : QObject(parent), qDBusRegisterMetaType(); qDBusRegisterMetaType(); + connect(&m_mediaTrackTimer, &QTimer::timeout, this, &TelephonyManager::mediaTrackTimerElapsed); + } TelephonyManager::~TelephonyManager(){ // delete m_activeDevice; @@ -224,6 +226,7 @@ void TelephonyManager::setBluezDevice(BluezQt::Device *device) { qCDebug(BLUEZ) << "Device set : NULL"; } m_activeDevice = device; + initMediaPlayer(); emit activeDeviceChanged(); emit pairedDevicesChanged(); } @@ -250,6 +253,79 @@ void TelephonyManager::deviceRemoved(BluezQt::DevicePtr device){ emit pairedDevicesChanged(); } +void TelephonyManager::mediaPositionChanged(quint32 position) { + //TODO: This only happens once every 10 seconds or when the track changes or status changes + // Have implemented a 1s timer instead to get around this + + //m_mediaTrackPosition = position; + //qCDebug(BLUEZ) << "PB Position: " << position; +} + +void TelephonyManager::mediaTrackTimerElapsed() { + if(m_activeDevice) { + BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); + if(!mediaPlayer.isNull()) { + if(m_mediaTrackGotPosition) { + m_mediaTrackPosition += 1000; + } else { + m_mediaTrackPosition = mediaPlayer->position(); + m_mediaTrackGotPosition = true; + } + qCDebug(BLUEZ) << "PB Position: " << m_mediaTrackPosition; + } else { + m_mediaTrackPosition = 0; + m_mediaTrackGotPosition = false; + m_mediaTrackTimer.stop(); + } + } else { + m_mediaTrackPosition = 0; + m_mediaTrackGotPosition = false; + m_mediaTrackTimer.stop(); + } +} + +void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { + qCDebug(BLUEZ) << "Status: " << status; + switch(status) { + case BluezQt::MediaPlayer::Playing: + m_mediaTrackTimer.start(1000); + break; + default: + m_mediaTrackTimer.stop(); + m_mediaTrackGotPosition = false; + break; + } +} + +void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { + qCDebug(BLUEZ) << "PB Track: " << " " << track.artist() << " " << track.title() << " " << track.trackNumber(); + m_mediaTrackPosition = 0; + m_mediaTrackGotPosition = false; +} + +void TelephonyManager::mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer) { + if(!mediaPlayer.isNull()) { + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::positionChanged, this, &TelephonyManager::mediaPositionChanged); + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::trackChanged, this, &TelephonyManager::mediaTrackChanged); + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::statusChanged, this, &TelephonyManager::mediaStatusChanged); + } +} + +void TelephonyManager::initMediaPlayer() { + if(m_activeDevice) { + connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::mediaPlayerChanged); + BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); + mediaPlayerChanged(mediaPlayer); + + //qCDebug(BLUEZ) << mediaPlayer->status(); + //qCDebug(BLUEZ) << mediaPlayer->position(); + qCDebug(BLUEZ) << mediaPlayer->track().artist(); + qCDebug(BLUEZ) << mediaPlayer->track().title(); + qCDebug(BLUEZ) << mediaPlayer->track().trackNumber(); + mediaStatusChanged(mediaPlayer->status()); + } +} + void TelephonyManager::deviceConnectionChanged(bool connected){ BluezQt::Device* device = dynamic_cast(QObject::sender()); if(connected){ @@ -265,7 +341,9 @@ void TelephonyManager::deviceConnectionChanged(bool connected){ } setBluezDevice(device); + initMediaPlayer(); getPhonebooks(m_activeDevice->address()); + } else { qCDebug(BLUEZ) << "Device disconnected : " << device->name(); if(m_activeDevice == device){ diff --git a/modules/phone-bluetooth/telephonymanager.h b/modules/phone-bluetooth/telephonymanager.h index 6135002..f5dafb5 100644 --- a/modules/phone-bluetooth/telephonymanager.h +++ b/modules/phone-bluetooth/telephonymanager.h @@ -124,8 +124,19 @@ private slots: void contactsFolderChanged(const QString &path); void contactsChanged(const QString &path); + + void mediaPositionChanged(quint32 position); + void mediaTrackChanged(BluezQt::MediaPlayerTrack track); + void mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer); + void mediaStatusChanged(BluezQt::MediaPlayer::Status status); + void mediaTrackTimerElapsed(); + private: QString m_contactsFolder = "contacts/"; + QTimer m_mediaTrackTimer; + + quint32 m_mediaTrackPosition = 0; + bool m_mediaTrackGotPosition = false; BluezQt::Manager m_bluez_manager; BluezQt::Device* m_activeDevice = nullptr; @@ -141,7 +152,7 @@ private slots: void setBluezDevice(BluezQt::Device* device); void initAdapter(BluezQt::AdapterPtr adapter); void pullPhonebook (QString path, QString type, QString output); - + void initMediaPlayer(); QVariantMap m_pairedDevices; QStringList m_adapters; void updateAdapters(); From eafc2da2fe4e02cde747270d52d0559ccdd84d98 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Sun, 29 Oct 2023 22:17:16 +1100 Subject: [PATCH 02/12] Added messaging for track and position --- modules/phone-bluetooth/telephonymanager.cpp | 54 +++++++++----------- modules/phone-bluetooth/telephonymanager.h | 1 + 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 385f03c..d95bace 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -20,6 +20,7 @@ TelephonyManager::TelephonyManager(QObject *parent) : QObject(parent), qDBusRegisterMetaType(); qDBusRegisterMetaType(); + connect(&m_mediaTrackTimer, &QTimer::timeout, this, &TelephonyManager::mediaTrackTimerElapsed); } @@ -254,28 +255,19 @@ void TelephonyManager::deviceRemoved(BluezQt::DevicePtr device){ } void TelephonyManager::mediaPositionChanged(quint32 position) { - //TODO: This only happens once every 10 seconds or when the track changes or status changes - // Have implemented a 1s timer instead to get around this - - //m_mediaTrackPosition = position; - //qCDebug(BLUEZ) << "PB Position: " << position; + //TODO: This only gets triggered sporadically or when the track changes or status changes + // Have implemented a 2Hz timer instead to get around this + m_mediaTrackPosition = position; + emit message("MediaPosition", position); + m_mediaTrackGotPosition = true; + m_mediaTrackTimer.start(500); } void TelephonyManager::mediaTrackTimerElapsed() { if(m_activeDevice) { - BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); - if(!mediaPlayer.isNull()) { - if(m_mediaTrackGotPosition) { - m_mediaTrackPosition += 1000; - } else { - m_mediaTrackPosition = mediaPlayer->position(); - m_mediaTrackGotPosition = true; - } - qCDebug(BLUEZ) << "PB Position: " << m_mediaTrackPosition; - } else { - m_mediaTrackPosition = 0; - m_mediaTrackGotPosition = false; - m_mediaTrackTimer.stop(); + if(m_mediaTrackGotPosition) { + m_mediaTrackPosition += 500; + emit message("MediaPosition", m_mediaTrackPosition); } } else { m_mediaTrackPosition = 0; @@ -285,10 +277,9 @@ void TelephonyManager::mediaTrackTimerElapsed() { } void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { - qCDebug(BLUEZ) << "Status: " << status; + qCDebug(BLUEZ) << "Media player status: " << status; switch(status) { case BluezQt::MediaPlayer::Playing: - m_mediaTrackTimer.start(1000); break; default: m_mediaTrackTimer.stop(); @@ -298,9 +289,16 @@ void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { } void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { - qCDebug(BLUEZ) << "PB Track: " << " " << track.artist() << " " << track.title() << " " << track.trackNumber(); + qCDebug(BLUEZ) << "Media player track: #" << track.trackNumber() << " | " << track.artist() << track.title(); m_mediaTrackPosition = 0; m_mediaTrackGotPosition = false; + + QVariantMap vTrack; + vTrack.insert("number",track.trackNumber()); + vTrack.insert("artist",track.artist()); + vTrack.insert("title",track.title()); + vTrack.insert("duration",track.duration()); + emit message("MediaTrack", vTrack); } void TelephonyManager::mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer) { @@ -315,14 +313,12 @@ void TelephonyManager::initMediaPlayer() { if(m_activeDevice) { connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::mediaPlayerChanged); BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); - mediaPlayerChanged(mediaPlayer); - - //qCDebug(BLUEZ) << mediaPlayer->status(); - //qCDebug(BLUEZ) << mediaPlayer->position(); - qCDebug(BLUEZ) << mediaPlayer->track().artist(); - qCDebug(BLUEZ) << mediaPlayer->track().title(); - qCDebug(BLUEZ) << mediaPlayer->track().trackNumber(); - mediaStatusChanged(mediaPlayer->status()); + if(!mediaPlayer.isNull()) { + mediaPlayerChanged(mediaPlayer); + mediaTrackChanged(mediaPlayer->track()); + mediaPositionChanged(mediaPlayer->position()); + mediaStatusChanged(mediaPlayer->status()); + } } } diff --git a/modules/phone-bluetooth/telephonymanager.h b/modules/phone-bluetooth/telephonymanager.h index f5dafb5..13410f0 100644 --- a/modules/phone-bluetooth/telephonymanager.h +++ b/modules/phone-bluetooth/telephonymanager.h @@ -85,6 +85,7 @@ class TelephonyManager : public QObject, PluginInterface, public MediaInterface void activeDeviceChanged(); void pairedDevicesChanged(); + void message(QString id, QVariant message); void action(QString id, QVariant message); void start() override; From 7a37d795245076247c265cd64fc588d07d1feb3a Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Sun, 29 Oct 2023 22:49:39 +1100 Subject: [PATCH 03/12] Changed case for messages, added better position handling --- modules/phone-bluetooth/telephonymanager.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index d95bace..297f090 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -26,6 +26,7 @@ TelephonyManager::TelephonyManager(QObject *parent) : QObject(parent), } TelephonyManager::~TelephonyManager(){ // delete m_activeDevice; + m_mediaTrackTimer.stop(); } QObject *TelephonyManager::getContextProperty(){ @@ -255,10 +256,10 @@ void TelephonyManager::deviceRemoved(BluezQt::DevicePtr device){ } void TelephonyManager::mediaPositionChanged(quint32 position) { - //TODO: This only gets triggered sporadically or when the track changes or status changes + //TODO: Investigate why this only gets triggered sporadically or when the track changes or status changes // Have implemented a 2Hz timer instead to get around this m_mediaTrackPosition = position; - emit message("MediaPosition", position); + emit message("mediaPosition", position); m_mediaTrackGotPosition = true; m_mediaTrackTimer.start(500); } @@ -267,12 +268,13 @@ void TelephonyManager::mediaTrackTimerElapsed() { if(m_activeDevice) { if(m_mediaTrackGotPosition) { m_mediaTrackPosition += 500; - emit message("MediaPosition", m_mediaTrackPosition); + emit message("mediaPosition", m_mediaTrackPosition); } } else { m_mediaTrackPosition = 0; m_mediaTrackGotPosition = false; m_mediaTrackTimer.stop(); + emit message("mediaPosition", m_mediaTrackPosition); } } @@ -290,7 +292,6 @@ void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { qCDebug(BLUEZ) << "Media player track: #" << track.trackNumber() << " | " << track.artist() << track.title(); - m_mediaTrackPosition = 0; m_mediaTrackGotPosition = false; QVariantMap vTrack; @@ -298,7 +299,7 @@ void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { vTrack.insert("artist",track.artist()); vTrack.insert("title",track.title()); vTrack.insert("duration",track.duration()); - emit message("MediaTrack", vTrack); + emit message("mediaTrack", vTrack); } void TelephonyManager::mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer) { From 19c5d25ed6e43e945880af69a01d3123dafd400d Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:12:02 +1100 Subject: [PATCH 04/12] MediaManager now places track position and track information on the message bus --- app/mediamanager.cpp | 12 +++++++ app/mediamanager.h | 4 +++ app/pluginmanager.cpp | 1 + includes/mediainterface.h | 3 +- modules/phone-bluetooth/telephonymanager.cpp | 34 +++++++++++--------- modules/phone-bluetooth/telephonymanager.h | 12 +++---- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/app/mediamanager.cpp b/app/mediamanager.cpp index c6788e8..03761ad 100644 --- a/app/mediamanager.cpp +++ b/app/mediamanager.cpp @@ -43,11 +43,23 @@ void MediaManager::addInterface(QString name, QObject *object){ for(int i = pluginMeta->methodOffset(); i < pluginMeta->methodCount(); ++i){ if(pluginMeta->method(i).methodSignature() == "playbackStarted()"){ connect(object, SIGNAL(playbackStarted()), this, SLOT(playbackStartedHandler())); + } else if(pluginMeta->method(i).methodSignature() == "trackChanged(QVariantMap)") { + connect(object, SIGNAL(trackChanged(QVariantMap)), this, SLOT(onTrackChanged(QVariantMap))); + } else if(pluginMeta->method(i).methodSignature() == "mediaPositionChanged(uint)") { + connect(object, SIGNAL(mediaPositionChanged(uint)), this, SLOT(onMediaPositionChanged(uint))); } } } } +void MediaManager::onTrackChanged(QVariantMap track) { + emit message("MediaManager", "mediaTrack", track); +} + +void MediaManager::onMediaPositionChanged(quint32 position) { + emit message("MediaManager", "mediaPosition", position); +} + void MediaManager::playbackStartedHandler(){ MediaInterface * sender = dynamic_cast(QObject::sender()); if(sender){ diff --git a/app/mediamanager.h b/app/mediamanager.h index f4bc5d8..92da1f6 100644 --- a/app/mediamanager.h +++ b/app/mediamanager.h @@ -29,6 +29,8 @@ class MediaManager : public QObject signals: void intefacesChanged(); void activeMediaPlayerChanged(); + void message(QString sender, QString message, QVariant parameter); + public slots: void setActiveMediaPlayer(QString name); void start(); @@ -36,6 +38,8 @@ public slots: void prevTrack(); void nextTrack(); void setVolume(uint8_t volume); + void onMediaPositionChanged(quint32 position); + void onTrackChanged(QVariantMap track); private slots: void setVoiceVolume(QString interface, QVariant value); diff --git a/app/pluginmanager.cpp b/app/pluginmanager.cpp index 152710f..af133a7 100644 --- a/app/pluginmanager.cpp +++ b/app/pluginmanager.cpp @@ -44,6 +44,7 @@ bool PluginManager::loadPlugins(QStringList filterList) connect(plugin, &PluginObject::action, this, &PluginManager::actionHandler); connect(plugin, &PluginObject::message, this, &PluginManager::messageHandler); + connect(m_mediaManager, &MediaManager::message, this, &PluginManager::messageHandler); } //Load QML plugins diff --git a/includes/mediainterface.h b/includes/mediainterface.h index 3d66819..5a9b2af 100644 --- a/includes/mediainterface.h +++ b/includes/mediainterface.h @@ -16,7 +16,8 @@ class MediaInterface virtual void nextTrack() = 0; virtual void setMediaVolume(uint8_t volume) {}; virtual void setVoiceVolume(uint8_t volume) {}; - + virtual void mediaPositionChanged(quint32 position) {}; + virtual void trackChanged(QVariantMap track) {}; virtual void playbackStarted() = 0; MediaInterfaceSettings getSettings() { diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 297f090..3e1e770 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -255,11 +255,11 @@ void TelephonyManager::deviceRemoved(BluezQt::DevicePtr device){ emit pairedDevicesChanged(); } -void TelephonyManager::mediaPositionChanged(quint32 position) { +void TelephonyManager::onMediaPosition(quint32 position) { //TODO: Investigate why this only gets triggered sporadically or when the track changes or status changes // Have implemented a 2Hz timer instead to get around this m_mediaTrackPosition = position; - emit message("mediaPosition", position); + emit mediaPositionChanged(position); m_mediaTrackGotPosition = true; m_mediaTrackTimer.start(500); } @@ -268,20 +268,21 @@ void TelephonyManager::mediaTrackTimerElapsed() { if(m_activeDevice) { if(m_mediaTrackGotPosition) { m_mediaTrackPosition += 500; - emit message("mediaPosition", m_mediaTrackPosition); + emit mediaPositionChanged(m_mediaTrackPosition); } } else { m_mediaTrackPosition = 0; m_mediaTrackGotPosition = false; m_mediaTrackTimer.stop(); - emit message("mediaPosition", m_mediaTrackPosition); + emit mediaPositionChanged(m_mediaTrackPosition); } } -void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { +void TelephonyManager::onMediaStatus(BluezQt::MediaPlayer::Status status) { qCDebug(BLUEZ) << "Media player status: " << status; switch(status) { case BluezQt::MediaPlayer::Playing: + emit playbackStarted(); break; default: m_mediaTrackTimer.stop(); @@ -290,7 +291,7 @@ void TelephonyManager::mediaStatusChanged(BluezQt::MediaPlayer::Status status) { } } -void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { +void TelephonyManager::onMediaTrack(BluezQt::MediaPlayerTrack track) { qCDebug(BLUEZ) << "Media player track: #" << track.trackNumber() << " | " << track.artist() << track.title(); m_mediaTrackGotPosition = false; @@ -299,26 +300,26 @@ void TelephonyManager::mediaTrackChanged(BluezQt::MediaPlayerTrack track) { vTrack.insert("artist",track.artist()); vTrack.insert("title",track.title()); vTrack.insert("duration",track.duration()); - emit message("mediaTrack", vTrack); + emit trackChanged(vTrack); } -void TelephonyManager::mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer) { +void TelephonyManager::onMediaPlayer(BluezQt::MediaPlayerPtr mediaPlayer) { if(!mediaPlayer.isNull()) { - connect(mediaPlayer.get(), &BluezQt::MediaPlayer::positionChanged, this, &TelephonyManager::mediaPositionChanged); - connect(mediaPlayer.get(), &BluezQt::MediaPlayer::trackChanged, this, &TelephonyManager::mediaTrackChanged); - connect(mediaPlayer.get(), &BluezQt::MediaPlayer::statusChanged, this, &TelephonyManager::mediaStatusChanged); + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::positionChanged, this, &TelephonyManager::onMediaPosition); + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::trackChanged, this, &TelephonyManager::onMediaTrack); + connect(mediaPlayer.get(), &BluezQt::MediaPlayer::statusChanged, this, &TelephonyManager::onMediaStatus); } } void TelephonyManager::initMediaPlayer() { if(m_activeDevice) { - connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::mediaPlayerChanged); + connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::onMediaPlayer); BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); if(!mediaPlayer.isNull()) { - mediaPlayerChanged(mediaPlayer); - mediaTrackChanged(mediaPlayer->track()); - mediaPositionChanged(mediaPlayer->position()); - mediaStatusChanged(mediaPlayer->status()); + onMediaPlayer(mediaPlayer); + onMediaTrack(mediaPlayer->track()); + onMediaPosition(mediaPlayer->position()); + onMediaStatus(mediaPlayer->status()); } } } @@ -433,6 +434,7 @@ void TelephonyManager::mediaPlaybackStarted() { emit playbackStarted(); } } + void TelephonyManager::eventMessage(QString id, QVariant message) { if(id == "AndroidAuto::connected"){ m_androidAutoConnected = message.toBool(); diff --git a/modules/phone-bluetooth/telephonymanager.h b/modules/phone-bluetooth/telephonymanager.h index 13410f0..1b80fbb 100644 --- a/modules/phone-bluetooth/telephonymanager.h +++ b/modules/phone-bluetooth/telephonymanager.h @@ -85,7 +85,6 @@ class TelephonyManager : public QObject, PluginInterface, public MediaInterface void activeDeviceChanged(); void pairedDevicesChanged(); - void message(QString id, QVariant message); void action(QString id, QVariant message); void start() override; @@ -93,8 +92,9 @@ class TelephonyManager : public QObject, PluginInterface, public MediaInterface void prevTrack() override; void nextTrack() override; void setMediaVolume(uint8_t volume) override; - void playbackStarted() override; + void trackChanged(QVariantMap track) override; + void mediaPositionChanged(quint32 position) override; public slots: void enablePairing(); @@ -126,10 +126,10 @@ private slots: void contactsFolderChanged(const QString &path); void contactsChanged(const QString &path); - void mediaPositionChanged(quint32 position); - void mediaTrackChanged(BluezQt::MediaPlayerTrack track); - void mediaPlayerChanged(BluezQt::MediaPlayerPtr mediaPlayer); - void mediaStatusChanged(BluezQt::MediaPlayer::Status status); + void onMediaPosition(quint32 position); + void onMediaTrack(BluezQt::MediaPlayerTrack track); + void onMediaPlayer(BluezQt::MediaPlayerPtr mediaPlayer); + void onMediaStatus(BluezQt::MediaPlayer::Status status); void mediaTrackTimerElapsed(); private: From fad6a505fc3dab97886d8fab67fdb198d07ce79f Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:18:02 +1100 Subject: [PATCH 05/12] Dropped "media" from message id --- app/mediamanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/mediamanager.cpp b/app/mediamanager.cpp index 03761ad..1df02fb 100644 --- a/app/mediamanager.cpp +++ b/app/mediamanager.cpp @@ -53,11 +53,11 @@ void MediaManager::addInterface(QString name, QObject *object){ } void MediaManager::onTrackChanged(QVariantMap track) { - emit message("MediaManager", "mediaTrack", track); + emit message("MediaManager", "track", track); } void MediaManager::onMediaPositionChanged(quint32 position) { - emit message("MediaManager", "mediaPosition", position); + emit message("MediaManager", "position", position); } void MediaManager::playbackStartedHandler(){ From 1bb66c1d26309a9f5ae436cffac62c61993a31e6 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 30 Oct 2023 12:40:07 +1100 Subject: [PATCH 06/12] Changed MediaManager to MediaInput message sender --- app/mediamanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/mediamanager.cpp b/app/mediamanager.cpp index 1df02fb..c1062f2 100644 --- a/app/mediamanager.cpp +++ b/app/mediamanager.cpp @@ -53,11 +53,11 @@ void MediaManager::addInterface(QString name, QObject *object){ } void MediaManager::onTrackChanged(QVariantMap track) { - emit message("MediaManager", "track", track); + emit message("MediaInput", "track", track); } void MediaManager::onMediaPositionChanged(quint32 position) { - emit message("MediaManager", "position", position); + emit message("MediaInput", "position", position); } void MediaManager::playbackStartedHandler(){ From 3bfb3d3b5abffb31322fda11e441aa21b6dd41aa Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:53:20 +1100 Subject: [PATCH 07/12] Fixed issues with playing/pausing with AA TelephonyManager::onMediaStatus() when raising playbackStarted was not checking if AA was connected. TelephonyManager::mediaPlaybackStarted() and TelephonyManager::onMediaStatus() both raise playbackStarted(); TelephonyManager::mediaPlaybackStarted() might be redundant. Needs to be removed from Phone.qml in a future change. --- modules/phone-bluetooth/telephonymanager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 3e1e770..9060380 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -282,7 +282,8 @@ void TelephonyManager::onMediaStatus(BluezQt::MediaPlayer::Status status) { qCDebug(BLUEZ) << "Media player status: " << status; switch(status) { case BluezQt::MediaPlayer::Playing: - emit playbackStarted(); + if(!m_androidAutoConnected) + emit playbackStarted(); break; default: m_mediaTrackTimer.stop(); From 572633a072c48ac89ecb3805bcb16fae5c44a431 Mon Sep 17 00:00:00 2001 From: aselafernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:29:47 +1100 Subject: [PATCH 08/12] Added bluetooth reconnection timer This allows bluetooth connections to be made later if the device is not present when the adaptor is initialised. Similarly, they can be remade if the connection is lost. --- modules/phone-bluetooth/telephonymanager.cpp | 31 ++++++++++++++++---- modules/phone-bluetooth/telephonymanager.h | 2 ++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 9060380..373e9ec 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -14,6 +14,9 @@ TelephonyManager::TelephonyManager(QObject *parent) : QObject(parent), m_pluginSettings.eventListeners = QStringList() << "AndroidAuto::connected"; + reconnectTimer.setSingleShot(true); + connect(&reconnectTimer, &QTimer::timeout, this, &TelephonyManager::connectToNextDevice); + BluezQt::InitManagerJob *job = m_bluez_manager.init(); job->start(); connect(job, &BluezQt::InitManagerJob::result, this, &TelephonyManager::initBluez); @@ -347,6 +350,10 @@ void TelephonyManager::deviceConnectionChanged(bool connected){ qCDebug(BLUEZ) << "Device disconnected : " << device->name(); if(m_activeDevice == device){ setBluezDevice(nullptr); + qCDebug(BLUEZ) << "Trying again : " << device->name(); + BluezQt::PendingCall * connectCall = device->connectToDevice(); + connectCall->setUserData(device->ubi()); + connect(connectCall, &BluezQt::PendingCall::finished, this, &TelephonyManager::connectToDeviceCallback); } } } @@ -378,12 +385,18 @@ void TelephonyManager::connectToNextDevice(){ } } } + m_previouslyTriedDevice = device; + if(device){ qCDebug(BLUEZ) << "Connecting to : " << device->name(); BluezQt::PendingCall * connectCall = device->connectToDevice(); connectCall->setUserData(device->ubi()); connect(connectCall, &BluezQt::PendingCall::finished, this, &TelephonyManager::connectToDeviceCallback); + } else { + if(activeDeviceFound) { + reconnectTimer.start(10000); + } } } @@ -458,15 +471,23 @@ void TelephonyManager::actionMessage(QString id, QVariant message) { } void TelephonyManager::showOverlay(){ - QVariantMap map; - map["source"] = "qrc:/PhoneBluetooth/CallNotification.qml"; - - emit action("GUI::OpenOverlay", map); + if(m_androidAutoConnected) { + emit action("GUI::changePageIndex", 0); + } else { + QVariantMap map; + map["source"] = "qrc:/PhoneBluetooth/CallNotification.qml"; + emit action("GUI::OpenOverlay", map); + } } void TelephonyManager::hideOverlay() { - emit action("GUI::CloseOverlay", QVariant()); + if(m_androidAutoConnected) { + emit action("GUI::changePagePrevIndex", 0); + } else { + emit action("GUI::CloseOverlay", QVariant()); + } } + void TelephonyManager::pullCallHistory() { getPhonebooks(m_activeDevice->address(), true); } diff --git a/modules/phone-bluetooth/telephonymanager.h b/modules/phone-bluetooth/telephonymanager.h index 1b80fbb..d1d4efa 100644 --- a/modules/phone-bluetooth/telephonymanager.h +++ b/modules/phone-bluetooth/telephonymanager.h @@ -28,6 +28,7 @@ #include #include +#include #include "ofonomanager.h" #include "bluezagent.h" @@ -159,6 +160,7 @@ private slots: void updateAdapters(); void connectToNextDevice(); + QTimer reconnectTimer; OfonoManager m_ofonoManagerClass; PhonebookModel m_phonebookModel; PhonebookModel m_callHistoryModel; From f6289d0180b0305f446aa37fe85fc39f73e84fa7 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 2 Mar 2026 22:45:07 +1100 Subject: [PATCH 09/12] Fixed bug preventing bluetooth retries --- modules/phone-bluetooth/telephonymanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 373e9ec..ae992c6 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -407,9 +407,9 @@ void TelephonyManager::connectToDeviceCallback(BluezQt::PendingCall *call){ qCDebug(BLUEZ) << "Finished connecting to : " << device->name(); } else { qCDebug(BLUEZ) << "Error connecting to : " << device->name() << " : " << call->errorText(); - if(device == m_previouslyTriedDevice){ + //if(device == m_previouslyTriedDevice){ connectToNextDevice(); - } + //} } } From 30368bf024335f319f3fd8aba09d759d0eeabc77 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Mon, 2 Mar 2026 23:06:06 +1100 Subject: [PATCH 10/12] Changed approach to reconnecting --- modules/phone-bluetooth/telephonymanager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index ae992c6..7d0e448 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -351,6 +351,7 @@ void TelephonyManager::deviceConnectionChanged(bool connected){ if(m_activeDevice == device){ setBluezDevice(nullptr); qCDebug(BLUEZ) << "Trying again : " << device->name(); + m_previouslyTriedDevice = device; BluezQt::PendingCall * connectCall = device->connectToDevice(); connectCall->setUserData(device->ubi()); connect(connectCall, &BluezQt::PendingCall::finished, this, &TelephonyManager::connectToDeviceCallback); @@ -407,9 +408,9 @@ void TelephonyManager::connectToDeviceCallback(BluezQt::PendingCall *call){ qCDebug(BLUEZ) << "Finished connecting to : " << device->name(); } else { qCDebug(BLUEZ) << "Error connecting to : " << device->name() << " : " << call->errorText(); - //if(device == m_previouslyTriedDevice){ + if(device == m_previouslyTriedDevice){ connectToNextDevice(); - //} + } } } From 216cda622ca1330cd82316e59a36aac580cba897 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:13:35 +1100 Subject: [PATCH 11/12] Stopped mediaPlayer signals accumulating Old connections were not disconnected when a media connection was reestablished, leading to triggers of signals/slots --- modules/phone-bluetooth/telephonymanager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/phone-bluetooth/telephonymanager.cpp b/modules/phone-bluetooth/telephonymanager.cpp index 7d0e448..df2fdd3 100755 --- a/modules/phone-bluetooth/telephonymanager.cpp +++ b/modules/phone-bluetooth/telephonymanager.cpp @@ -312,18 +312,24 @@ void TelephonyManager::onMediaPlayer(BluezQt::MediaPlayerPtr mediaPlayer) { connect(mediaPlayer.get(), &BluezQt::MediaPlayer::positionChanged, this, &TelephonyManager::onMediaPosition); connect(mediaPlayer.get(), &BluezQt::MediaPlayer::trackChanged, this, &TelephonyManager::onMediaTrack); connect(mediaPlayer.get(), &BluezQt::MediaPlayer::statusChanged, this, &TelephonyManager::onMediaStatus); + } else { + disconnect(mediaPlayer.get(), &BluezQt::MediaPlayer::positionChanged, this, &TelephonyManager::onMediaPosition); + disconnect(mediaPlayer.get(), &BluezQt::MediaPlayer::trackChanged, this, &TelephonyManager::onMediaTrack); + disconnect(mediaPlayer.get(), &BluezQt::MediaPlayer::statusChanged, this, &TelephonyManager::onMediaStatus); } } void TelephonyManager::initMediaPlayer() { if(m_activeDevice) { - connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::onMediaPlayer); BluezQt::MediaPlayerPtr mediaPlayer = m_activeDevice->mediaPlayer(); if(!mediaPlayer.isNull()) { + connect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::onMediaPlayer); onMediaPlayer(mediaPlayer); onMediaTrack(mediaPlayer->track()); onMediaPosition(mediaPlayer->position()); onMediaStatus(mediaPlayer->status()); + } else { + disconnect(m_activeDevice, &BluezQt::Device::mediaPlayerChanged, this, &TelephonyManager::onMediaPlayer); } } } From f427ce1746292f7911caf688f4297c4cecbe0564 Mon Sep 17 00:00:00 2001 From: Asela Fernando <25498128+aselafernando@users.noreply.github.com> Date: Wed, 4 Mar 2026 01:51:03 +1100 Subject: [PATCH 12/12] FIXED: MediaManager sending multiple events MediaManager was connected to the message handler on each plugin load. This caused every message from MediaManager to be repeated based on the number of plugins loaded. --- app/pluginmanager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/pluginmanager.cpp b/app/pluginmanager.cpp index af133a7..e655096 100644 --- a/app/pluginmanager.cpp +++ b/app/pluginmanager.cpp @@ -44,9 +44,11 @@ bool PluginManager::loadPlugins(QStringList filterList) connect(plugin, &PluginObject::action, this, &PluginManager::actionHandler); connect(plugin, &PluginObject::message, this, &PluginManager::messageHandler); - connect(m_mediaManager, &MediaManager::message, this, &PluginManager::messageHandler); - } + + //Connect media manager to Message Handler + connect(m_mediaManager, &MediaManager::message, this, &PluginManager::messageHandler); + //Load QML plugins if(pluginsDir.cd("qml")){ for (const QString &fileName : pluginsDir.entryList(QDir::Files)) {