From 7c38ca387cf3e9aa6d7f47a00b296247da102147 Mon Sep 17 00:00:00 2001
From: BogDan Vatra <bogdan@kdab.com>
Date: Tue, 4 Jul 2017 14:13:29 +0300
Subject: [PATCH] Say hello to low level Android Service & Binder
 implementations

These are the building blocks for higher level APIs such as Qt Remote
Objects.

[ChangeLog][Android] Added low level APIs for Android Service & Binder.

Change-Id: I320214d310a398541bbde985ecf67bf6101c0b67
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
---
 src/androidextras/android/android.pri         |  18 +-
 src/androidextras/android/qandroidbinder.cpp  | 164 ++++++++++++
 src/androidextras/android/qandroidbinder.h    |  80 ++++++
 src/androidextras/android/qandroidbinder_p.h  |  77 ++++++
 .../android/qandroidfunctions.cpp             |  66 +++++
 src/androidextras/android/qandroidfunctions.h |  22 ++
 src/androidextras/android/qandroidintent.cpp  | 164 ++++++++++++
 src/androidextras/android/qandroidintent.h    |  70 +++++
 src/androidextras/android/qandroidparcel.cpp  | 243 ++++++++++++++++++
 src/androidextras/android/qandroidparcel.h    |  78 ++++++
 src/androidextras/android/qandroidparcel_p.h  |  78 ++++++
 src/androidextras/android/qandroidservice.cpp | 143 +++++++++++
 src/androidextras/android/qandroidservice.h   |  72 ++++++
 .../android/qandroidserviceconnection.cpp     | 117 +++++++++
 .../android/qandroidserviceconnection.h       |  66 +++++
 src/androidextras/android/qjnionload.cpp      | 111 ++++++++
 src/androidextras/androidextras.pro           |   5 +
 .../jni/qandroidjnienvironment.cpp            |  58 +++++
 .../jni/qandroidjnienvironment.h              |  17 ++
 src/jar/AndroidManifest.xml                   |   6 +
 src/jar/bundledjar.pro                        |   3 +
 src/jar/distributedjar.pro                    |   2 +
 src/jar/jar.pri                               |  14 +
 src/jar/jar.pro                               |   3 +
 .../qt5/android/extras/QtAndroidBinder.java   |  69 +++++
 .../extras/QtAndroidServiceConnection.java    |  78 ++++++
 .../qt5/android/extras/QtNative.java          |  55 ++++
 src/src.pro                                   |   2 +-
 28 files changed, 1878 insertions(+), 3 deletions(-)
 create mode 100644 src/androidextras/android/qandroidbinder.cpp
 create mode 100644 src/androidextras/android/qandroidbinder.h
 create mode 100644 src/androidextras/android/qandroidbinder_p.h
 create mode 100644 src/androidextras/android/qandroidintent.cpp
 create mode 100644 src/androidextras/android/qandroidintent.h
 create mode 100644 src/androidextras/android/qandroidparcel.cpp
 create mode 100644 src/androidextras/android/qandroidparcel.h
 create mode 100644 src/androidextras/android/qandroidparcel_p.h
 create mode 100644 src/androidextras/android/qandroidservice.cpp
 create mode 100644 src/androidextras/android/qandroidservice.h
 create mode 100644 src/androidextras/android/qandroidserviceconnection.cpp
 create mode 100644 src/androidextras/android/qandroidserviceconnection.h
 create mode 100644 src/androidextras/android/qjnionload.cpp
 create mode 100644 src/jar/AndroidManifest.xml
 create mode 100644 src/jar/bundledjar.pro
 create mode 100644 src/jar/distributedjar.pro
 create mode 100644 src/jar/jar.pri
 create mode 100644 src/jar/jar.pro
 create mode 100644 src/jar/src/org/qtproject/qt5/android/extras/QtAndroidBinder.java
 create mode 100644 src/jar/src/org/qtproject/qt5/android/extras/QtAndroidServiceConnection.java
 create mode 100644 src/jar/src/org/qtproject/qt5/android/extras/QtNative.java

diff --git a/src/androidextras/android/android.pri b/src/androidextras/android/android.pri
index b86d380..4f99c14 100644
--- a/src/androidextras/android/android.pri
+++ b/src/androidextras/android/android.pri
@@ -1,7 +1,21 @@
 SOURCES += \
            $$PWD/qandroidfunctions.cpp \
-           $$PWD/qandroidactivityresultreceiver.cpp
+           $$PWD/qandroidactivityresultreceiver.cpp \
+           $$PWD/qandroidservice.cpp \
+           $$PWD/qandroidbinder.cpp \
+           $$PWD/qandroidparcel.cpp \
+           $$PWD/qandroidintent.cpp \
+           $$PWD/qjnionload.cpp \
+           $$PWD/qandroidserviceconnection.cpp
+
 HEADERS += \
            $$PWD/qandroidfunctions.h \
            $$PWD/qandroidactivityresultreceiver.h \
