summaryrefslogtreecommitdiffstats
path: root/src/nfc/android
diff options
context:
space:
mode:
authorJuhana Jauhiainen <juhana.jauhiainen@gmail.com>2013-07-29 10:22:08 +0300
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-01-08 11:49:10 +0100
commitd50039ca0cc5c4168fa77579b524f9c5464ad186 (patch)
tree88e179d960f596d7ebc9a6d3824a8cf0d073dc5d /src/nfc/android
parentd9b50136b15a2236f4f4f01254034ecb87601673 (diff)
Squashed code contribtion for QtNfc on Android
The code was contributed by Juhana Jauhiainen <juhana.jauhiainen@gmail.com> osaukko <osaukko@gmail.com> waz <markus.liuska@gmail.fi> List of squashed commits: Preliminary Android support to QtNFC. Only receiving Ndef messages to QNearFieldManager. QNearFieldTarget and LLCP classes need to be implemented for Android ------------------ Added Android buildsettings to nfc.pro Including Android implementation in QNearFieldManager.h ------------------ QtNfc namespace removed. ------------------ Added Android support to QNearFieldManager::isAvailable() method ------------------ Improved isAvailable method ------------------ Fix QtNfc java module Added checking for NfcAdapter object so that calling QNearFieldManager::startTargetDetection() and QNearFieldManager::stopTargetDetection() methods will not crash application. ------------------ Added support for tag types. NFC tag type is now included in onNdefDiscovered() method call. Only showing information in debug messages for now. ------------------ Fixing missing return values and releasing acquired resources. ------------------ First proof of concept version of target creation for android. ------------------ Fix for include guards. ------------------ Added QHash container for NearFieldmanager Added QHash container for NearFieldManager which holds each discovered targets. Also added setters for NearFieldTarget. ------------------ Using signals and slots to move target information to main thread. Fixes problem when creating new targets as child of manager. ------------------ Fix for tag detection for tags without NDEF messages Tag type checking is not working if there is no NDEF messages currently. Need to find way to check tag type without Ndef object. ------------------ Added error reporting for QNearFieldTarget::readNdefMessages (Android) ------------------ Registering type name for QNearFieltTarget. Small refactoring for QNearFieldTarget android implementation. ------------------ Sending UID as bytearray. Also debug messages to show tech list added into QtNfc.java. ------------------ Trying different approach for android version of QtNfc module. In this approach we pass through intent object(Java) to NearFieldTarget object(c++). ------------------ Fixed nfc.pro so QtNfc.jar is built. ------------------ Added tech list into android version of QNearFieldTarget Could be used to detect availability of NDEF messages and also to detect tag type. ------------------ Fixed build files so both the C++ and Java libraries are built correctly. ------------------ Support for writing Ndef messages. ------------------ Implementation for NearFieldTarget::hasNdefMessage(). Also nice debug messages to show available technologies for current tag. ------------------ Support for NdefFormatable tags. ------------------ Support for writing NdefFormatable tags. ------------------ Removed debug messages. ------------------ Implemented type() method to Android's QNearFieldTarget. Conflicts: src/nfc/qnearfieldtarget_android.cpp src/nfc/qnearfieldtarget_android_p.h ------------------ Small fixes to remove some of the warnings. Conflicts: src/nfc/qnearfieldtarget_android.cpp src/nfc/qnearfieldtarget_android_p.h ------------------ Committing test code for targetLost signal (Because of Merge) Conflicts: src/nfc/qnearfieldtarget_android.cpp src/nfc/qnearfieldtarget_android_p.h ------------------ Added support for target lost signal ------------------ Using QString::fromUtf8 instead of QString() Conflicts: src/nfc/qnearfieldtarget_android.cpp ------------------ Fixed bug with targetLost not emitting when reading or writing Ndef messages. Added some untested code for sendCommand. ------------------ Refactoring. Conflicts: src/nfc/qnearfieldtarget_android_p.h ------------------ Refactoring and fixes. ------------------ Less debug messages. ------------------ Refactoring and cleaning. Conflicts: src/android/android.pro src/nfc/neard/neard_helper_p.h src/nfc/nfc.pro src/nfc/qdeclarativendefrecord.cpp src/nfc/qdeclarativendefrecord.h src/nfc/qllcpserver_p.h src/nfc/qllcpsocket.h src/nfc/qndefmessage.h src/nfc/qndefnfcsmartposterrecord_p.h src/nfc/qnearfieldmanager.cpp src/nfc/qnearfieldmanager_neard_p.h src/nfc/qnearfieldtarget.h src/nfc/qnfcglobal.h src/src.pro tests/nfctestserver/socketcontroller.h Change-Id: Ideb4c8c8064f46b431532ea4870207691bc49c99 Reviewed-by: Peter Rustler <peter.rustler@basyskom.com> Reviewed-by: Frank Meerkoetter <frank.meerkoetter@basyskom.com> Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/nfc/android')
-rw-r--r--src/nfc/android/androidglobal.h49
-rw-r--r--src/nfc/android/androidjninfc.cpp214
-rw-r--r--src/nfc/android/androidjninfc_p.h80
3 files changed, 343 insertions, 0 deletions
diff --git a/src/nfc/android/androidglobal.h b/src/nfc/android/androidglobal.h
new file mode 100644
index 00000000..271ab2c3
--- /dev/null
+++ b/src/nfc/android/androidglobal.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNfc module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDGLOBAL_H
+#define ANDROIDGLOBAL_H
+
+#define QT_USE_ANDROIDNFC_NAMESPACE using namespace ::AndroidNfc;
+#define QT_BEGIN_ANDROIDNFC_NAMESPACE namespace AndroidNfc {
+#define QT_END_ANDROIDNFC_NAMESPACE }
+
+#endif // ANDROIDGLOBAL_H
diff --git a/src/nfc/android/androidjninfc.cpp b/src/nfc/android/androidjninfc.cpp
new file mode 100644
index 00000000..6a46c422
--- /dev/null
+++ b/src/nfc/android/androidjninfc.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNfc module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "androidjninfc_p.h"
+
+#include <android/log.h>
+
+#include "qglobal.h"
+#include "qlist.h"
+#include "qreadwritelock.h"
+#include "qbytearray.h"
+#include "qdebug.h"
+
+static JavaVM *javaVM = 0;
+static jclass nfcClass;
+
+static jmethodID startDiscoveryId;
+static jmethodID stopDiscoveryId;
+static jmethodID isAvailableId;
+
+static QList<AndroidNfc::AndroidNfcListenerInterface*> listeners;
+QReadWriteLock listenersLock;
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+AttachedJNIEnv::AttachedJNIEnv()
+{
+ Q_ASSERT_X(javaVM != 0, "constructor", "javaVM pointer is null");
+ attached = false;
+ if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) {
+ if (javaVM->AttachCurrentThread(&jniEnv, NULL) < 0) {
+ __android_log_print(ANDROID_LOG_ERROR, "Qt", "AttachCurrentThread failed");
+ jniEnv = 0;
+ return;
+ }
+ attached = true;
+ }
+}
+
+AttachedJNIEnv::~AttachedJNIEnv()
+{
+ if (attached)
+ javaVM->DetachCurrentThread();
+}
+
+bool startDiscovery()
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "QtNfc::startDiscovery()");
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ aenv.jniEnv->CallStaticObjectMethod(nfcClass, startDiscoveryId);
+ return true;
+}
+
+bool isAvailable()
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "QtNfc::isAvailable()");
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ return aenv.jniEnv->CallStaticBooleanMethod(nfcClass, isAvailableId);
+}
+
+bool stopDiscovery()
+{
+ AttachedJNIEnv aenv;
+ if (!aenv.jniEnv)
+ return false;
+
+ aenv.jniEnv->CallStaticObjectMethod(nfcClass, stopDiscoveryId);
+ return true;
+}
+
+bool registerListener(AndroidNfcListenerInterface *listener)
+{
+ listenersLock.lockForWrite();
+ listeners.push_back(listener);
+ listenersLock.unlock();
+ return true;
+}
+
+bool unregisterListener(AndroidNfcListenerInterface *listener)
+{
+ listenersLock.lockForWrite();
+ listeners.removeOne(listener);
+ listenersLock.unlock();
+ return true;
+}
+
+jobject getTag(JNIEnv *env, jobject intent)
+{
+ jclass intentClass = env->GetObjectClass(intent);
+ Q_ASSERT_X(intentClass != 0, "getTag", "could not get Intent class");
+
+ jmethodID getParcelableExtraMID = env->GetMethodID(intentClass,
+ "getParcelableExtra",
+ "(Ljava/lang/String;)Landroid/os/Parcelable;");
+ Q_ASSERT_X(getParcelableExtraMID != 0, "getTag", "could not get method ID for getParcelableExtra()");
+
+ jclass nfcAdapterClass = env->FindClass("android/nfc/NfcAdapter");
+ Q_ASSERT_X(nfcAdapterClass != 0, "getTag", "could not find NfcAdapter class");
+
+ jfieldID extraTagFID = env->GetStaticFieldID(nfcAdapterClass, "EXTRA_TAG", "Ljava/lang/String;");
+ Q_ASSERT_X(extraTagFID != 0, "getTag", "could not get field ID for EXTRA_TAG");
+
+ jobject extraTag = env->GetStaticObjectField(nfcAdapterClass, extraTagFID);
+ Q_ASSERT_X(extraTag != 0, "getTag", "could not get EXTRA_TAG");
+
+ jobject tag = env->CallObjectMethod(intent, getParcelableExtraMID, extraTag);
+ Q_ASSERT_X(tag != 0, "getTag", "could not get Tag object");
+
+ return tag;
+}
+
+QT_END_ANDROIDNFC_NAMESPACE
+
+static const char logTag[] = "Qt";
+static const char classErrorMsg[] = "Can't find class \"%s\"";
+static const char methodErrorMsg[] = "Can't find method \"%s%s\"";
+
+static void newIntent(JNIEnv *env, jobject obj, jobject intent)
+{
+ Q_UNUSED(obj);
+ listenersLock.lockForRead();
+ foreach (AndroidNfc::AndroidNfcListenerInterface *listener, listeners) {
+ // Making new global reference for each listener.
+ // Listeners must release reference when it is not used anymore.
+ jobject newIntentRef = env->NewGlobalRef(intent);
+ listener->newIntent(newIntentRef);
+ }
+ listenersLock.unlock();
+}
+
+static JNINativeMethod methods[] = {
+ {"newIntent", "(Landroid/content/Intent;)V", (void*)newIntent}
+};
+
+#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
+ clazz = env->FindClass(CLASS_NAME); \
+ if (!clazz) { \
+ return JNI_FALSE; \
+ }
+
+#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \
+ VAR = env->GetStaticMethodID(CLASS, METHOD_NAME, METHOD_SIGNATURE); \
+ if (!VAR) { \
+ return JNI_FALSE; \
+ }
+
+Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
+{
+ //__android_log_print(ANDROID_LOG_INFO, "Qt", "JNI_OnLoad for QtNfc");
+ JNIEnv* env;
+ if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+ return -1;
+ }
+
+ jclass clazz;
+ FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/nfc/QtNfc");
+ nfcClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+
+ if (env->RegisterNatives(nfcClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
+ __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives failed");
+ return JNI_FALSE;
+ }
+
+ GET_AND_CHECK_STATIC_METHOD(startDiscoveryId, nfcClass, "start", "()V");
+ GET_AND_CHECK_STATIC_METHOD(stopDiscoveryId, nfcClass, "stop", "()V");
+ GET_AND_CHECK_STATIC_METHOD(isAvailableId, nfcClass, "isAvailable", "()Z");
+ javaVM = vm;
+
+ return JNI_VERSION_1_6;
+}
diff --git a/src/nfc/android/androidjninfc_p.h b/src/nfc/android/androidjninfc_p.h
new file mode 100644
index 00000000..21e3087e
--- /dev/null
+++ b/src/nfc/android/androidjninfc_p.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 Centria research and development
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNfc module 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ANDROIDJNINFC_H
+#define ANDROIDJNINFC_H
+
+#include "androidglobal.h"
+#include "qglobal.h"
+
+#include <jni.h>
+
+QT_BEGIN_ANDROIDNFC_NAMESPACE
+
+class AndroidNfcListenerInterface
+{
+public:
+ virtual ~AndroidNfcListenerInterface(){}
+ virtual void newIntent(jobject intent) = 0;
+};
+
+class AttachedJNIEnv
+{
+public:
+ AttachedJNIEnv();
+ virtual ~AttachedJNIEnv();
+ bool attached;
+ JNIEnv *jniEnv;
+
+private:
+ Q_DISABLE_COPY(AttachedJNIEnv)
+};
+
+bool startDiscovery();
+bool stopDiscovery();
+bool isAvailable();
+bool registerListener(AndroidNfcListenerInterface *listener);
+bool unregisterListener(AndroidNfcListenerInterface *listener);
+jobject getTag(JNIEnv *env, jobject intent);
+
+QT_END_ANDROIDNFC_NAMESPACE
+
+#endif