Make LenaPi usable on Android devices

- Add app icon
- prevend android device from shutting down cpu while playing music
- fix scaling bug
- fix energy saver for RasPi by reconnecting to music player
- minor refactorings and renaming
This commit is contained in:
Jan-Martin Raemer 2022-07-16 12:19:57 +02:00
parent 851b83a53a
commit 1f12d93300
19 changed files with 499 additions and 48 deletions

24
LenaPi/.qmake.stash Normal file
View file

@ -0,0 +1,24 @@
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 10
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 2
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 1
QMAKE_CXX.COMPILER_MACROS = \
QT_COMPILER_STDCXX \
QMAKE_GCC_MAJOR_VERSION \
QMAKE_GCC_MINOR_VERSION \
QMAKE_GCC_PATCH_VERSION
QMAKE_CXX.INCDIRS = \
/usr/arm-linux-gnueabihf/include/c++/10 \
/usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf \
/usr/arm-linux-gnueabihf/include/c++/10/backward \
/usr/lib/gcc-cross/arm-linux-gnueabihf/10/include \
/usr/arm-linux-gnueabihf/include \
/usr/include/arm-linux-gnueabihf \
/usr/include
QMAKE_CXX.LIBDIRS = \
/usr/lib/gcc-cross/arm-linux-gnueabihf/10 \
/usr/arm-linux-gnueabihf/lib \
/lib/arm-linux-gnueabihf \
/lib \
/usr/lib/arm-linux-gnueabihf \
/usr/lib

View file