-           $$PWD/qandroidactivityresultreceiver_p.h
+           $$PWD/qandroidactivityresultreceiver_p.h \
+           $$PWD/qandroidservice.h \
+           $$PWD/qandroidbinder.h \
+           $$PWD/qandroidparcel.h \
+           $$PWD/qandroidbinder_p.h \
+           $$PWD/qandroidintent.h \
+           $$PWD/qandroidparcel_p.h \
+           $$PWD/qandroidserviceconnection.h
diff --git a/src/androidextras/android/qandroidbinder.cpp b/src/androidextras/android/qandroidbinder.cpp
new file mode 100644
index 0000000..76ae57a
--- /dev/null
+++ b/src/androidextras/android/qandroidbinder.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidbinder.h"
+
+#include "qandroidbinder_p.h"
+#include "qandroidparcel.h"
+#include "qandroidparcel_p.h"
+
+#include <jni/qandroidjnienvironment.h>
+
+QT_BEGIN_NAMESPACE
+QAndroidBinderPrivate::QAndroidBinderPrivate(QAndroidBinder *binder)
+    : handle("org/qtproject/qt5/android/extras/QtAndroidBinder", "(J)V", jlong(binder))
+    , m_isQtAndroidBinder(true)
+{
+    QAndroidJniExceptionCleaner cleaner;
+}
+
+QAndroidBinderPrivate::QAndroidBinderPrivate(const QAndroidJniObject &binder)
+    : handle(binder)
+    , m_isQtAndroidBinder(false)
+{
+}
+
+QAndroidBinderPrivate::~QAndroidBinderPrivate()
+{
+    if (m_isQtAndroidBinder) {
+        QAndroidJniExceptionCleaner cleaner;
+        handle.callMethod<void>("setId", "(J)V", jlong(0));
+        if (m_deleteListener)
+            m_deleteListener();
+    }
+}
+
+/*!
+    \class QAndroidBinder
+    \inmodule QtAndroidExtras
+    The QAndroidBinder is a convenience class that wraps the most important
+           \l {https://developer.android.com/reference/android/os/Binder.html} {Android Binder} methods.
+    \since 5.10
+*/
+
+
+/*!
+    \enum QAndroidBinder::CallType
+
+    This enum is used with \l QAndroidBinder::transact() to describe the mode in which the
+    IPC call is performed.
+
+    \value Normal normal IPC, meaning that the caller waits the result from the callee
+    \value OneWay one-way IPC, meaning that the caller returns immediately, without waiting for a result from the callee
+*/
+
+/*!
+    Creates a new object which can be used to perform IPC.
+
+    \sa onTransact, transact
+ */
+QAndroidBinder::QAndroidBinder()
+    : d(new QAndroidBinderPrivate(this))
+{
+}
+
+/*!
+    Creates a new object from the \a binder Java object.
+
+    \sa transact
+ */
+QAndroidBinder::QAndroidBinder(const QAndroidJniObject &binder)
+    : d(new QAndroidBinderPrivate(binder))
+{
+}
+
+QAndroidBinder::~QAndroidBinder()
+{
+}
+
+/*!
+    Default implementation is a stub that returns false.
+    The user should override this method to get the transact data from the caller.
+
+    The \a code is the action to perform.
+    The \a data is the marshaled data sent by the caller.\br
+    The \a reply is the marshaled data to be sent to the caller.\br
+    The \a flags are the additional operation flags.\br
+
+    \warning This method is called from Binder's thread which is different
+    from the thread that this object was created.
+
+    \sa transact
+ */
+bool QAndroidBinder::onTransact(int /*code*/, const QAndroidParcel &/*data*/, const QAndroidParcel &/*reply*/, CallType /*flags*/)
+{
+    return false;
+}
+
+/*!
+    Performs an IPC call
+
+    The \a code is the action to perform. Should be between
+                \l {https://developer.android.com/reference/android/os/IBinder.html#FIRST_CALL_TRANSACTION}
+                {FIRST_CALL_TRANSACTION} and
+                \l {https://developer.android.com/reference/android/os/IBinder.html#LAST_CALL_TRANSACTION}
+                {LAST_CALL_TRANSACTION}.\br
+    The \a data is the marshaled data to send to the target.\br
+    The \a reply (if specified) is the marshaled data to be received from the target.
+    May be \b nullptr if you are not interested in the return value.\br
+    The \a flags are the additional operation flags.\br
+
+    \return true on success
+ */
+bool QAndroidBinder::transact(int code, const QAndroidParcel &data, QAndroidParcel *reply, CallType flags) const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    return d->handle.callMethod<jboolean>("transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z",
+                                   jint(code), data.d->handle.object(), reply ? reply->d->handle.object() : nullptr, jint(flags));
+}
+
+/*!
+    The return value is useful to call other Java API which are not covered by this wrapper
+ */
+QAndroidJniObject QAndroidBinder::handle() const
+{
+    return d->handle;
+}
+
+QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidbinder.h b/src/androidextras/android/qandroidbinder.h
new file mode 100644
index 0000000..1e73e7d
--- /dev/null
+++ b/src/androidextras/android/qandroidbinder.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDBINDER_H
+#define QANDROIDBINDER_H
+
+#include <QtAndroidExtras/qandroidextrasglobal.h>
+#include <QSharedPointer>
+
+#include <jni.h>
+
+QT_BEGIN_NAMESPACE
+class QAndroidBinderPrivate;
+class QAndroidParcel;
+class QAndroidJniObject;
+
+class Q_ANDROIDEXTRAS_EXPORT QAndroidBinder
+{
+public:
+    enum class CallType {
+        Normal = 0,
+        OneWay = 1
+    };
+
+public:
+    explicit QAndroidBinder();
+    QAndroidBinder(const QAndroidJniObject &binder);
+
+    virtual ~QAndroidBinder();
+
+    virtual bool onTransact(int code, const QAndroidParcel &data, const QAndroidParcel &reply, CallType flags);
+    bool transact(int code, const QAndroidParcel &data, QAndroidParcel *reply = nullptr, CallType flags = CallType::Normal) const;
+
+    QAndroidJniObject handle() const;
+
+private:
+    friend class QAndroidBinderPrivate;
+    friend class QAndroidParcelPrivate;
+    friend class QAndroidServicePrivate;
+    QSharedPointer<QAndroidBinderPrivate> d;
+};
+QT_END_NAMESPACE
+
+#endif // QANDROIDBINDER_H
diff --git a/src/androidextras/android/qandroidbinder_p.h b/src/androidextras/android/qandroidbinder_p.h
new file mode 100644
index 0000000..b132b33
--- /dev/null
+++ b/src/androidextras/android/qandroidbinder_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDBINDER_P_H
+#define QANDROIDBINDER_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qandroidjniobject.h"
+
+#include <functional>
+#include <jni.h>
+
+QT_BEGIN_NAMESPACE
+class QAndroidBinder;
+class QAndroidBinderPrivate
+{
+public:
+    explicit QAndroidBinderPrivate(QAndroidBinder *binder);
+    explicit QAndroidBinderPrivate(const QAndroidJniObject &binder);
+    void setDeleteListener(const std::function<void()> &func) { m_deleteListener = func; }
+    ~QAndroidBinderPrivate();
+
+private:
+    QAndroidJniObject handle;
+    std::function<void()> m_deleteListener;
+    bool m_isQtAndroidBinder;
+    friend class QAndroidBinder;
+};
+QT_END_NAMESPACE
+
+#endif // QANDROIDBINDER_P_H
diff --git a/src/androidextras/android/qandroidfunctions.cpp b/src/androidextras/android/qandroidfunctions.cpp
index 6fc7ed3..f22ed9b 100644
--- a/src/androidextras/android/qandroidfunctions.cpp
+++ b/src/androidextras/android/qandroidfunctions.cpp
@@ -1,5 +1,6 @@
 /****************************************************************************
 **
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
 ** Copyright (C) 2016 The Qt Company Ltd.
 ** Contact: https://www.qt.io/licensing/
 **
@@ -40,10 +41,14 @@
 #include "qandroidfunctions.h"
 #include "qandroidactivityresultreceiver.h"
 #include "qandroidactivityresultreceiver_p.h"
+#include "qandroidintent.h"
+#include "qandroidserviceconnection.h"
 
 #include <QtCore/private/qjni_p.h>
 #include <QtCore/private/qjnihelpers_p.h>
 
+#include <jni/qandroidjnienvironment.h>
+
 QT_BEGIN_NAMESPACE
 
 /*!
@@ -54,6 +59,43 @@ QT_BEGIN_NAMESPACE
     \inheaderfile QtAndroid
 */
 
