diff options
author | Nick Pelly <npelly@google.com> | 2010-10-13 17:25:24 -0700 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2010-10-15 02:12:32 -0700 |
commit | bc21fdefdfbeba1754c6cd339c7dd8e8f1d6fd48 (patch) | |
tree | 8b58be37237ea58089f6541403fd3092ff64f6bc /core/jni | |
parent | c1e7b2182594aa0463c4a738cc8e7eea6777ef50 (diff) | |
download | frameworks_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.mk | 13 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 28 | ||||
-rw-r--r-- | core/jni/android_nfc.h | 54 | ||||
-rw-r--r-- | core/jni/android_nfc_NdefMessage.cpp | 175 | ||||
-rw-r--r-- | core/jni/android_nfc_NdefRecord.cpp | 92 |
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 |