@ -4,16 +4,35 @@
#include <QFileInfo> #include <QFileInfo>
#include <QProcess> #include <QProcess>
#include <iostream> #include <iostream>
EnergySaver::~EnergySaver()
{
#ifdef ANDROID
releaseAndroidLock();
#endif
}
void EnergySaver::init()
{
auto saver = instance();
saver->mIsAutoShutDownEnabled = false;
#ifdef ANDROID
saver->initAdroidLocks();
#endif
}
void EnergySaver::init(int interval, const QString &shutdownScript) void EnergySaver::init(int interval, const QString &shutdownScript)
{ {
auto saver = instance();
saver->mIsAutoShutDownEnabled = true;
QFileInfo script(shutdownScript); QFileInfo script(shutdownScript);
if(script.exists()){ if(script.exists()){
auto saver = instance();
saver->setShutdownScript(shutdownScript); saver->setShutdownScript(shutdownScript);
saver->initTimer(interval*1000); saver->initTimer(interval*1000);
saver->restartTimer(); saver->restartTimer();
} }
#ifdef ANDROID
saver->initAdroidLocks();
#endif
} }
@ -21,15 +40,32 @@ void EnergySaver::init(int interval, const QString &shutdownScript)
EnergySaver *EnergySaver::instance() EnergySaver *EnergySaver::instance()
{ {
static EnergySaver* inst; static EnergySaver* inst;
if (inst == nullptr) if (!inst)
{ {
inst = new EnergySaver(); inst = new EnergySaver();
} }
return inst; return inst;
} }
void EnergySaver::deactivate()
{
mIsActive = false;
mTimer.stop();
setAndroidLock();
}
void EnergySaver::activate()
{
mIsActive = true;
restartTimer();
releaseAndroidLock();
}
void EnergySaver::restartTimer() void EnergySaver::restartTimer()
{ {
// Energy saver is currently deactivated -> Do NOT start timer
if(!mIsActive) return;
if(mTimer.isActive()){ if(mTimer.isActive()){
mTimer.stop(); mTimer.stop();
} }
@ -49,9 +85,59 @@ void EnergySaver::setShutdownScript(const QString &shutdownScript)
mShutdownScript = shutdownScript; mShutdownScript = shutdownScript;
} }
void EnergySaver::initAdroidLocks()
{
#ifdef ANDROID
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if ( activity.isValid() )
{
QAndroidJniObject serviceName = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Context","POWER_SERVICE");
if ( serviceName.isValid() )
{
QAndroidJniObject powerMgr = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",serviceName.object<jobject>());
if ( powerMgr.isValid() )
{
jint levelAndFlags = QAndroidJniObject::getStaticField<jint>("android/os/PowerManager","SCREEN_DIM_WAKE_LOCK");
QAndroidJniObject tag = QAndroidJniObject::fromString( "My Tag" );
m_wakeLock = powerMgr.callObjectMethod("newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;", levelAndFlags,tag.object<jstring>());
}
}
}
#endif
}
void EnergySaver::setAndroidLock()
{
#ifdef ANDROID
if ( m_wakeLock.isValid() )
{
m_wakeLock.callMethod<void>("acquire", "()V");
qDebug() << "Locked device, can't go to standby anymore";
}
else
{
assert( false );
}
#endif
}
void EnergySaver::releaseAndroidLock()
{
#ifdef ANDROID
if ( m_wakeLock.isValid() )
{
m_wakeLock.callMethod<void>("release", "()V");
qDebug() << "Unlocked device, can now go to standby";
}
#endif
}
void EnergySaver::onTimeout() void EnergySaver::onTimeout()
{ {
if(!mIsAutoShutDownEnabled) return;
std::cout << "Shutting down."; std::cout << "Shutting down.";
#ifndef _DEBUG #ifndef _DEBUG
QProcess p; QProcess p;

View file

@ -4,27 +4,39 @@
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#ifdef ANDROID
#include <qandroidjniobject.h>
#endif
/** /**
* @brief Class handling energy saving options. * @brief Class handling energy saving options.
* *
* Shut down device if no mouse input is detected and music player * On Android devices, it locks the cpu shutdown while active. On other devices, it
* has not been active or a certain time interval. * will shut down device on timeout if the options are set accordingly and a shutdown script
* is provided.
* *
* @todo For now this does only work for Lena's RasPi, where the * In the context of the LenaPi application, it will prevent cpu shutdown on android devices while playing
* shutdown script is positioned in a ceratin hardcoded path. * music. On other devices, it will shutdown the device if no music has been playing and no mouse input was
* Enable/disable energy saving option, timeout and path of * detected for a certain time intervall.
* shutdown script via config
*/ */
class EnergySaver : public QObject class EnergySaver : public QObject
{ {
Q_OBJECT Q_OBJECT
protected: protected:
explicit EnergySaver(QObject *parent = nullptr) : QObject(parent) {} using QObject::QObject;
public: public:
~EnergySaver();
/**
* @brief Create instance if necessary. The instance will have auto shutdown disabeld.
*
* Used to prevent sleep on android devices.
*/
static void init();
/** /**
* @brief Create instance if necessary, configure it and start timer. * @brief Create instance if necessary, configure it and start timer.
* @param enabledAutoShutdown Defines whether device will shutdown on inactivity using shutdownScript
* @param interval Timer interval in seconds * @param interval Timer interval in seconds
* @param shutdownScript Path to shutdown script file * @param shutdownScript Path to shutdown script file
* @see EnergySaver::instance * @see EnergySaver::instance
@ -43,7 +55,19 @@ public:
public slots: public slots:
/** /**
* @brief Restart shutdown timer, e.g. because of music player activiti * @brief Deactivate energy saver, e.g., as music is currently playing
*
* Sets locks on adroid devics and stops shutdown-timer.
*/
void deactivate();
/**
* @brief Active energy saver
*
* Releases locks on android devices and restarts shutdown-timer if shutdown option is set.
*/
void activate();
/**
* @brief Restart shutdown timer, e.g. because of music player activity
*/ */
void restartTimer(); void restartTimer();
@ -54,8 +78,31 @@ private:
*/ */
void initTimer(int interval); void initTimer(int interval);
void setShutdownScript(const QString& shutdownScript); void setShutdownScript(const QString& shutdownScript);
/**
* @brief Initializes locking or Android devices
*/
void initAdroidLocks();
/**
* @brief Sets locks on Android devices to prevent sleep.
*
* Used to prevent cpu sleep as otherwise music will stop.
*/
void setAndroidLock();
/**
* @brief Releases locks on Android devices to allow the device's cpu to go into sleep mode.
*/
void releaseAndroidLock();
QTimer mTimer; QTimer mTimer;
QString mShutdownScript; QString mShutdownScript;
bool mIsActive{false};
bool mIsAutoShutDownEnabled{false};
#ifdef ANDROID
/**
* @brief Prevent energy saving for Android devices
*/
QAndroidJniObject m_wakeLock;
#endif
private slots: private slots:
/** /**
@ -63,6 +110,7 @@ private slots:
*/ */
void onTimeout(); void onTimeout();
}; };
#endif // ENERGYSAVER_H #endif // ENERGYSAVER_H

View file

@ -1,12 +1,16 @@
TEMPLATE = app TEMPLATE = app
linux:android {
QT += androidextras
ANDROID_PERMISSIONS += android.permission.WAKE_LOCK
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-files
QMAKE_CXXFLAGS += -DANDROID=1
}
QT += qml quick multimedia QT += qml quick multimedia
CONFIG += c++11 CONFIG += c++11
LIBS += LIBS +=
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-files
SOURCES += main.cpp \ SOURCES += main.cpp \
controllers/MusicPlayer.cpp \ controllers/MusicPlayer.cpp \
controllers/StyleController.cpp \ controllers/StyleHandling.cpp \
models/NavigationListModel.cpp \ models/NavigationListModel.cpp \
models/NavigationItemModel.cpp \ models/NavigationItemModel.cpp \
controllers/NavigationController.cpp \ controllers/NavigationController.cpp \
@ -42,7 +46,7 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin
HEADERS += \ HEADERS += \
controllers/MusicPlayer.h \ controllers/MusicPlayer.h \
controllers/StyleController.h \ controllers/StyleHandling.h \
models/MusicPlayer.h \ models/MusicPlayer.h \
models/NavigationListModel.h \ models/NavigationListModel.h \
models/NavigationItemModel.h \ models/NavigationItemModel.h \

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 7.0.1, 2022-06-01T19:47:32. --> <!-- Written by QtCreator 7.0.1, 2022-07-15T15:40:08. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>
@ -87,6 +87,250 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Target.0</variable> <variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="DeviceType">GenericLinuxOsType</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">armhf/raspi 10.0.1.146</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">armhf/raspi 10.0.1.146</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{9f02fab2-7f72-4b24-bbd8-dbe33e863260}</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Debug</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Debug</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Release</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Release</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
<value type="int" key="EnableQmlDebugging">0</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Profile</value>
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/home/jmr/privat/src/LenaPi/build-LenaPi-Unnamed-Profile</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="int" key="SeparateDebugInfo">0</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CheckForFreeDiskSpaceStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<value type="QString" key="RemoteLinux.CheckForFreeDiskSpaceStep.PathToCheck">/</value>
<value type="qlonglong" key="RemoteLinux.CheckForFreeDiskSpaceStep.RequiredSpace">5242880</value>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.KillAppStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.RsyncDeployStep</value>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
<value type="QString" key="RemoteLinux.RsyncDeployStep.Flags">-av</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">3</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">DeployToGenericLinux</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="QString">0</value>
<value type="QString">1</value>
<value type="QString">2</value>
<value type="QString">3</value>
<value type="QString">4</value>
<value type="QString">5</value>
<value type="QString">6</value>
<value type="QString">7</value>
<value type="QString">8</value>
<value type="QString">9</value>
<value type="QString">10</value>
<value type="QString">11</value>
<value type="QString">12</value>
<value type="QString">13</value>
<value type="QString">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.1">
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="QString">0</value>
<value type="QString">1</value>
<value type="QString">2</value>
<value type="QString">3</value>
<value type="QString">4</value>
<value type="QString">5</value>
<value type="QString">6</value>
<value type="QString">7</value>
<value type="QString">8</value>
<value type="QString">9</value>
<value type="QString">10</value>
<value type="QString">11</value>
<value type="QString">12</value>
<value type="QString">13</value>
<value type="QString">14</value>
</valuelist>
<valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">1</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">RemoteLinux.CustomRunConfig</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
<value type="int" key="RemoteLinux.EnvironmentAspect.Version">1</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.X11Forwarding">:0.0</value>
</valuemap>
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">2</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.Target.1</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Android.Device.Type</value> <value type="QString" key="DeviceType">Android.Device.Type</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android Qt 5.15.2 (android) Clang Multi-Abi</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android Qt 5.15.2 (android) Clang Multi-Abi</value>
@ -309,7 +553,6 @@
<valuelist type="QVariantList" key="CustomOutputParsers"/> <valuelist type="QVariantList" key="CustomOutputParsers"/>
<value type="int" key="PE.EnvironmentAspect.Base">0</value> <value type="int" key="PE.EnvironmentAspect.Base">0</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/> <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">LenaPi</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidRunConfiguration:/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidRunConfiguration:/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value> <value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">/home/jmr/privat/src/LenaPi/LenaPi/LenaPi.pro</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value> <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
@ -321,7 +564,7 @@
</valuemap> </valuemap>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Target.1</variable> <variable>ProjectExplorer.Project.Target.2</variable>
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value type="QString" key="DeviceType">Desktop</value> <value type="QString" key="DeviceType">Desktop</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">desktop</value> <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">desktop</value>
@ -492,7 +735,7 @@
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.TargetCount</variable> <variable>ProjectExplorer.Project.TargetCount</variable>
<value type="qlonglong">2</value> <value type="qlonglong">3</value>
</data> </data>
<data> <data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable> <variable>ProjectExplorer.Project.Updater.FileVersion</variable>

View file

@ -12,7 +12,7 @@ void MouseEventSpy::init()
MouseEventSpy* MouseEventSpy::instance() MouseEventSpy* MouseEventSpy::instance()
{ {
static MouseEventSpy* inst; static MouseEventSpy* inst;
if (inst == nullptr) if (!inst)
{ {
inst = new MouseEventSpy(); inst = new MouseEventSpy();
QGuiApplication* app = qGuiApp; QGuiApplication* app = qGuiApp;

View file

@ -15,7 +15,7 @@
<uses-feature android:name="android.hardware.microphone" android:required="false"/> <uses-feature android:name="android.hardware.microphone" android:required="false"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/> <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="LenaPi" android:extractNativeLibs="true"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="LenaPi" android:extractNativeLibs="true" android:icon="@drawable/icon">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="LenaPi" android:screenOrientation="landscape" android:launchMode="singleTop"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="LenaPi" android:screenOrientation="landscape" android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
@ -81,4 +81,6 @@
<!-- %%INSERT_PERMISSIONS --> <!-- %%INSERT_PERMISSIONS -->
<!-- %%INSERT_FEATURES --> <!-- %%INSERT_FEATURES -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.PERSISTENT_ACTIVITY"/>
</manifest> </manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View file

@ -3,6 +3,7 @@
#include <QDir> #include <QDir>
#include <QDebug> #include <QDebug>
#include <EnergySaver.h>
#include <models/NavigationItemModel.h> #include <models/NavigationItemModel.h>
#include <models/NavigationListModel.h> #include <models/NavigationListModel.h>
@ -19,6 +20,9 @@ NavigationController::NavigationController(QObject *parent) : QObject(parent),
mUiState->showNavigation(); mUiState->showNavigation();
mNavList->navigateTo(item); mNavList->navigateTo(item);
}); });
/* Connect player state to energy saver to prevent device shutdown while playing music.
*/
connect(mMediaPlayer, &MusicPlayer::isPlayingChanged, this, &NavigationController::startOrStopEnergySaverDependingOnPlayerState);
} }
void NavigationController::setDebugOutput(const QString& text) void NavigationController::setDebugOutput(const QString& text)
@ -111,3 +115,16 @@ void NavigationController::onNavigationRequest()
mUiState->showMusicPlayer(); mUiState->showMusicPlayer();
} }
} }
void NavigationController::startOrStopEnergySaverDependingOnPlayerState()
{
auto* energySaver = EnergySaver::instance();
assert(energySaver);
if(energySaver){
if(mMediaPlayer->isPlaying()){
energySaver->deactivate();
} else {
energySaver->activate();
}
}
}

