1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2015 Dennis Nienhüser <nienhueser@kde.org>
4 //
5 
6 #include "MarbleMaps.h"
7 #include <FileManager.h>
8 
9 #include <MarbleModel.h>
10 #include <QGuiApplication>
11 
12 #ifdef Q_OS_ANDROID
13 #include <QtAndroid>
14 #include <QAndroidJniObject>
15 #include <qandroidfunctions.h>
16 #endif
17 
18 namespace Marble {
19 
MarbleMaps(QQuickItem * parent)20 MarbleMaps::MarbleMaps(QQuickItem *parent) :
21     MarbleQuickItem(parent),
22     m_suspended(false),
23     m_keepScreenOn(false)
24 {
25     QGuiApplication* application = qobject_cast<QGuiApplication*>(QGuiApplication::instance());
26     if (application) {
27         connect(application, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
28                 this, SLOT(handleApplicationStateChange(Qt::ApplicationState)));
29     }
30 
31 #ifdef Q_OS_ANDROID
32     QAndroidJniObject const activity = QtAndroid::androidActivity();
33     if (activity.isValid()) {
34         // Control music volume
35         int const STREAM_MUSIC = 3;
36         activity.callMethod<void>("setVolumeControlStream", "(I)V", STREAM_MUSIC);
37 
38         // If a file is passed, open it. Possible file types are registered in package/AndroidManifest.xml
39         QAndroidJniObject const intent = activity.callObjectMethod("getIntent", "()Landroid/content/Intent;");
40         if (intent.isValid()) {
41             QAndroidJniObject const data = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
42             if (data.isValid()) {
43                 QAndroidJniObject const path = data.callObjectMethod("getPath", "()Ljava/lang/String;");
44                 if (path.isValid()) {
45                     model()->addGeoDataFile(path.toString());
46                     connect( model()->fileManager(), SIGNAL(centeredDocument(GeoDataLatLonBox)), this, SLOT(centerOn(GeoDataLatLonBox)) );
47                 }
48             }
49         }
50     }
51 #endif
52 }
53 
isSuspended() const54 bool MarbleMaps::isSuspended() const
55 {
56     return m_suspended;
57 }
58 
keepScreenOn() const59 bool MarbleMaps::keepScreenOn() const
60 {
61     return m_keepScreenOn;
62 }
63 
setKeepScreenOn(bool screenOn)64 void MarbleMaps::setKeepScreenOn(bool screenOn)
65 {
66     if (m_keepScreenOn == screenOn) {
67         return;
68     }
69     m_keepScreenOn = screenOn;
70     char const * const action = m_keepScreenOn ? "addFlags" : "clearFlags";
71 #ifdef Q_OS_ANDROID
72   #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
73     QtAndroid::runOnAndroidThread([action](){
74     QAndroidJniObject activity = QtAndroid::androidActivity();
75     if (activity.isValid()) {
76         QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
77         if (window.isValid()) {
78             const int FLAG_KEEP_SCREEN_ON = 128;
79             window.callMethod<void>(action, "(I)V", FLAG_KEEP_SCREEN_ON);
80         }
81     }});
82   #else
83   #warning "Please upgrade to Qt for Android 5.7 or later to enable the keep-screen-on feature"
84   #endif
85 #else
86     Q_UNUSED(action);
87 #endif
88     emit keepScreenOnChanged(screenOn);
89 }
90 
handleApplicationStateChange(Qt::ApplicationState state)91 void MarbleMaps::handleApplicationStateChange(Qt::ApplicationState state)
92 {
93     if (state == Qt::ApplicationSuspended) {
94         m_suspended = true;
95         emit isSuspendedChanged(m_suspended);
96     } else if (state == Qt::ApplicationActive) {
97         m_suspended = false;
98         emit isSuspendedChanged(m_suspended);
99     }
100 }
101 
102 }
103 
104 #include "moc_MarbleMaps.cpp"
105