Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android power management #1602

Merged
merged 1 commit into from
Feb 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion plugins/channelrx/heatmap/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ To view the Heat Map visually, the [Map Feature](../../feature/map/readme.md) sh

To record data for a heat map, a GPS is required, and Preferences > My Position should have "Auto-update from GPS" enabled.

On Android, GPS setup should be automatic. On Windows/Linux/Mac, a GPS supporting NMEA via a serial port at 4800 baud is required.
On Windows/Linux/Mac, a GPS supporting NMEA via a serial port at 4800 baud is required.
The COM port / serial device should be specfied via the QT_NMEA_SERIAL_PORT environment variable before SDRangel is started.

On Android, GPS setup should be automatic. GPS position updates may stop on Android when the screen is off. To keep the screen on, press the View > Keep Screen On menu.

![A Heat Map](../../../doc/img/HeatMap_plugin_map.png)

<h2>Interface</h2>
Expand Down
29 changes: 29 additions & 0 deletions sdrbase/maincore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include "device/deviceset.h"
#include "device/deviceapi.h"
#include "channel/channelapi.h"
#ifdef ANDROID
#include "util/android.h"
#endif

#include "maincore.h"

Expand Down Expand Up @@ -75,6 +78,9 @@ MainCore::MainCore()
m_masterElapsedTimer.start();
// Position can take a while to determine, so we start updates at program startup
initPosition();
#ifdef ANDROID
QObject::connect(this, &MainCore::deviceStateChanged, this, &MainCore::updateWakeLock);
#endif
}

MainCore::~MainCore()
Expand Down Expand Up @@ -394,3 +400,26 @@ void MainCore::positionError(QGeoPositionInfoSource::Error positioningError)
{
qWarning() << "MainCore::positionError: " << positioningError;
}

#ifdef ANDROID
// On Android, we want to prevent the app from being put to sleep, when any
// device is running
void MainCore::updateWakeLock()
{
bool running = false;
for (int i = 0; i < m_deviceSets.size(); i++)
{
if (m_deviceSets[i]->m_deviceAPI->state() == DeviceAPI::StRunning)
{
running = true;
break;
}
}
if (running) {
Android::acquireWakeLock();
} else {
Android::releaseWakeLock();
}
}
#endif

3 changes: 3 additions & 0 deletions sdrbase/maincore.h
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,9 @@ public slots:
void positionUpdated(const QGeoPositionInfo &info);
void positionUpdateTimeout();
void positionError(QGeoPositionInfoSource::Error positioningError);
#ifdef ANDROID
void updateWakeLock();
#endif

signals:
void deviceSetAdded(int index, DeviceAPI *device);
Expand Down
34 changes: 32 additions & 2 deletions sdrbase/util/android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ void Android::closeUSBDevice(int fd)
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
activity.callMethod<void>("closeUSBDevice", "(I)V", fd);
} else {
qCritical() << "MainCore::closeUSBDevice: activity is not valid.";
}
}
}
Expand All @@ -169,6 +167,38 @@ void Android::moveTaskToBack()
}
}

void Android::acquireWakeLock()
{
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
activity.callMethod<void>("acquireWakeLock");
}
}

void Android::releaseWakeLock()
{
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
activity.callMethod<void>("releaseWakeLock");
}
}

void Android::acquireScreenLock()
{
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
activity.callMethod<void>("acquireScreenLock");
}
}

void Android::releaseScreenLock()
{
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
activity.callMethod<void>("releaseScreenLock");
}
}

#endif // QT6

// Redirect qDebug/qWarning to Android log, so we can view remotely with adb
Expand Down
4 changes: 4 additions & 0 deletions sdrbase/util/android.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class SDRBASE_API Android
static void closeUSBDevice(int fd);
static void moveTaskToBack();
static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
static void acquireWakeLock();
static void releaseWakeLock();
static void acquireScreenLock();
static void releaseScreenLock();

};

Expand Down
17 changes: 17 additions & 0 deletions sdrgui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,12 @@ void MainWindow::createMenuBar(QToolButton *button)
fullscreenAction->setToolTip("Toggle fullscreen view");
fullscreenAction->setCheckable(true);
QObject::connect(fullscreenAction, &QAction::triggered, this, &MainWindow::on_action_View_Fullscreen_toggled);
#ifdef ANDROID
QAction *keepscreenonAction = viewMenu->addAction("&Keep screen on");
keepscreenonAction->setToolTip("Prevent screen from switching off");
keepscreenonAction->setCheckable(true);
QObject::connect(keepscreenonAction, &QAction::triggered, this, &MainWindow::on_action_View_KeepScreenOn_toggled);
#endif

QAction *newWorkspaceAction = workspacesMenu->addAction("&New");
newWorkspaceAction->setToolTip("Add a new workspace");
Expand Down Expand Up @@ -2183,6 +2189,17 @@ void MainWindow::removeEmptyWorkspaces()
#endif
}

#ifdef ANDROID
void MainWindow::on_action_View_KeepScreenOn_toggled(bool checked)
{
if (checked) {
Android::acquireScreenLock();
} else {
Android::releaseScreenLock();
}
}
#endif

void MainWindow::on_action_View_Fullscreen_toggled(bool checked)
{
if(checked) {
Expand Down
3 changes: 3 additions & 0 deletions sdrgui/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ private slots:
void handleMessages();
void handleWorkspaceVisibility(Workspace *workspace, bool visibility);

#ifdef ANDROID
void on_action_View_KeepScreenOn_toggled(bool checked);
#endif
void on_action_View_Fullscreen_toggled(bool checked);
void on_action_saveAll_triggered();
void on_action_Configurations_triggered();
Expand Down