+/*!
+    \since 5.10
+    \enum QtAndroid::BindFlag
+
+    This enum is used with QtAndroid::bindService to describe the mode in which the
+    binding is performed.
+
+    \value None                 No options.
+    \value AutoCreate           Automatically creates the service as long as the binding exist.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_AUTO_CREATE}
+                                {BIND_AUTO_CREATE} documentation for more details.
+    \value DebugUnbind          Include debugging help for mismatched calls to unbind.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_DEBUG_UNBIND}
+                                {BIND_DEBUG_UNBIND} documentation for more details.
+    \value NotForeground        Don't allow this binding to raise the target service's process to the foreground scheduling priority.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_NOT_FOREGROUND}
+                                {BIND_NOT_FOREGROUND} documentation for more details.
+    \value AboveClient          Indicates that the client application binding to this service considers the service to be more important than the app itself.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT}
+                                {BIND_ABOVE_CLIENT} documentation for more details.
+    \value AllowOomManagement   Allow the process hosting the bound service to go through its normal memory management.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_ALLOW_OOM_MANAGEMENT}
+                                {BIND_ALLOW_OOM_MANAGEMENT} documentation for more details.
+    \value WaivePriority        Don't impact the scheduling or memory management priority of the target service's hosting process.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_WAIVE_PRIORITY}
+                                {BIND_WAIVE_PRIORITY} documentation for more details.
+    \value Important            This service is assigned a higher priority so that it is available to the client when needed.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_IMPORTANT}
+                                {BIND_IMPORTANT} documentation for more details.
+    \value AdjustWithActivity   If binding from an activity, allow the target service's process importance to be raised based on whether the activity is visible to the user.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_ADJUST_WITH_ACTIVITY}
+                                {BIND_ADJUST_WITH_ACTIVITY} documentation for more details.
+    \value ExternalService      The service being bound is an isolated, external service.
+                                See \l {https://developer.android.com/reference/android/content/Context.html#BIND_EXTERNAL_SERVICE}
+                                {BIND_EXTERNAL_SERVICE} documentation for more details.
+*/
+
 /*!
     \since 5.3
     \fn QAndroidJniObject QtAndroid::androidActivity()
@@ -255,4 +297,28 @@ void QtAndroid::hideSplashScreen(int duration)
     QtAndroidPrivate::hideSplashScreen(QJNIEnvironmentPrivate(), duration);
 }
 
+
+/*!
+    \since 5.10
+    \fn bool QtAndroid::bindService(const QAndroidIntent &serviceIntent, const QAndroidServiceConnection &serviceConnection, BindFlags flags = BindFlag::None)
+
+    Binds the service given by \a serviceIntent, \a serviceConnection and \a flags.
+    The \a serviceIntent object identifies the service to connect to.
+    The \a serviceConnection is a listener that receives the information as the service is started and stopped.
+
+    \return true on success
+
+    See \l {https://developer.android.com/reference/android/content/Context.html#bindService%28android.content.Intent,%20android.content.ServiceConnection,%20int%29}
+    {Android documentation} documentation for more details.
+
+    \sa QAndroidIntent, QAndroidServiceConnection, BindFlag
+*/
+bool QtAndroid::bindService(const QAndroidIntent &serviceIntent,
+                            const QAndroidServiceConnection &serviceConnection, BindFlags flags)
+{
+    QAndroidJniExceptionCleaner cleaner;
+    return androidContext().callMethod<jboolean>("bindService", "(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z",
+                                                 serviceIntent.handle().object(), serviceConnection.handle().object(), jint(flags));
+}
+
 QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidfunctions.h b/src/androidextras/android/qandroidfunctions.h
index 7095c1b..c5023f4 100644
--- a/src/androidextras/android/qandroidfunctions.h
+++ b/src/androidextras/android/qandroidfunctions.h
@@ -52,6 +52,9 @@
 QT_BEGIN_NAMESPACE
 
 class QAndroidActivityResultReceiver;
+class QAndroidServiceConnection;
+class QAndroidIntent;
+
 namespace QtAndroid
 {
     Q_ANDROIDEXTRAS_EXPORT QAndroidJniObject androidActivity();
@@ -66,6 +69,25 @@ namespace QtAndroid
                                               int receiverRequestCode,
                                               QAndroidActivityResultReceiver *resultReceiver = nullptr);
 
+    enum class BindFlag {
+        None                = 0x00000000,
+        AutoCreate          = 0x00000001,
+        DebugUnbind         = 0x00000002,
+        NotForeground       = 0x00000004,
+        AboveClient         = 0x00000008,
+        AllowOomManagement  = 0x00000010,
+        WaivePriority       = 0x00000020,
+        Important           = 0x00000040,
+        AdjustWithActivity  = 0x00000080,
+        ExternalService     = -2147483648 // 0x80000000
+
+    };
+    Q_DECLARE_FLAGS(BindFlags, BindFlag)
+
+    Q_ANDROIDEXTRAS_EXPORT bool bindService(const QAndroidIntent &serviceIntent,
+                                            const QAndroidServiceConnection &serviceConnection,
+                                            BindFlags flags = BindFlag::None);
+
     typedef std::function<void()> Runnable;
     Q_ANDROIDEXTRAS_EXPORT void runOnAndroidThread(const Runnable &runnable);
     Q_ANDROIDEXTRAS_EXPORT void runOnAndroidThreadSync(const Runnable &runnable, int timeoutMs = INT_MAX);