View file

@ -86,6 +86,7 @@ private slots:
* @brief Either show subdirectories or music player depending on current directory type * @brief Either show subdirectories or music player depending on current directory type
*/ */
void onNavigationRequest(); void onNavigationRequest();
void startOrStopEnergySaverDependingOnPlayerState();
}; };
#endif // NAVIGATIONCONTROLLER_H #endif // NAVIGATIONCONTROLLER_H

View file

@ -1,27 +1,29 @@
#include "StyleController.h" #include "StyleHandling.h"
#include <QGuiApplication> #include <QGuiApplication>
#include <QScreen> #include <QScreen>
#include <QDebug>
StyleController::StyleController(QObject *parent) StyleHandling::StyleHandling(QObject *parent)
: QObject{parent}, mStyleSizes(new QQmlPropertyMap(this)), : QObject{parent}, mStyleSizes(new QQmlPropertyMap(this)),
mMargins(new QQmlPropertyMap(this)), mSpacings(new QQmlPropertyMap(this)), mPaddings(new QQmlPropertyMap(this)) mMargins(new QQmlPropertyMap(this)), mSpacings(new QQmlPropertyMap(this)), mPaddings(new QQmlPropertyMap(this))
{ {
// nothing // nothing
} }
void StyleController::calculateAndSetRatio() void StyleHandling::calculateAndSetRatio()
{ {
qreal refHeight = 480; qreal refHeight = 480;
qreal refWidth = 800; qreal refWidth = 800;
// Scales to fullscreen. No rescaling when changing window size // Scales to fullscreen. No rescaling when changing window size
QRect rect = QGuiApplication::primaryScreen()->geometry(); QRect rect = QGuiApplication::primaryScreen()->geometry();
qreal height = qMax(rect.width(),rect.height()); qreal height = qMin(rect.width(),rect.height());
qreal width = qMin(rect.width(), rect.height()); qreal width = qMax(rect.width(), rect.height());
mRatio = qMin(height/refHeight, width/refWidth); mRatio = qMin(height/refHeight, width/refWidth);
qDebug() << "mRation=" << mRatio<< "sizes="<<width<<", "<< height<<"\n";
} }
void StyleController::initStyleSizes() void StyleHandling::initStyleSizes()
{ {
scaleAndInsert(mStyleSizes, "roundButtonDefaultSize", 65); scaleAndInsert(mStyleSizes, "roundButtonDefaultSize", 65);
scaleAndInsert(mStyleSizes, "roundButtonBorderWidth", 2); scaleAndInsert(mStyleSizes, "roundButtonBorderWidth", 2);
@ -43,14 +45,14 @@ void StyleController::initStyleSizes()
} }
void StyleController::initSpacings() void StyleHandling::initSpacings()
{ {
scaleAndInsert(mSpacings, "defaultSpacing", 20); scaleAndInsert(mSpacings, "defaultSpacing", 20);
scaleAndInsert(mSpacings, "smallSpacing", 10); scaleAndInsert(mSpacings, "smallSpacing", 10);
scaleAndInsert(mSpacings, "tinySpacing", 5); scaleAndInsert(mSpacings, "tinySpacing", 5);
} }
void StyleController::initMargins() void StyleHandling::initMargins()
{ {
scaleAndInsert(mMargins, "defaultMargin", 20); scaleAndInsert(mMargins, "defaultMargin", 20);
scaleAndInsert(mMargins, "smallMargin", 10); scaleAndInsert(mMargins, "smallMargin", 10);
@ -58,22 +60,22 @@ void StyleController::initMargins()
scaleAndInsert(mMargins, "scrollHandleMargins", 1); scaleAndInsert(mMargins, "scrollHandleMargins", 1);
} }
void StyleController::initPaddings() void StyleHandling::initPaddings()
{ {
scaleAndInsert(mPaddings, "defaultPadding", 5); scaleAndInsert(mPaddings, "defaultPadding", 5);
} }
void StyleController::scaleAndInsert(QQmlPropertyMap *map, const QString &key, int value) void StyleHandling::scaleAndInsert(QQmlPropertyMap *map, const QString &key, int value)
{ {
map->insert(key, applyRatio(value)); map->insert(key, applyRatio(value));
} }
int StyleController::applyRatio(int size) const int StyleHandling::applyRatio(int size) const
{ {
return size*mRatio; return size*mRatio;
} }
void StyleController::init(QQmlContext *context) void StyleHandling::init(QQmlContext *context)
{ {
calculateAndSetRatio(); calculateAndSetRatio();
initStyleSizes(); initStyleSizes();

View file

@ -1,5 +1,5 @@
#ifndef STYLECONTROLLER_H #ifndef STYLEHANDLING_H
#define STYLECONTROLLER_H #define STYLEHANDLING_H
#include <QObject> #include <QObject>
#include <QQmlContext> #include <QQmlContext>
@ -20,11 +20,11 @@
* @todo scale fonts as well? * @todo scale fonts as well?
* @todo use dpi for scaling as app is very small on Android? * @todo use dpi for scaling as app is very small on Android?
*/ */
class StyleController : public QObject class StyleHandling : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit StyleController(QObject *parent = nullptr); explicit StyleHandling(QObject *parent = nullptr);
/** /**
* @brief Calculates ratio, initializes all maps and registers them in QML context * @brief Calculates ratio, initializes all maps and registers them in QML context
@ -78,4 +78,4 @@ private:
QQmlPropertyMap* mPaddings = nullptr; QQmlPropertyMap* mPaddings = nullptr;
}; };
#endif // STYLECONTROLLER_H #endif // STYLEHANDLING_H

View file

@ -4,18 +4,20 @@
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QFileInfo> #include <QFileInfo>
#include <QDebug> #include <QDebug>
#include <controllers/StyleController.h> #include <controllers/StyleHandling.h>
#include "controllers/NavigationController.h" #include <controllers/NavigationController.h>
#include <controllers/SettingsHandler.h>
#include "MouseEventSpy.h" #include "MouseEventSpy.h"
#include "EnergySaver.h" #include "EnergySaver.h"
#include "controllers/SettingsHandler.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QGuiApplication app(argc, argv); QGuiApplication app(argc, argv);
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
/****************************************************************************
* Configure and parse commandline arguments
****************************************************************************/
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription("Lena's music app"); parser.setApplicationDescription("Lena's music app");
// Define a custom config file using -c or --config // Define a custom config file using -c or --config
@ -25,6 +27,12 @@ int main(int argc, char *argv[])
// process commandline arguments // process commandline arguments
parser.process(app); parser.process(app);
/****************************************************************************
* Find and read settings
* If a config file is handed over via commandline arguments, it is preferred.
* Otherwise, the config in the standard location is used. If none exists yet,
* a default config is created.
****************************************************************************/
QSettings* settings = nullptr; QSettings* settings = nullptr;
if(!parser.value(configOption).isEmpty()){ if(!parser.value(configOption).isEmpty()){
// config was handed over via commandline argument. Use this config if file exists. // config was handed over via commandline argument. Use this config if file exists.
@ -35,23 +43,35 @@ int main(int argc, char *argv[])
} }
} }
if(!settings){ if(!settings){
// default config // create config from default location
settings = new QSettings(QSettings::Scope::UserScope, "MaleyanaSoft", "LenaPi"); settings = new QSettings(QSettings::Scope::UserScope, "MaleyanaSoft", "LenaPi");
} }
/* Read Settings */ // Read Settings
const auto settingsHandler = SettingsHandler::createSettingsHandlerAndFillWithDefaultsIfMissing(settings); const auto settingsHandler = SettingsHandler::createSettingsHandlerAndFillWithDefaultsIfMissing(settings);
// init style /****************************************************************************
StyleController styleController; * init style
styleController.init(engine.rootContext()); * Sets default sizes for ui elements. The element size is scaled according
// init main app * to the device's display size.
****************************************************************************/
StyleHandling styleHandler;
styleHandler.init(engine.rootContext());
/****************************************************************************
* init main app
****************************************************************************/
NavigationController navController; NavigationController navController;
navController.setContext(engine.rootContext()); navController.setContext(engine.rootContext());
navController.init(settingsHandler->getRootPath()); navController.init(settingsHandler->getRootPath());
navController.setUiProfile(settingsHandler->getProfile()); navController.setUiProfile(settingsHandler->getProfile());
/****************************************************************************
* init energy saver
* Prevents sleep on android devices and shuts down other device if inactive
* (no music or mouse events) for a certain time intervall
****************************************************************************/
if(settingsHandler->isEnergySaverEnabled()){ if(settingsHandler->isEnergySaverEnabled()){
/* install MouseEventSpy and energy saver used for auto shut down of device /* install MouseEventSpy and energy saver used for auto shut down of device
* if not used for a predefined time. * if not used for a predefined time.
@ -60,9 +80,13 @@ int main(int argc, char *argv[])
EnergySaver::init(settingsHandler->getEnergySaverTimeout(), settingsHandler->getShutdownScript()); EnergySaver::init(settingsHandler->getEnergySaverTimeout(), settingsHandler->getShutdownScript());
QObject::connect(MouseEventSpy::instance(), &MouseEventSpy::mouseEventDetected, QObject::connect(MouseEventSpy::instance(), &MouseEventSpy::mouseEventDetected,
EnergySaver::instance(), &EnergySaver::restartTimer); EnergySaver::instance(), &EnergySaver::restartTimer);
} else {
EnergySaver::init();
} }
// load GUI /****************************************************************************
* load view
****************************************************************************/
engine.load(QUrl("qrc:/main.qml")); engine.load(QUrl("qrc:/main.qml"));
return app.exec(); return app.exec();

BIN
LenaPi/resources/icon.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB