summaryrefslogtreecommitdiffstats
path: root/core/jni
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-10-13 17:25:24 -0700
committerNick Pelly <npelly@google.com>2010-10-15 02:12:32 -0700
commitbc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48 (patch)
tree8b58be37237ea58089f6541403fd3092ff64f6bc /core/jni
parentc1e7b2182594aa0463c4a738cc8e7eea6777ef50 (diff)
downloadframeworks_base-bc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48.zip
frameworks_base-bc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48.tar.gz
frameworks_base-bc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48.tar.bz2
NFC: Move NFC service implementation out of system_server.
NFC service is now an application service in packages/apps/Nfc. NFC service is registered through ServiceManager.addService(), and the proxy object NfcAdapter obtains a handle to it through ServiceManager.getService(). **Important** Had to add new symbols AID_NFC / NFC_UID / android.uid.nfc and modify service_manager.c, Process.java and PackageManagerService.java in order to force the com.android.nfc process to take a fixed uid, so that it can use ServiceManager.addService(). Most of the JNI has moved to packages/apps/Nfc/jni. However NdefRecord and NdefMessage require some in-process native code, so android_com_NdefMessage.cpp and android_com_NdefRecord.cpp stay in frameworks/base/core/jni. They link to a very small library libnfc_ndef.so that implements NDEF message parsing. This has been added to core.mk so all devices (even without NFC hardware) can work with NDEF data. Bug: 3041259 Bug: 3097445 Change-Id: If8f00ce8f2053acfc9319ca366d4a9c02bd396e6 Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'core/jni')
-rw-r--r--core/jni/Android.mk13
-rw-r--r--core/jni/AndroidRuntime.cpp28
-rw-r--r--core/jni/android_nfc.h54
-rw-r--r--core/jni/android_nfc_NdefMessage.cpp175
-rw-r--r--core/jni/android_nfc_NdefRecord.cpp92
5 files changed, 329 insertions, 33 deletions
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index d51c0b7..c3f393d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -67,6 +67,8 @@ LOCAL_SRC_FILES:= \
android_net_TrafficStats.cpp \
android_net_wifi_Wifi.cpp \
android_nio_utils.cpp \
+ android_nfc_NdefMessage.cpp \
+ android_nfc_NdefRecord.cpp \
android_pim_EventRecurrence.cpp \
android_text_format_Time.cpp \
android_security_Md5MessageDigest.cpp \
@@ -190,15 +192,8 @@ LOCAL_SHARED_LIBRARIES := \
libicui18n \
libmedia \
libwpa_client \
- libjpeg
-
-ifeq ($(BOARD_HAVE_NFC),true)
-LOCAL_SHARED_LIBRARIES += \
- libnfc_jni \
- libnfc
-
-LOCAL_CFLAGS += -DHAVE_NFC
-endif
+ libjpeg \
+ libnfc_ndef
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_C_INCLUDES += \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 5f73443..648d93f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -125,6 +125,8 @@ extern int register_android_database_SQLiteQuery(JNIEnv* env);
extern int register_android_database_SQLiteStatement(JNIEnv* env);
extern int register_android_debug_JNITest(JNIEnv* env);
extern int register_android_nio_utils(JNIEnv* env);
+extern int register_android_nfc_NdefMessage(JNIEnv *env);
+extern int register_android_nfc_NdefRecord(JNIEnv *env);
extern int register_android_pim_EventRecurrence(JNIEnv* env);
extern int register_android_text_format_Time(JNIEnv* env);
extern int register_android_os_Debug(JNIEnv* env);
@@ -169,18 +171,6 @@ extern int register_android_view_MotionEvent(JNIEnv* env);
extern int register_android_content_res_ObbScanner(JNIEnv* env);
extern int register_android_content_res_Configuration(JNIEnv* env);
-#ifdef HAVE_NFC
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeNfcManager(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeNfcTag(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeNdefTag(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_NdefMessage(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_NdefRecord(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeP2pDevice(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket(JNIEnv *env);
-extern int register_com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket(JNIEnv *env);
-#endif
-
static AndroidRuntime* gCurRuntime = NULL;
static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
@@ -1263,6 +1253,8 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_net_NetworkUtils),
REG_JNI(register_android_net_TrafficStats),
REG_JNI(register_android_net_wifi_WifiManager),
+ REG_JNI(register_android_nfc_NdefMessage),
+ REG_JNI(register_android_nfc_NdefRecord),
REG_JNI(register_android_os_MemoryFile),
REG_JNI(register_com_android_internal_os_ZygoteInit),
REG_JNI(register_android_hardware_Camera),
@@ -1297,18 +1289,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_content_res_ObbScanner),
REG_JNI(register_android_content_res_Configuration),
-
-#ifdef HAVE_NFC
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeNfcManager),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeNfcTag),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeNdefTag),
- REG_JNI(register_com_trustedlogic_trustednfc_android_NdefMessage),
- REG_JNI(register_com_trustedlogic_trustednfc_android_NdefRecord),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeP2pDevice),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeLlcpSocket),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeLlcpConnectionlessSocket),
- REG_JNI(register_com_trustedlogic_trustednfc_android_internal_NativeLlcpServiceSocket),
-#endif
};
/*
diff --git a/core/jni/android_nfc.h b/core/jni/android_nfc.h
new file mode 100644
index 0000000..df660f2
--- /dev/null
+++ b/core/jni/android_nfc.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Contains the bare minimum header so that framework NFC jni can link
+ * against NFC native library
+ */
+
+#ifndef __ANDROID_NFC_H__
+#define __ANDROID_NFC_H__
+
+extern "C" {
+
+typedef struct phFriNfc_NdefRecord {
+ uint8_t Flags;
+ uint8_t Tnf;
+ uint8_t TypeLength;
+ uint8_t *Type;
+ uint8_t IdLength;
+ uint8_t *Id;
+ uint32_t PayloadLength;
+ uint8_t *PayloadData;
+} phFriNfc_NdefRecord_t;
+
+uint16_t phFriNfc_NdefRecord_GetRecords(uint8_t* pBuffer,
+ uint32_t BufferLength,
+ uint8_t* pRawRecords[ ],
+ uint8_t IsChunked[ ],
+ uint32_t* pNumberOfRawRecords
+ );
+uint16_t phFriNfc_NdefRecord_Parse(phFriNfc_NdefRecord_t* pRecord,
+ uint8_t* pRawRecord);
+
+uint16_t phFriNfc_NdefRecord_Generate(phFriNfc_NdefRecord_t* pRecord,
+ uint8_t* pBuffer,
+ uint32_t MaxBufferSize,
+ uint32_t* pBytesWritten
+ );
+}
+
+#endif
diff --git a/core/jni/android_nfc_NdefMessage.cpp b/core/jni/android_nfc_NdefMessage.cpp
new file mode 100644
index 0000000..99295f4
--- /dev/null
+++ b/core/jni/android_nfc_NdefMessage.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NdefMessage"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_nfc.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+static jint android_nfc_NdefMessage_parseNdefMessage(JNIEnv *e, jobject o,
+ jbyteArray array)
+{
+ uint16_t status;
+ uint32_t i;
+ jbyte *raw_msg;
+ jsize raw_msg_size;
+ uint32_t num_of_records = 0;
+ uint8_t **records = NULL;
+ uint8_t *is_chunked = NULL;
+ jint ret = -1;
+ phFriNfc_NdefRecord_t record;
+
+ jclass record_cls;
+ jobjectArray records_array;
+ jmethodID ctor;
+
+ jclass msg_cls;
+ jfieldID mrecords;
+
+ raw_msg_size = e->GetArrayLength(array);
+ raw_msg = e->GetByteArrayElements(array, NULL);
+ if (raw_msg == NULL)
+ return -1;
+
+ /* Get the number of records in the message so we can allocate buffers */
+ LOGD("phFriNfc_NdefRecord_GetRecords(NULL)");
+
+ status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
+ (uint32_t)raw_msg_size, NULL, NULL, &num_of_records);
+
+ if (status) {
+ LOGE("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x", status);
+ goto end;
+ }
+ LOGD("phFriNfc_NdefRecord_GetRecords(NULL) returned 0x%04x", status);
+
+ LOGD("found %d records in message", num_of_records);
+
+ is_chunked = (uint8_t*)malloc(num_of_records);
+ if (is_chunked == NULL)
+ goto end;
+ records = (uint8_t**)malloc(num_of_records * sizeof(uint8_t *));
+ if (records == NULL)
+ goto end;
+
+ /* Now, actually retrieve records position in message */
+ LOGD("phFriNfc_NdefRecord_GetRecords()");
+
+ status = phFriNfc_NdefRecord_GetRecords((uint8_t *)raw_msg,
+ (uint32_t)raw_msg_size, records, is_chunked, &num_of_records);
+
+ if (status) {
+ LOGE("phFriNfc_NdefRecord_GetRecords() returned 0x%04x", status);
+ goto end;
+ }
+ LOGD("phFriNfc_NdefRecord_GetRecords() returned 0x%04x", status);
+
+ /* Build NDEF records array */
+ record_cls = e->FindClass("android/nfc/NdefRecord");
+ records_array = e->NewObjectArray((jsize)num_of_records, record_cls,
+ NULL);
+ if (records_array == NULL)
+ goto end;
+
+ ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[B)V");
+
+ LOGD("NFC_Number of records = %d\n", num_of_records);
+
+ for (i = 0; i < num_of_records; i++) {
+ jbyteArray type, id, payload;
+ jobject new_record;
+
+ LOGD("phFriNfc_NdefRecord_Parse()");
+
+ status = phFriNfc_NdefRecord_Parse(&record, records[i]);
+
+ if (status) {
+ LOGE("phFriNfc_NdefRecord_Parse() returned 0x%04x", status);
+ goto end;
+ }
+ LOGD("phFriNfc_NdefRecord_Parse() returned 0x%04x", status);
+
+ type = e->NewByteArray(record.TypeLength);
+ if (type == NULL) {
+ LOGD("NFC_Set Record Type Error\n");
+ goto end;
+ }
+
+ id = e->NewByteArray(record.IdLength);
+ if(id == NULL) {
+ LOGD("NFC_Set Record ID Error\n");
+ goto end;
+ }
+
+ payload = e->NewByteArray(record.PayloadLength);
+ if(payload == NULL) {
+ LOGD("NFC_Set Record Payload Error\n");
+ goto end;
+ }
+
+ e->SetByteArrayRegion(type, 0, record.TypeLength,
+ (jbyte *)record.Type);
+ e->SetByteArrayRegion(id, 0, record.IdLength,
+ (jbyte *)record.Id);
+ e->SetByteArrayRegion(payload, 0, record.PayloadLength,
+ (jbyte *)record.PayloadData);
+
+ new_record = e->NewObject(record_cls, ctor,
+ (jshort)record.Tnf, type, id, payload);
+
+ e->SetObjectArrayElement(records_array, i, new_record);
+
+ /* Try not to clutter the Java stack too much */
+ e->DeleteLocalRef(new_record);
+ e->DeleteLocalRef(type);
+ e->DeleteLocalRef(id);
+ e->DeleteLocalRef(payload);
+ }
+
+ /* Store built array in our NDEFMessage instance */
+ msg_cls = e->GetObjectClass(o);
+ mrecords = e->GetFieldID(msg_cls, "mRecords", "[Landroid/nfc/NdefRecord;");
+
+ e->SetObjectField(o, mrecords, (jobject)records_array);
+
+ ret = 0;
+
+end:
+ if(is_chunked)
+ free(is_chunked);
+ if(records)
+ free(records);
+ e->ReleaseByteArrayElements(array, raw_msg, JNI_ABORT);
+
+ return ret;
+}
+
+static JNINativeMethod gMethods[] = {
+ {"parseNdefMessage", "([B)I", (void *)android_nfc_NdefMessage_parseNdefMessage},
+};
+
+int register_android_nfc_NdefMessage(JNIEnv *e)
+{
+ return jniRegisterNativeMethods(e, "android/nfc/NdefMessage", gMethods, NELEM(gMethods));
+}
+
+} // namespace android
diff --git a/core/jni/android_nfc_NdefRecord.cpp b/core/jni/android_nfc_NdefRecord.cpp
new file mode 100644
index 0000000..8ce1837
--- /dev/null
+++ b/core/jni/android_nfc_NdefRecord.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NdefRecord"
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_nfc.h"
+
+#include <utils/Log.h>
+
+namespace android {
+
+static jbyteArray android_nfc_NdefRecord_generate(
+ JNIEnv *e, jobject o, jshort flags, jshort tnf, jbyteArray type,
+ jbyteArray id, jbyteArray payload)
+{
+ uint32_t status;
+ phFriNfc_NdefRecord_t record;
+ uint32_t buf_size;
+ uint32_t record_size;
+ uint8_t *buf = NULL;
+ jbyteArray result = NULL;
+
+ /* Prepare NDEF record structure */
+ record.Flags = (uint8_t)flags;
+ record.Tnf = (uint8_t)tnf;
+ record.TypeLength = (uint32_t)e->GetArrayLength(type);
+ record.Type = (uint8_t *)e->GetByteArrayElements(type, NULL);
+ record.IdLength = (uint32_t)e->GetArrayLength(id);
+ record.Id = (uint8_t *)e->GetByteArrayElements(id, NULL);
+ record.PayloadLength = (uint32_t)e->GetArrayLength(payload);
+ record.PayloadData = (uint8_t *)e->GetByteArrayElements(payload, NULL);
+
+ buf_size = record.PayloadLength + record.IdLength + record.TypeLength + 8;
+
+ buf = (uint8_t*)malloc(buf_size);
+ if (buf == NULL)
+ goto end;
+
+ LOGD("phFriNfc_NdefRecord_Generate()");
+
+ status = phFriNfc_NdefRecord_Generate(&record, buf, buf_size,
+ &record_size);
+
+ if (status) {
+ LOGE("phFriNfc_NdefRecord_Generate() returned 0x%04x", status);
+ goto end;
+ }
+ LOGD("phFriNfc_NdefRecord_Generate() returned 0x%04x", status);
+
+ result = e->NewByteArray(record_size);
+ if (result == NULL)
+ goto end;
+
+ e->SetByteArrayRegion(result, 0, record_size, (jbyte *)buf);
+
+end:
+ e->ReleaseByteArrayElements(type, (jbyte *)record.Type, JNI_ABORT);
+ e->ReleaseByteArrayElements(id, (jbyte *)record.Id, JNI_ABORT);
+ e->ReleaseByteArrayElements(payload, (jbyte *)record.PayloadData, JNI_ABORT);
+
+ if(buf)
+ free(buf);
+
+ return result;
+}
+
+static JNINativeMethod gMethods[] = {
+ {"generate", "(SS[B[B[B)[B", (void *)android_nfc_NdefRecord_generate},
+};
+
+int register_android_nfc_NdefRecord(JNIEnv *e)
+{
+ return jniRegisterNativeMethods(e, "android/nfc/NdefRecord", gMethods, NELEM(gMethods));
+}
+
+} // namespace android