diff --git a/src/androidextras/android/qandroidintent.cpp b/src/androidextras/android/qandroidintent.cpp
new file mode 100644
index 0000000..318b576
--- /dev/null
+++ b/src/androidextras/android/qandroidintent.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidintent.h"
+
+#include <jni/qandroidjnienvironment.h>
+#include <QtCore/private/qjni_p.h>
+#include <QBuffer>
+#include <QDataStream>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+    \class QAndroidIntent
+    \inmodule QtAndroidExtras
+
+    The QAndroidIntent is a convenience class that wraps the most important
+    \l {https://developer.android.com/reference/android/content/Intent.html} {Android Intent} methods.
+
+    \since 5.10
+*/
+
+/*!
+    Create a new intent
+ */
+QAndroidIntent::QAndroidIntent()
+    : m_handle("android.content.Intent", "()V")
+{
+
+}
+
+QAndroidIntent::~QAndroidIntent()
+{}
+
+/*!
+    Wraps the provided \a intent java object.
+ */
+QAndroidIntent::QAndroidIntent(const QAndroidJniObject &intent)
+    : m_handle(intent)
+{
+}
+
+/*!
+    Creates a new intent and sets the provided \a action.
+ */
+QAndroidIntent::QAndroidIntent(const QString &action)
+    : m_handle("android.content.Intent", "(Ljava/lang/String;)V",
+                        QAndroidJniObject::fromString(action).object())
+{
+    QAndroidJniExceptionCleaner cleaner;
+}
+
+/*!
+    Creates a new intent and sets the provided \a packageContext and the service \a className.
+    Example:
+    \code
+        auto serviceIntent = QAndroidIntent(QtAndroid::androidActivity().object(), "com.example.MyService");
+    \endcode
+
+    \sa QtAndroid::androidActivity, QtAndroid::bindService
+ */
+QAndroidIntent::QAndroidIntent(const QAndroidJniObject &packageContext, const char *className)
+    : m_handle("android/content/Intent", "(Landroid/content/Context;Ljava/lang/Class;)V",
+                        packageContext.object(), QJNIEnvironmentPrivate::findClass(className))
+{
+    QAndroidJniExceptionCleaner cleaner;
+}
+
+/*!
+    Sets the \a key with the \a data in the Intent extras
+ */
+void QAndroidIntent::putExtra(const QString &key, const QByteArray &data)
+{
+    QAndroidJniExceptionCleaner cleaner;
+    QAndroidJniEnvironment env;
+    jbyteArray array = env->NewByteArray(data.size());
+    env->SetByteArrayRegion(array, 0, data.length(), reinterpret_cast<const jbyte*>(data.constData()));
+    m_handle.callMethod<void>("putExtra", "(Ljava/lang/String;[B)Landroid.content.Intent;",
+                              QAndroidJniObject::fromString(key).object(), array);
+    env->DeleteLocalRef(array);
+}
+
+/*!
+    Returns the extra \a key data from the Intent extras
+ */
+QByteArray QAndroidIntent::extraBytes(const QString &key)
+{
+    QAndroidJniExceptionCleaner cleaner;
+    auto array = m_handle.callObjectMethod("getByteArrayExtra", "(Ljava/lang/String;)[B",
+                                           QAndroidJniObject::fromString(key).object());
+    QAndroidJniEnvironment env;
+    auto sz = env->GetArrayLength(jarray(array.object()));
+    QByteArray res(sz, Qt::Initialization::Uninitialized);
+    env->GetByteArrayRegion(jbyteArray(array.object()), 0, sz, reinterpret_cast<jbyte *>(res.data()));
+    return res;
+}
+
+/*!
+    Sets the \a key with the \a value in the Intent extras.
+ */
+void QAndroidIntent::putExtra(const QString &key, const QVariant &value)
+{
+    QByteArray buff;
+    QDataStream stream(&buff, QIODevice::WriteOnly);
+    stream << value;
+    putExtra(key, buff);
+}
+
+/*!
+    Returns the extra \a key data from the Intent extras as a QVariant
+ */
+QVariant QAndroidIntent::extraVariant(const QString &key)
+{
+    QDataStream stream(extraBytes(key));
+    QVariant res;
+    stream >> res;
+    return res;
+}
+
+/*!
+    The return value is useful to call other Java API which are not covered by this wrapper
+ */
+QAndroidJniObject QAndroidIntent::handle() const
+{
+    return m_handle;
+}
+QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidintent.h b/src/androidextras/android/qandroidintent.h
new file mode 100644
index 0000000..3da5692
--- /dev/null
+++ b/src/androidextras/android/qandroidintent.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDINTENT_H
+#define QANDROIDINTENT_H
+
+#include <QtAndroidExtras/qandroidextrasglobal.h>
+#include <QtAndroidExtras/qandroidjniobject.h>
+
+QT_BEGIN_NAMESPACE
+class QAndroidJniObject;
+class Q_ANDROIDEXTRAS_EXPORT QAndroidIntent
+{
+public:
+    QAndroidIntent();
+    virtual ~QAndroidIntent();
+    explicit QAndroidIntent(const QAndroidJniObject &intent);
+    explicit QAndroidIntent(const QString &action);
+    explicit QAndroidIntent(const QAndroidJniObject &packageContext, const char *className);
+
+    void putExtra(const QString &key, const QByteArray &data);
+    QByteArray extraBytes(const QString &key);
+
+    void putExtra(const QString &key, const QVariant &value);
+    QVariant extraVariant(const QString &key);
+
+    QAndroidJniObject handle() const;
+
+private:
+    QAndroidJniObject m_handle;
+};
+QT_END_NAMESPACE
+
+#endif // QANDROIDINTENT_H
diff --git a/src/androidextras/android/qandroidparcel.cpp b/src/androidextras/android/qandroidparcel.cpp
new file mode 100644
index 0000000..c2e80a0
--- /dev/null
+++ b/src/androidextras/android/qandroidparcel.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidparcel.h"
+
+#include "qandroidbinder.h"
+#include "qandroidbinder_p.h"
+#include "qandroidparcel_p.h"
+
+#include <QAndroidJniObject>
+#include <QAndroidJniEnvironment>
+#include <QBuffer>
+#include <QDataStream>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+struct FileDescriptor
+{
+    explicit FileDescriptor(int fd = -1)
+        : handle("java/io/FileDescriptor")
+    {
+        QAndroidJniExceptionCleaner cleaner;
+        setFileDescriptor(fd);
+    }
+
+    inline void setFileDescriptor(int fd)
+    {
+        QAndroidJniExceptionCleaner cleaner;
+        handle.setField("descriptor", fd);
+    }
+
+    QAndroidJniObject handle;
+};
+
+QAndroidParcelPrivate::QAndroidParcelPrivate()
+    : handle(QAndroidJniObject::callStaticObjectMethod("android/os/Parcel","obtain", "()Landroid/os/Parcel;").object())
+{}
+
+QAndroidParcelPrivate::QAndroidParcelPrivate(const QAndroidJniObject &parcel)
+    : handle(parcel)
+{}
+
+void QAndroidParcelPrivate::writeData(const QByteArray &data) const
+{
+    if (data.isEmpty())
+        return;
+
+    QAndroidJniExceptionCleaner cleaner;
+    QAndroidJniEnvironment env;
+    jbyteArray array = env->NewByteArray(data.size());
+    env->SetByteArrayRegion(array, 0, data.length(), reinterpret_cast<const jbyte*>(data.constData()));
+    handle.callMethod<void>("writeByteArray", "([B)V", array);
+    env->DeleteLocalRef(array);
+}
+
+void QAndroidParcelPrivate::writeBinder(const QAndroidBinder &binder) const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    handle.callMethod<void>("writeStrongBinder", "(Landroid/os/IBinder;)V", binder.handle().object());
+}
+
+void QAndroidParcelPrivate::writeFileDescriptor(int fd) const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    handle.callMethod<void>("writeFileDescriptor", "(Ljava/io/FileDescriptor;)V", FileDescriptor(fd).handle.object());
+}
+
+QByteArray QAndroidParcelPrivate::readData() const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    auto array = handle.callObjectMethod("createByteArray", "()[B");
+    QAndroidJniEnvironment env;
+    auto sz = env->GetArrayLength(jbyteArray(array.object()));
+    QByteArray res(sz, Qt::Initialization::Uninitialized);
+    env->GetByteArrayRegion(jbyteArray(array.object()), 0, sz, reinterpret_cast<jbyte *>(res.data()));
+    return res;
+}
+
+int QAndroidParcelPrivate::readFileDescriptor() const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    auto parcelFD = handle.callObjectMethod("readFileDescriptor", "()Landroid/os/ParcelFileDescriptor;");
+    if (parcelFD.isValid())
+        return parcelFD.callMethod<jint>("getFd", "()I");
+    return -1;
+}
+
+QAndroidBinder QAndroidParcelPrivate::readBinder() const
+{
+    QAndroidJniExceptionCleaner cleaner;
+    auto strongBinder = handle.callObjectMethod("readStrongBinder", "()Landroid/os/IBinder;");
+    return QAndroidBinder(strongBinder.object());
+}
+
+/*!
+    \class QAndroidParcel
+    \inmodule QtAndroidExtras
+
+    The QAndroidParcel is a convenience class that wraps the most important
+    \l {https://developer.android.com/reference/android/os/Parcel.html} {Android Parcel} methods.
+
+    \since 5.10
+*/
+
+/*!
+    Creates a new object.
+ */
+QAndroidParcel::QAndroidParcel()
+    : d(new QAndroidParcelPrivate())
+{
+}
+
+/*!
+    Wraps the \a parcel object.
+ */
+QAndroidParcel::QAndroidParcel(const QAndroidJniObject& parcel)
+    : d(new QAndroidParcelPrivate(parcel))
+{
+
+}
+
+QAndroidParcel::~QAndroidParcel()
+{
+}
+
+/*!
+    Writes the provided \a data as a byte array
+ */
+void QAndroidParcel::writeData(const QByteArray &data) const
+{
+    d->writeData(data);
+}
+
+/*!
+    Writes the provided \a value. The value is converted into a
+    QByteArray before is written.
+ */
+void QAndroidParcel::writeVariant(const QVariant &value) const
+{
+    QByteArray buff;
+    QDataStream stream(&buff, QIODevice::WriteOnly);
+    stream << value;
+    d->writeData(buff);
+}
+
+/*!
+    Writes a \a binder object. This is useful for a client to
+    send to a server a binder which can be used by the server callback the client.
+ */
+void QAndroidParcel::writeBinder(const QAndroidBinder &binder) const
+{
+    d->writeBinder(binder);
+}
+
+/*!
+    Writes the provided \a fd.
+ */
+void QAndroidParcel::writeFileDescriptor(int fd) const
+{
+    d->writeFileDescriptor(fd);
+}
+
+/*!
+    Returns the data as a QByteArray
+ */
+QByteArray QAndroidParcel::readData() const
+{
+    return d->readData();
+}
+
+/*!
+    Returns the data as a QVariant
+ */
+QVariant QAndroidParcel::readVariant() const
+{
+    QDataStream stream(d->readData());
+    QVariant res;
+    stream >> res;
+    return res;
+}
+
+/*!
+    Returns the binder as a QAndroidBinder
+ */
+QAndroidBinder QAndroidParcel::readBinder() const
+{
+    return d->readBinder();
+}
+
+/*!
+    Returns the file descriptor
+ */
+int QAndroidParcel::readFileDescriptor() const
+{
+    return d->readFileDescriptor();
+}
+
+/*!
+    The return value is useful to call other Java API which are not covered by this wrapper
+ */
+QAndroidJniObject QAndroidParcel::handle() const
+{
+    return d->handle;
+}
+
+QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidparcel.h b/src/androidextras/android/qandroidparcel.h
new file mode 100644
index 0000000..23d1edc
--- /dev/null
+++ b/src/androidextras/android/qandroidparcel.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPARCEL_H
+#define QANDROIDPARCEL_H
+
+#include <QtAndroidExtras/qandroidextrasglobal.h>
+#include <QSharedPointer>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+class QAndroidBinder;
+class QAndroidJniObject;
+class QAndroidParcelPrivate;
+class Q_ANDROIDEXTRAS_EXPORT QAndroidParcel
+{
+public:
+    QAndroidParcel();
+    explicit QAndroidParcel(const QAndroidJniObject& parcel);
+    virtual ~QAndroidParcel();
+
+    void writeData(const QByteArray &data) const;
+    void writeVariant(const QVariant &value) const;
+    void writeBinder(const QAndroidBinder &binder) const;
+    void writeFileDescriptor(int fd) const;
+
+    QByteArray readData() const;
+    QVariant readVariant() const;
+    QAndroidBinder readBinder() const;
+    int readFileDescriptor() const;
+
+    QAndroidJniObject handle() const;
+
+private:
+    friend class QAndroidParcelPrivate;
+    friend class QAndroidBinder;
+    QSharedPointer<QAndroidParcelPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPARCEL_H
diff --git a/src/androidextras/android/qandroidparcel_p.h b/src/androidextras/android/qandroidparcel_p.h
new file mode 100644
index 0000000..0be55f8
--- /dev/null
+++ b/src/androidextras/android/qandroidparcel_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPARCEL_P_H
+#define QANDROIDPARCEL_P_H
+
+//
+//  W A R N I N G
+//  -------------
+//
+// This file is not part of the Qt API.  It exists purely as an
+// implementation detail.  This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QAndroidJniObject>
+QT_BEGIN_NAMESPACE
+class QAndroidBinder;
+class QAndroidParcelPrivate
+{
+public:
+    QAndroidParcelPrivate();
+    explicit QAndroidParcelPrivate(const QAndroidJniObject& parcel);
+
+    void writeData(const QByteArray &data) const;
+    void writeBinder(const QAndroidBinder &binder) const;
+    void writeFileDescriptor(int fd) const;
+
+    QByteArray readData() const;
+    int readFileDescriptor() const;
+    QAndroidBinder readBinder() const;
+
+private:
+    friend class QAndroidBinder;
+    friend class QAndroidParcel;
+    QAndroidJniObject handle;
+};
+QT_END_NAMESPACE
+
+#endif // QANDROIDPARCEL_P_H
diff --git a/src/androidextras/android/qandroidservice.cpp b/src/androidextras/android/qandroidservice.cpp
new file mode 100644
index 0000000..3a7626d
--- /dev/null
+++ b/src/androidextras/android/qandroidservice.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidservice.h"
+
+#include "qandroidintent.h"
+#include "qandroidbinder.h"
+#include "qandroidbinder_p.h"
+
+#include <private/qjnihelpers_p.h>
+
+#include <QMutex>
+#include <QSet>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidServicePrivate : public QObject, public QtAndroidPrivate::OnBindListener
+{
+public:
+    QAndroidServicePrivate(QAndroidService *service)
+        : m_service(service)
+    {
+        QtAndroidPrivate::setOnBindListener(this);
+    }
+
+    ~QAndroidServicePrivate()
+    {
+        QMutexLocker lock(&m_bindersMutex);
+        while (!m_binders.empty()) {
+            auto it = m_binders.begin();
+            lock.unlock();
+            delete (*it);
+            lock.relock();
+        }
+    }
+
+    // OnBindListener interface
+    jobject onBind(jobject intent) override
+    {
+        auto binder = m_service->onBind(QAndroidIntent(intent));
+        if (binder) {
+            {
+                QMutexLocker lock(&m_bindersMutex);
+                binder->d->setDeleteListener([this, binder]{binderDestroied(binder);});
+                m_binders.insert(binder);
+            }
+            return binder->handle().object();
+        }
+        return nullptr;
+    }
+
+private:
+    void binderDestroied(QAndroidBinder* obj)
+    {
+        QMutexLocker lock(&m_bindersMutex);
+        m_binders.remove(obj);
+    }
+
+private:
+    QAndroidService *m_service;
+    QMutex m_bindersMutex;
+    QSet<QAndroidBinder*> m_binders;
+};
+
+/*!
+    \class QAndroidService
+    \inmodule QtAndroidExtras
+
+    The QAndroidService is a convenience class that wraps the most important
+    \l {https://developer.android.com/reference/android/app/Service.html} {Android Service} methods.
+
+    \since 5.10
+*/
+
+
+/*!
+    Creates a new Android Service
+
+    \sa QCoreApplication
+ */
+QAndroidService::QAndroidService(int &argc, char **argv, int flags)
+    : QCoreApplication (argc, argv, QtAndroidPrivate::acuqireServiceSetup(flags))
+    , d(new QAndroidServicePrivate(this))
+{
+}
+
+QAndroidService::~QAndroidService()
+{}
+
+/*!
+    The user must override this method and to return a binder.
+
+    The \a intent parameter contains all the caller information.
+
+    The returned binder is used by the caller to perform IPC calls.
+
+    \warning This method is called from Binder's thread which is different
+    from the thread that this object was created.
+
+    \sa QAndroidBinder::onTransact, QAndroidBinder::transact
+ */
+QAndroidBinder* QAndroidService::onBind(const QAndroidIntent &/*intent*/)
+{
+    return nullptr;
+}
+
+QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidservice.h b/src/androidextras/android/qandroidservice.h
new file mode 100644
index 0000000..72e47a4
--- /dev/null
+++ b/src/androidextras/android/qandroidservice.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDSERVICE_H
+#define QANDROIDSERVICE_H
+
+#include <QtAndroidExtras/qandroidextrasglobal.h>
+#include <QCoreApplication>
+#include <QSharedPointer>
+
+QT_BEGIN_NAMESPACE
+class QAndroidServicePrivate;
+class QAndroidIntent;
+class QAndroidBinder;
+class Q_ANDROIDEXTRAS_EXPORT QAndroidService : public QCoreApplication
+{
+public:
+    QAndroidService(int &argc, char **argv
+#ifndef Q_QDOC
+                                     , int flags = ApplicationFlags
+#endif
+            );
+    virtual ~QAndroidService();
+
+    virtual QAndroidBinder* onBind(const QAndroidIntent &intent);
+
+private:
+    friend class QAndroidServicePrivate;
+    Q_DISABLE_COPY(QAndroidService)
+
+    QScopedPointer<QAndroidServicePrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDSERVICE_H
diff --git a/src/androidextras/android/qandroidserviceconnection.cpp b/src/androidextras/android/qandroidserviceconnection.cpp
new file mode 100644
index 0000000..fb4f3da
--- /dev/null
+++ b/src/androidextras/android/qandroidserviceconnection.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidserviceconnection.h"
+#include "qandroidjniobject.h"
+
+#include <QAndroidJniEnvironment>
+
+QT_BEGIN_NAMESPACE
+/*!
+    \class QAndroidServiceConnection
+    \inmodule QtAndroidExtras
+
+    The QAndroidServiceConnection is a convenience abstract class which wraps the
+    \l {https://developer.android.com/reference/android/content/ServiceConnection.html} {Android ServiceConnection} interface.
+
+    It is useful when you perform a QtAndroid::bindService operation.
+
+    \since 5.10
+*/
+
+
+/*!
+    Creates a new object
+ */
+QAndroidServiceConnection::QAndroidServiceConnection()
+    : m_handle("org/qtproject/qt5/android/extras/QtAndroidServiceConnection", "(J)V", jlong(this))
+{
+}
+
+/*!
+    Creates a new object from an existing \a serviceConnection.
+
+    It's useful when you have your own Java implementation.
+    Of course onServiceConnected()/onServiceDisconnected()
+    will not be called anymore.
+ */
+QAndroidServiceConnection::QAndroidServiceConnection(const QAndroidJniObject &serviceConnection)
+    : m_handle(serviceConnection)
+{
+}
+
+QAndroidServiceConnection::~QAndroidServiceConnection()
+{
+    m_handle.callMethod<void>("setId", "(J)V", jlong(this));
+}
+
+/*!
+    returns the underline QAndroidJniObject
+ */
+QAndroidJniObject QAndroidServiceConnection::handle() const
+{
+    return m_handle;
+}
+
+/*!
+    \fn void QAndroidServiceConnection::onServiceConnected(const QString &name, const QAndroidBinder &serviceBinder)
+
+    This notification is called when the client managed to connect to the service.
+    The \a name contains the server name, the \a serviceBinder is the binder that the client
+    uses to perform IPC operations.
+
+    \warning This method is called from Binder's thread which is different
+    from the thread that this object was created.
+
+    returns the underline QAndroidJniObject
+ */
+
+/*!
+    \fn void QAndroidServiceConnection::onServiceDisconnected(const QString &name)
+
+    Called when a connection to the Service has been lost.
+    The \a name parameter specifies which connectioen was lost.
+
+    \warning This method is called from Binder's thread which is different
+    from the thread that this object was created.
+
+    returns the underline QAndroidJniObject
+ */
+
+QT_END_NAMESPACE
diff --git a/src/androidextras/android/qandroidserviceconnection.h b/src/androidextras/android/qandroidserviceconnection.h
new file mode 100644
index 0000000..ed0b4e0
--- /dev/null
+++ b/src/androidextras/android/qandroidserviceconnection.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTANDROIDSERVICECONNECTION_H
+#define QTANDROIDSERVICECONNECTION_H
+
+#include <QtAndroidExtras/qandroidextrasglobal.h>
+#include <QAndroidJniObject>
+
+QT_BEGIN_NAMESPACE
+class QAndroidBinder;
+class Q_ANDROIDEXTRAS_EXPORT QAndroidServiceConnection
+{
+public:
+    QAndroidServiceConnection();
+    explicit QAndroidServiceConnection(const QAndroidJniObject &serviceConnection);
+    virtual ~QAndroidServiceConnection();
+
+    virtual void onServiceConnected(const QString &name, const QAndroidBinder &serviceBinder) = 0;
+    virtual void onServiceDisconnected(const QString &name) = 0;
+
+    QAndroidJniObject handle() const;
+private:
+    Q_DISABLE_COPY(QAndroidServiceConnection)
+    QAndroidJniObject m_handle;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTANDROIDSERVICECONNECTION_H
diff --git a/src/androidextras/android/qjnionload.cpp b/src/androidextras/android/qjnionload.cpp
new file mode 100644
index 0000000..8f74744
--- /dev/null
+++ b/src/androidextras/android/qjnionload.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidbinder.h"
+#include "qandroidparcel.h"
+#include "qandroidserviceconnection.h"
+
+#include <android/log.h>
+#include <QAndroidJniObject>
+#include <jni.h>
+
+static jboolean onTransact(JNIEnv */*env*/, jclass /*cls*/, jlong id, jint code, jobject data, jobject reply, jint flags)
+{
+    if (!id)
+        return false;
+    return reinterpret_cast<QAndroidBinder*>(id)->onTransact(code, QAndroidParcel(data), QAndroidParcel(reply), QAndroidBinder::CallType(flags));
+}
+
+static void onServiceConnected(JNIEnv */*env*/, jclass /*cls*/, jlong id, jstring name, jobject service)
+{
+    if (!id)
+        return;
+    return reinterpret_cast<QAndroidServiceConnection *>(id)->onServiceConnected(QAndroidJniObject(name).toString(),
+                                                                                  QAndroidBinder(service));
+}
+
+static void onServiceDisconnected(JNIEnv */*env*/, jclass /*cls*/, jlong id, jstring name)
+{
+    if (!id)
+        return;
+    return reinterpret_cast<QAndroidServiceConnection *>(id)->onServiceDisconnected(QAndroidJniObject(name).toString());
+}
+
+static JNINativeMethod methods[] = {
+    {"onTransact", "(JILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void *)onTransact},
+    {"onServiceConnected", "(JLjava/lang/String;Landroid/os/IBinder;)V", (void *)onServiceConnected},
+    {"onServiceDisconnected", "(JLjava/lang/String;)V", (void *)onServiceDisconnected}
+};
+
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
+{
+    static bool initialized = false;
+    if (initialized)
+        return JNI_VERSION_1_6;
+    initialized = true;
+
+    typedef union {
+        JNIEnv *nativeEnvironment;
+        void *venv;
+    } UnionJNIEnvToVoid;
+
+    UnionJNIEnvToVoid uenv;
+    uenv.venv = nullptr;
+
+    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK) {
+        __android_log_print(ANDROID_LOG_FATAL, "Qt", "GetEnv failed");
+        return -1;
+    }
+
+    JNIEnv *env = uenv.nativeEnvironment;
+    jclass clazz;
+    clazz = env->FindClass("org/qtproject/qt5/android/extras/QtNative");
+    if (!clazz) {
+        __android_log_print(ANDROID_LOG_FATAL,"Qt", "Can't find \"org/qtproject/qt5/android/extras/QtNative\" class");
+        return -1;
+    }
+
+    if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+        __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+        return -1;
+    }
+
+    return JNI_VERSION_1_6;
+}
diff --git a/src/androidextras/androidextras.pro b/src/androidextras/androidextras.pro
index 7b5d218..584c82e 100644
--- a/src/androidextras/androidextras.pro
+++ b/src/androidextras/androidextras.pro
@@ -8,4 +8,9 @@ QT += core-private
 include(jni/jni.pri)
 include(android/android.pri)
 
+ANDROID_BUNDLED_JAR_DEPENDENCIES = \
+    jar/QtAndroidExtras-bundled.jar
+ANDROID_JAR_DEPENDENCIES = \
+    jar/QtAndroidExtras.jar
+
 load(qt_module)
diff --git a/src/androidextras/jni/qandroidjnienvironment.cpp b/src/androidextras/jni/qandroidjnienvironment.cpp
index 0800906..08f0c71 100644
--- a/src/androidextras/jni/qandroidjnienvironment.cpp
+++ b/src/androidextras/jni/qandroidjnienvironment.cpp
@@ -108,4 +108,62 @@ QAndroidJniEnvironment::operator JNIEnv*() const
     return d->jniEnv;
 }
 
+static void clearException(bool silent)
+{
+    QAndroidJniEnvironment env;
+    if (Q_UNLIKELY(env->ExceptionCheck())) {
+        if (!silent)
+            env->ExceptionDescribe();
+        env->ExceptionClear();
+    }
+}
+
+/*!
+    \class QAndroidJniExceptionCleaner
+    \inmodule QtAndroidExtras
+
+    The QAndroidJniExceptionCleaner is a convenience class useful to clean
+    the pending JNI exceptions from the current scope.
+
+    \since 5.10
+*/
+
+/*!
+    \enum QAndroidJniExceptionCleaner::OutputMode
+
+    \value Silent the exceptions are cleaned silently
+    \value Verbose discribes the exceptions before cleaning them
+*/
+
+/*!
+    \fn QAndroidJniExceptionCleaner::QAndroidJniExceptionCleaner(OutputMode outputMode = OutputMode::Silent)
+
+    Cleans any pending exceptions either silently or with descriptions, depending on the \a outputMode.
+ */
+QAndroidJniExceptionCleaner::QAndroidJniExceptionCleaner(QAndroidJniExceptionCleaner::OutputMode outputMode)
+    : m_outputMode(outputMode)
+{
+    clearException(outputMode == OutputMode::Silent);
+}
+
+/*!
+    \fn QAndroidJniExceptionCleaner::~QAndroidJniExceptionCleaner()
+
+    Clean any pending exceptions.
+ */
+QAndroidJniExceptionCleaner::~QAndroidJniExceptionCleaner()
+{
+    clearException(m_outputMode == OutputMode::Silent);
+}
+
+/*!
+ \fn void QAndroidJniExceptionCleaner::clean()
+
+ Manually cleans any pending exceptions
+ */
+void QAndroidJniExceptionCleaner::clean()
+{
+    clearException(m_outputMode == OutputMode::Silent);
+}
+
 QT_END_NAMESPACE
diff --git a/src/androidextras/jni/qandroidjnienvironment.h b/src/androidextras/jni/qandroidjnienvironment.h
index fcced40..654117b 100644
--- a/src/androidextras/jni/qandroidjnienvironment.h
+++ b/src/androidextras/jni/qandroidjnienvironment.h
@@ -63,6 +63,23 @@ private:
     QScopedPointer<QJNIEnvironmentPrivate> d;
 };
 
