mirror of
https://github.com/kavishdevar/librepods.git
synced 2026-01-31 23:29:10 +00:00
[Linux] Allow setting ear detection behaviour
This commit is contained in:
committed by
Tim Gromeyer
parent
c2db0afdf1
commit
0846c3eb48
@@ -34,7 +34,8 @@ public:
|
||||
AirPodsTrayApp(bool debugMode)
|
||||
: debugMode(debugMode)
|
||||
, m_battery(new Battery(this))
|
||||
, monitor(new BluetoothMonitor(this)) {
|
||||
, monitor(new BluetoothMonitor(this))
|
||||
, m_settings(new QSettings("AirPodsTrayApp", "AirPodsTrayApp")){
|
||||
if (debugMode) {
|
||||
QLoggingCategory::setFilterRules("airpodsApp.debug=true");
|
||||
} else {
|
||||
@@ -85,6 +86,7 @@ public:
|
||||
|
||||
~AirPodsTrayApp() {
|
||||
saveCrossDeviceEnabled();
|
||||
saveEarDetectionSettings();
|
||||
|
||||
delete trayIcon;
|
||||
delete trayMenu;
|
||||
@@ -265,18 +267,11 @@ public slots:
|
||||
}
|
||||
}
|
||||
|
||||
bool loadCrossDeviceEnabled()
|
||||
{
|
||||
QSettings settings;
|
||||
return settings.value("crossdevice/enabled", false).toBool();
|
||||
}
|
||||
bool loadCrossDeviceEnabled() { return m_settings->value("crossdevice/enabled", false).toBool(); }
|
||||
void saveCrossDeviceEnabled() { m_settings->setValue("crossdevice/enabled", CrossDevice.isEnabled); }
|
||||
|
||||
void saveCrossDeviceEnabled()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("crossdevice/enabled", CrossDevice.isEnabled);
|
||||
settings.sync();
|
||||
}
|
||||
int loadEarDetectionSettings() { return m_settings->value("earDetection/setting", MediaController::EarDetectionBehavior::PauseWhenOneRemoved).toInt(); }
|
||||
void saveEarDetectionSettings() { m_settings->setValue("earDetection/setting", mediaController->getEarDetectionBehavior()); }
|
||||
|
||||
private slots:
|
||||
void onTrayIconActivated()
|
||||
@@ -836,7 +831,7 @@ private:
|
||||
MediaController* mediaController;
|
||||
TrayIconManager *trayManager;
|
||||
BluetoothMonitor *monitor;
|
||||
QSettings *settings;
|
||||
QSettings *m_settings;
|
||||
|
||||
QString m_batteryStatus;
|
||||
QString m_earDetectionStatus;
|
||||
|
||||
@@ -38,12 +38,20 @@ void MediaController::initializeMprisInterface() {
|
||||
}
|
||||
}
|
||||
|
||||
void MediaController::handleEarDetection(const QString &status) {
|
||||
void MediaController::handleEarDetection(const QString &status)
|
||||
{
|
||||
if (earDetectionBehavior == Disabled)
|
||||
{
|
||||
LOG_DEBUG("Ear detection is disabled, ignoring status");
|
||||
return;
|
||||
}
|
||||
|
||||
bool primaryInEar = false;
|
||||
bool secondaryInEar = false;
|
||||
|
||||
QStringList parts = status.split(", ");
|
||||
if (parts.size() == 2) {
|
||||
if (parts.size() == 2)
|
||||
{
|
||||
primaryInEar = parts[0].contains("In Ear");
|
||||
secondaryInEar = parts[1].contains("In Ear");
|
||||
}
|
||||
@@ -51,37 +59,68 @@ void MediaController::handleEarDetection(const QString &status) {
|
||||
LOG_DEBUG("Ear detection status: primaryInEar="
|
||||
<< primaryInEar << ", secondaryInEar=" << secondaryInEar
|
||||
<< ", isAirPodsActive=" << isActiveOutputDeviceAirPods());
|
||||
if (primaryInEar || secondaryInEar) {
|
||||
LOG_INFO("At least one AirPod is in ear");
|
||||
activateA2dpProfile();
|
||||
} else {
|
||||
LOG_INFO("Both AirPods are out of ear");
|
||||
removeAudioOutputDevice();
|
||||
|
||||
// First handle playback pausing based on selected behavior
|
||||
bool shouldPause = false;
|
||||
bool shouldResume = false;
|
||||
|
||||
if (earDetectionBehavior == PauseWhenOneRemoved)
|
||||
{
|
||||
shouldPause = !primaryInEar || !secondaryInEar;
|
||||
shouldResume = primaryInEar && secondaryInEar;
|
||||
}
|
||||
else if (earDetectionBehavior == PauseWhenBothRemoved)
|
||||
{
|
||||
shouldPause = !primaryInEar && !secondaryInEar;
|
||||
shouldResume = primaryInEar || secondaryInEar;
|
||||
}
|
||||
|
||||
if (primaryInEar && secondaryInEar) {
|
||||
if (wasPausedByApp && isActiveOutputDeviceAirPods()) {
|
||||
if (shouldPause && isActiveOutputDeviceAirPods())
|
||||
{
|
||||
QProcess process;
|
||||
process.start("playerctl", QStringList() << "status");
|
||||
process.waitForFinished();
|
||||
QString playbackStatus = process.readAllStandardOutput().trimmed();
|
||||
LOG_DEBUG("Playback status: " << playbackStatus);
|
||||
if (playbackStatus == "Playing")
|
||||
{
|
||||
pause();
|
||||
}
|
||||
}
|
||||
|
||||
// Then handle device profile switching
|
||||
if (primaryInEar || secondaryInEar)
|
||||
{
|
||||
LOG_INFO("At least one AirPod is in ear");
|
||||
activateA2dpProfile();
|
||||
|
||||
// Resume if conditions are met and we previously paused
|
||||
if (shouldResume && wasPausedByApp && isActiveOutputDeviceAirPods())
|
||||
{
|
||||
int result = QProcess::execute("playerctl", QStringList() << "play");
|
||||
LOG_DEBUG("Executed 'playerctl play' with result: " << result);
|
||||
if (result == 0) {
|
||||
if (result == 0)
|
||||
{
|
||||
LOG_INFO("Resumed playback via Playerctl");
|
||||
wasPausedByApp = false;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("Failed to resume playback via Playerctl");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isActiveOutputDeviceAirPods()) {
|
||||
QProcess process;
|
||||
process.start("playerctl", QStringList() << "status");
|
||||
process.waitForFinished();
|
||||
QString playbackStatus = process.readAllStandardOutput().trimmed();
|
||||
LOG_DEBUG("Playback status: " << playbackStatus);
|
||||
if (playbackStatus == "Playing") {
|
||||
pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("Both AirPods are out of ear");
|
||||
removeAudioOutputDevice();
|
||||
}
|
||||
}
|
||||
|
||||
void MediaController::setEarDetectionBehavior(EarDetectionBehavior behavior)
|
||||
{
|
||||
earDetectionBehavior = behavior;
|
||||
LOG_INFO("Set ear detection behavior to: " << behavior);
|
||||
}
|
||||
|
||||
void MediaController::followMediaChanges() {
|
||||
|
||||
@@ -6,14 +6,28 @@
|
||||
|
||||
class QProcess;
|
||||
|
||||
class MediaController : public QObject {
|
||||
class MediaController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum MediaState { Playing, Paused, Stopped };
|
||||
enum MediaState
|
||||
{
|
||||
Playing,
|
||||
Paused,
|
||||
Stopped
|
||||
};
|
||||
Q_ENUM(MediaState)
|
||||
enum EarDetectionBehavior
|
||||
{
|
||||
PauseWhenOneRemoved,
|
||||
PauseWhenBothRemoved,
|
||||
Disabled
|
||||
};
|
||||
Q_ENUM(EarDetectionBehavior)
|
||||
|
||||
explicit MediaController(QObject *parent = nullptr);
|
||||
~MediaController();
|
||||
|
||||
|
||||
void initializeMprisInterface();
|
||||
void handleEarDetection(const QString &status);
|
||||
void followMediaChanges();
|
||||
@@ -23,6 +37,9 @@ public:
|
||||
void removeAudioOutputDevice();
|
||||
void setConnectedDeviceMacAddress(const QString &macAddress);
|
||||
|
||||
void setEarDetectionBehavior(EarDetectionBehavior behavior);
|
||||
inline EarDetectionBehavior getEarDetectionBehavior() const { return earDetectionBehavior; }
|
||||
|
||||
void pause();
|
||||
|
||||
Q_SIGNALS:
|
||||
@@ -36,6 +53,7 @@ private:
|
||||
bool wasPausedByApp = false;
|
||||
int initialVolume = -1;
|
||||
QString connectedDeviceMacAddress;
|
||||
EarDetectionBehavior earDetectionBehavior = PauseWhenOneRemoved;
|
||||
};
|
||||
|
||||
#endif // MEDIACONTROLLER_H
|
||||
#endif // MEDIACONTROLLER_H
|
||||
Reference in New Issue
Block a user