+class Q_ANDROIDEXTRAS_EXPORT QAndroidJniExceptionCleaner
+{
+public:
+    enum class OutputMode {
+        Silent,
+        Verbose
+    };
+
+public:
+    explicit QAndroidJniExceptionCleaner(OutputMode outputMode = OutputMode::Silent);
+    ~QAndroidJniExceptionCleaner();
+
+    void clean();
+private:
+    OutputMode m_outputMode;
+};
+
 QT_END_NAMESPACE
 
 #endif // QANDROIDJNIENVIRONMENT_H
diff --git a/src/jar/AndroidManifest.xml b/src/jar/AndroidManifest.xml
new file mode 100644
index 0000000..7eae185
--- /dev/null
+++ b/src/jar/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.qtproject.qt5.android.multimedia"
+    android:versionCode="1"
+    android:versionName="1.0" >
+    <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
+</manifest>
diff --git a/src/jar/bundledjar.pro b/src/jar/bundledjar.pro
new file mode 100644
index 0000000..9456e1c
--- /dev/null
+++ b/src/jar/bundledjar.pro
@@ -0,0 +1,3 @@
+TARGET = QtAndroidExtras-bundled
+CONFIG += bundled_jar_file
+include(jar.pri)
diff --git a/src/jar/distributedjar.pro b/src/jar/distributedjar.pro
new file mode 100644
index 0000000..714916b
--- /dev/null
+++ b/src/jar/distributedjar.pro
@@ -0,0 +1,2 @@
+TARGET = QtAndroidExtras
+include(jar.pri)
diff --git a/src/jar/jar.pri b/src/jar/jar.pri
new file mode 100644
index 0000000..8ea4342
--- /dev/null
+++ b/src/jar/jar.pri
@@ -0,0 +1,14 @@
+load(qt_build_paths)
+CONFIG += java
+DESTDIR = $$MODULE_BASE_OUTDIR/jar
+
+JAVACLASSPATH += $$PWD/src
+
+JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/extras/QtAndroidBinder.java \
+               $$PWD/src/org/qtproject/qt5/android/extras/QtAndroidServiceConnection.java \
+               $$PWD/src/org/qtproject/qt5/android/extras/QtNative.java
+# install
+target.path = $$[QT_INSTALL_PREFIX]/jar
+INSTALLS += target
+
+OTHER_FILES += $$JAVASOURCES
diff --git a/src/jar/jar.pro b/src/jar/jar.pro
new file mode 100644
index 0000000..6a4fcd3
--- /dev/null
+++ b/src/jar/jar.pro
@@ -0,0 +1,3 @@
+TEMPLATE=subdirs
+SUBDIRS += distributedjar.pro bundledjar.pro
+
diff --git a/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidBinder.java b/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidBinder.java
new file mode 100644
index 0000000..aed6652
--- /dev/null
+++ b/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidBinder.java
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.extras;
+
+import android.os.Binder;
+import android.os.Parcel;
+
+public class QtAndroidBinder extends Binder
+{
+    public QtAndroidBinder(long id)
+    {
+        m_id = id;
+    }
+
+    public void setId(long id)
+    {
+        synchronized(this)
+        {
+            m_id = id;
+        }
+    }
+    @Override
+    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+    {
+        synchronized(this)
+        {
+            return QtNative.onTransact(m_id, code, data, reply, flags);
+        }
+    }
+
+    private long m_id;
+}
diff --git a/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidServiceConnection.java b/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidServiceConnection.java
new file mode 100644
index 0000000..6b35817
--- /dev/null
+++ b/src/jar/src/org/qtproject/qt5/android/extras/QtAndroidServiceConnection.java
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.extras;
+
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+
+public class QtAndroidServiceConnection implements ServiceConnection
+{
+    public QtAndroidServiceConnection(long id)
+    {
+        m_id = id;
+    }
+
+    public void setId(long id)
+    {
+        synchronized(this)
+        {
+            m_id = id;
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service)
+    {
+        synchronized(this) {
+            QtNative.onServiceConnected(m_id, name.flattenToString(), service);
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name)
+    {
+        synchronized(this) {
+            QtNative.onServiceDisconnected(m_id, name.flattenToString());
+        }
+    }
+
+    private long m_id;
+}
diff --git a/src/jar/src/org/qtproject/qt5/android/extras/QtNative.java b/src/jar/src/org/qtproject/qt5/android/extras/QtNative.java
new file mode 100644
index 0000000..79a0592
--- /dev/null
+++ b/src/jar/src/org/qtproject/qt5/android/extras/QtNative.java
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 BogDan Vatra <bogdan@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Android port of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+package org.qtproject.qt5.android.extras;
+
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.os.Parcel;
+
+public class QtNative {
+    // Binder
+    public static native boolean onTransact(long id, int code, Parcel data, Parcel reply, int flags);
+
+
+    // ServiceConnection
+    public static native void onServiceConnected(long id, String name, IBinder service);
+    public static native void onServiceDisconnected(long id, String name);
+}
diff --git a/src/src.pro b/src/src.pro
index a15e9b8..0c91144 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,6 +1,6 @@
 android {
     TEMPLATE = subdirs
-    SUBDIRS += androidextras
+    SUBDIRS += androidextras jar
 } else {
     TEMPLATE = aux
     QMAKE_DOCS = $$PWD/androidextras/doc/qtandroidextras.qdocconf
-- 
GitLab