Update to API changes.

Change-Id: I8f52bf20f493581aef80201b4b112af28cf3b5fa
diff --git a/jni/com_android_nfc.h b/jni/com_android_nfc.h
index ae361f7..881c48c 100644
--- a/jni/com_android_nfc.h
+++ b/jni/com_android_nfc.h
@@ -63,19 +63,17 @@
 #define ERROR_BUFFER_TOO_SMALL            -12
 #define ERROR_INSUFFICIENT_RESOURCES      -9
 
-/* Name strings for target types */
-#define TARGET_TYPE_ISO14443_3A     "Iso14443-3A"
-#define TARGET_TYPE_ISO14443_3B     "Iso14443-3B"
-#define TARGET_TYPE_ISO14443_4      "Iso14443-4"
-#define TARGET_TYPE_ISO15693        "Iso15693"
-#define TARGET_TYPE_MIFARE_UL       "MifareUL"
-#define TARGET_TYPE_MIFARE_1K       "Mifare1K"
-#define TARGET_TYPE_MIFARE_4K       "Mifare4K"
-#define TARGET_TYPE_MIFARE_DESFIRE  "MifareDESFIRE"
-#define TARGET_TYPE_MIFARE_UNKNOWN  "Unknown Mifare"
-#define TARGET_TYPE_FELICA          "Felica"
-#define TARGET_TYPE_JEWEL           "Jewel"
-#define TARGET_TYPE_UNKNOWN         "Unknown Type"
+/* Name strings for target types. These *must* match the values in TagTechnology.java */
+#define TARGET_TYPE_UNKNOWN               -1
+#define TARGET_TYPE_ISO14443_3A           1
+#define TARGET_TYPE_ISO14443_3B           2
+#define TARGET_TYPE_ISO14443_4            3
+#define TARGET_TYPE_ISO15693              21
+#define TARGET_TYPE_MIFARE_CLASSIC        200
+#define TARGET_TYPE_MIFARE_UL             202
+#define TARGET_TYPE_MIFARE_DESFIRE        203
+#define TARGET_TYPE_FELICA                11
+#define TARGET_TYPE_JEWEL                 101
 
 /* Utility macros for logging */
 #define GET_LEVEL(status) ((status)==NFCSTATUS_SUCCESS)?ANDROID_LOG_DEBUG:ANDROID_LOG_WARN
diff --git a/jni/com_android_nfc_NativeNfcManager.cpp b/jni/com_android_nfc_NativeNfcManager.cpp
index 56ab872..cd32ede 100644
--- a/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/jni/com_android_nfc_NativeNfcManager.cpp
@@ -417,7 +417,7 @@
 /*
  *  Utility to get target type name from its specs
  */
-static const char* get_target_type_name(phNfc_eRemDevType_t type, uint8_t sak)
+static int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak)
 {
    switch (type)
    {
@@ -452,27 +452,25 @@
         {
           switch(sak)
           {
-            case 0:
-              {
-                return TARGET_TYPE_MIFARE_UL;
-              }break;
-            case 8:
-              {
-                return TARGET_TYPE_MIFARE_1K;
-              }break;
-            case 24:
-              {
-                return TARGET_TYPE_MIFARE_4K;
-              }break;
-              
-            case 32:
-              {
-                return TARGET_TYPE_MIFARE_DESFIRE;
-              }break;
-              
+            case 0x00:
+              // could be UL or UL-C
+              return TARGET_TYPE_MIFARE_UL;
+            case 0x08:
+            case 0x09:
+            case 0x10:
+            case 0x11:
+            case 0x18:
+            case 0x28:
+            case 0x38:
+            case 0x88:
+            case 0x98:
+            case 0xB8:
+              return TARGET_TYPE_MIFARE_CLASSIC;
+            case 0x20:
+              return TARGET_TYPE_MIFARE_DESFIRE;
             default:
               {
-                return TARGET_TYPE_MIFARE_UNKNOWN;
+                return TARGET_TYPE_UNKNOWN;
               }break;
           }
         }break;
@@ -983,12 +981,21 @@
         }
         e->SetObjectField(tag, f, tagUid);
 
-        /* Set tag type */
-        typeName = get_target_type_name( psRemoteDevList[target_index].psRemoteDevInfo->RemDevType,
-                          psRemoteDevList[target_index].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
-        LOGD("Discovered tag: type=0x%08x[%s]", psRemoteDevList[target_index].psRemoteDevInfo->RemDevType, typeName);
-        f = e->GetFieldID(tag_cls, "mType", "Ljava/lang/String;");
-        e->SetObjectField(tag, f, e->NewStringUTF(typeName));
+        /* Generate technology list */
+        jintArray techList;
+        int tech = get_technology_type(psRemoteDevList[target_index].psRemoteDevInfo->RemDevType,
+            psRemoteDevList[target_index].psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Sak);
+        if (tech != TARGET_TYPE_UNKNOWN) {
+            LOGD("Tag tech: %d", tech);
+            techList = e->NewIntArray(1);
+            e->SetIntArrayRegion(techList, 0, 1, &tech);
+        } else {
+            techList = e->NewIntArray(0);
+        }
+
+        /* Push the technology list into the java object */
+        f = e->GetFieldID(tag_cls, "mTechList", "[I");
+        e->SetObjectField(tag, f, techList);
 
         /* Set tag polling bytes */
         TRACE("Set Tag PollBytes");
diff --git a/src/com/android/nfc/NativeNfcManager.java b/src/com/android/nfc/NativeNfcManager.java
index cb74279..a2b6d51 100755
--- a/src/com/android/nfc/NativeNfcManager.java
+++ b/src/com/android/nfc/NativeNfcManager.java
@@ -19,14 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.content.Intent;
-import android.nfc.NdefTag;
-import android.nfc.NfcAdapter;
-import android.nfc.NdefMessage;
-import android.nfc.Tag;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
 
 /**
  * Native interface to the NFC Manager functions
diff --git a/src/com/android/nfc/NativeNfcTag.java b/src/com/android/nfc/NativeNfcTag.java
index 075fdf3..ae1bc18 100755
--- a/src/com/android/nfc/NativeNfcTag.java
+++ b/src/com/android/nfc/NativeNfcTag.java
@@ -16,6 +16,10 @@
 
 package com.android.nfc;
 
+import android.nfc.technology.NfcA;
+import android.nfc.technology.NfcB;
+import android.nfc.technology.TagTechnology;
+import android.os.Bundle;
 import android.util.Log;
 
 /**
@@ -26,18 +30,16 @@
 
     private int mHandle;
 
-    private String mType;
-
+    private int[] mTechList;
+    private Bundle[] mTechExtras;
     private byte[] mPollBytes;
-
     private byte[] mActivationBytes;
-
     private byte[] mUid;
 
     private final String TAG = "NativeNfcTag";
 
     private PresenceCheckWatchdog mWatchdog;
-    private class PresenceCheckWatchdog extends Thread {
+    class PresenceCheckWatchdog extends Thread {
 
         private boolean isPresent = true;
         private boolean isRunning = true;
@@ -81,7 +83,7 @@
         return isSuccess;
     }
 
-    private native boolean doDisconnect();
+    native boolean doDisconnect();
     public synchronized boolean disconnect() {
         if (mWatchdog != null) {
             mWatchdog.end();
@@ -121,7 +123,7 @@
         return doWrite(buf);
     }
 
-    private native boolean doPresenceCheck();
+    native boolean doPresenceCheck();
     public synchronized boolean presenceCheck() {
         if (mWatchdog != null) {
             mWatchdog.reset();
@@ -136,20 +138,45 @@
         return mHandle;
     }
 
-    public String getType() {
-        return mType;
-    }
-
     public byte[] getUid() {
         return mUid;
     }
 
-    public byte[] getPollBytes() {
-        return mPollBytes;
+    public int[] getTechList() {
+        return mTechList;
     }
 
-    public byte[] getActivationBytes() {
-        return mActivationBytes;
-    }
+    public Bundle[] getTechExtras() {
+        synchronized (this) {
+            if (mTechExtras != null) return mTechExtras;
+            mTechExtras = new Bundle[mTechList.length];
+            for (int i = 0; i < mTechList.length; i++) {
+                Bundle extras = new Bundle();
+                switch (mTechList[i]) {
+                    case TagTechnology.ISO_14443_3A: {
+                        byte[] actBytes = mActivationBytes;
+                        if ((actBytes != null) && (actBytes.length > 0)) {
+                            extras.putShort(NfcA.EXTRA_SAK, (short) (actBytes[0] & (short) 0xFF));
+                        } else {
+                            throw new IllegalStateException("missing activation bytes");
+                        }
+                        extras.putByteArray(NfcA.EXTRA_ATQA, mPollBytes);
+                        break;
+                    }
 
+                    case TagTechnology.ISO_14443_3B: {
+                        extras.putByteArray(NfcB.EXTRA_ATQB, mPollBytes);
+                        break;
+                    }
+
+                    default: {
+                        // Leave the entry in the array null
+                        continue;
+                    }
+                }
+                mTechExtras[i] = extras;
+            }
+            return mTechExtras;
+        }
+    }
 }
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index aaef3ef..ce67581 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -40,10 +40,10 @@
 import android.nfc.IP2pTarget;
 import android.nfc.LlcpPacket;
 import android.nfc.NdefMessage;
-import android.nfc.NdefTag;
 import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.os.AsyncTask;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
@@ -160,7 +160,7 @@
     static final int MSG_TARGET_DESELECTED = 4;
     static final int MSG_SHOW_MY_TAG_ICON = 5;
     static final int MSG_HIDE_MY_TAG_ICON = 6;
-    static final int MSG_MOCK_NDEF_TAG = 7;
+    static final int MSG_MOCK_NDEF = 7;
 
     // TODO: none of these appear to be synchronized but are
     // read/written from different threads (notably Binder threads)...
@@ -1376,22 +1376,18 @@
         }
 
         @Override
-        public String getType(int nativeHandle) throws RemoteException {
+        public int[] getTechList(int nativeHandle) throws RemoteException {
             mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR);
 
-            NativeNfcTag tag = null;
-            String type;
-
             // Check if NFC is enabled
             if (!mIsNfcEnabled) {
                 return null;
             }
 
             /* find the tag in the hmap */
-            tag = (NativeNfcTag) findObject(nativeHandle);
+            NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle);
             if (tag != null) {
-                type = tag.getType();
-                return type;
+                return tag.getTechList();
             }
             return null;
         }
@@ -2161,11 +2157,7 @@
     }
 
     public void sendMockNdefTag(NdefMessage msg) {
-        NdefTag tag = NdefTag.createMockNdefTag(new byte[] { 0x00 },
-                new String[] { Tag.TARGET_OTHER },
-                null, null, new String[] { NdefTag.TARGET_OTHER },
-                new NdefMessage[][] { new NdefMessage[] { msg } });
-        sendMessage(MSG_MOCK_NDEF_TAG, tag);
+        sendMessage(MSG_MOCK_NDEF, msg);
     }
 
     void sendMessage(int what, Object obj) {
@@ -2175,13 +2167,16 @@
         mHandler.sendMessage(msg);
     }
 
-    private final Handler mHandler = new Handler() {
+    final class NfcServiceHandler extends Handler {
         @Override
         public void handleMessage(Message msg) {
            switch (msg.what) {
-           case MSG_MOCK_NDEF_TAG: {
-               NdefTag tag = (NdefTag) msg.obj;
-               Intent intent = buildNdefTagIntent(tag);
+           case MSG_MOCK_NDEF: {
+               NdefMessage ndefMsg = (NdefMessage) msg.obj;
+               Tag tag = Tag.createMockTag(new byte[] { 0x00 },
+                       new int[] { },
+                       new Bundle[] { });
+               Intent intent = buildTagIntent(tag, new NdefMessage[] { ndefMsg });
                Log.d(TAG, "mock NDEF tag, starting corresponding activity");
                Log.d(TAG, tag.toString());
                try {
@@ -2203,13 +2198,11 @@
                            NdefMessage[] msgNdef = new NdefMessage[1];
                            try {
                                msgNdef[0] = new NdefMessage(buff);
-                               NdefTag tag = new NdefTag(nativeTag.getUid(),
-                                       TagTarget.internalTypeToRawTargets(nativeTag.getType()),
-                                       nativeTag.getPollBytes(), nativeTag.getActivationBytes(), 
-                                       nativeTag.getHandle(),
-                                       TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
-                                       new NdefMessage[][] {msgNdef});
-                               Intent intent = buildNdefTagIntent(tag);
+                               Tag tag = new Tag(nativeTag.getUid(),
+                                       nativeTag.getTechList(),
+                                       nativeTag.getTechExtras(),
+                                       nativeTag.getHandle());
+                               Intent intent = buildTagIntent(tag, msgNdef);
                                if (DBG) Log.d(TAG, "NDEF tag found, starting corresponding activity");
                                if (DBG) Log.d(TAG, tag.toString());
                                try {
@@ -2229,13 +2222,11 @@
                        }
                        if (generateEmptyIntent) {
                            // Create an intent with an empty ndef message array
-                           NdefTag tag = new NdefTag(nativeTag.getUid(),
-                                   TagTarget.internalTypeToRawTargets(nativeTag.getType()),
-                                   nativeTag.getPollBytes(), nativeTag.getActivationBytes(),
-                                   nativeTag.getHandle(),
-                                   TagTarget.internalTypeToNdefTargets(nativeTag.getType()),
-                                   new NdefMessage[][] { {} });
-                           Intent intent = buildNdefTagIntent(tag);
+                           Tag tag = new Tag(nativeTag.getUid(),
+                                   nativeTag.getTechList(),
+                                   nativeTag.getTechExtras(),
+                                   nativeTag.getHandle());
+                           Intent intent = buildTagIntent(tag, new NdefMessage[] { });
                            if (DBG) Log.d(TAG, "NDEF tag found, but length 0 or invalid format, starting corresponding activity");
                            try {
                                mContext.startActivity(intent);
@@ -2246,15 +2237,11 @@
                            }
                        }
                    } else {
-                       Intent intent = new Intent();
-                       Tag tag = new Tag(nativeTag.getUid(), false,
-                               TagTarget.internalTypeToRawTargets(nativeTag.getType()),
-                               nativeTag.getPollBytes(), nativeTag.getActivationBytes(), 
+                       Tag tag = new Tag(nativeTag.getUid(),
+                               nativeTag.getTechList(),
+                               nativeTag.getTechExtras(),
                                nativeTag.getHandle());
-                       intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
-                       intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
-                       intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
-                       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                       Intent intent = buildTagIntent(tag, null);
                        if (DBG) Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
                        if (DBG) Log.d(TAG, tag.toString());
                        try {
@@ -2378,17 +2365,18 @@
            }
         }
 
-        private Intent buildNdefTagIntent(NdefTag tag) {
-            Intent intent = new Intent();
-               intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
-               intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
-               intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
-               intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, tag.getNdefMessages());
-               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        private Intent buildTagIntent(Tag tag, NdefMessage[] msgs) {
+            Intent intent = new Intent(NfcAdapter.ACTION_TAG_DISCOVERED);
+            intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
+            intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId());
+            intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, msgs);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             return intent;
         }
-    };
+    }
 
+    private NfcServiceHandler mHandler = new NfcServiceHandler();
+    
     private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> {
         @Override
         protected Void doInBackground(Boolean... enable) {
diff --git a/src/com/android/nfc/TagTarget.java b/src/com/android/nfc/TagTarget.java
deleted file mode 100644
index e835f78..0000000
--- a/src/com/android/nfc/TagTarget.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.nfc;
-
-import java.util.HashMap;
-
-import android.nfc.NdefTag;
-import android.nfc.Tag;
-
-/**
- * Helper to convert between internal tag types and public target types
- */
-public abstract class TagTarget {
-    static final String INTERNAL_TARGET_TYPE_ISO14443_3A = "Iso14443-3A";
-    static final String INTERNAL_TARGET_TYPE_ISO14443_3B = "Iso14443-3B";
-    static final String INTERNAL_TARGET_TYPE_ISO14443_4 = "Iso14443-4";
-    static final String INTERNAL_TARGET_TYPE_MIFARE_UL = "MifareUL";
-    static final String INTERNAL_TARGET_TYPE_MIFARE_1K = "Mifare1K";
-    static final String INTERNAL_TARGET_TYPE_MIFARE_4K = "Mifare4K";
-    static final String INTERNAL_TARGET_TYPE_MIFARE_DESFIRE = "MifareDESFIRE";
-    static final String INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN = "Unknown Mifare";
-    static final String INTERNAL_TARGET_TYPE_FELICA = "Felica";
-    static final String INTERNAL_TARGET_TYPE_JEWEL = "Jewel";
-    static final String INTERNAL_TARGET_TYPE_UNKNOWN = "Unknown Type";
-
-    static final HashMap<String, String[]> INT_TYPE_TO_RAW_TARGETS = new HashMap<String, String[]>() {
-        {
-            /* TODO: handle multiprotocol */
-            put(INTERNAL_TARGET_TYPE_ISO14443_3A, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_ISO14443_3B, new String[] { Tag.TARGET_ISO_14443_3B });
-            put(INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN, new String[] { Tag.TARGET_ISO_14443_3A });
-            put(INTERNAL_TARGET_TYPE_FELICA, new String[] { Tag.TARGET_JIS_X_6319_4 });
-            put(INTERNAL_TARGET_TYPE_JEWEL, new String[] { Tag.TARGET_ISO_14443_3A });
-        }
-    };
-
-    static final HashMap<String, String[]> INT_TYPE_TO_NDEF_TARGETS = new HashMap<String, String[]>() {
-        {
-            // TODO: handle multiprotocol
-            put(INTERNAL_TARGET_TYPE_JEWEL, new String[] { NdefTag.TARGET_TYPE_1 });
-            put(INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { NdefTag.TARGET_TYPE_2 });
-            put(INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { NdefTag.TARGET_MIFARE_CLASSIC });
-            put(INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { NdefTag.TARGET_MIFARE_CLASSIC });
-            put(INTERNAL_TARGET_TYPE_FELICA, new String[] { NdefTag.TARGET_TYPE_3 });
-            put(INTERNAL_TARGET_TYPE_ISO14443_4, new String[] { NdefTag.TARGET_TYPE_4 });
-            put(INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { NdefTag.TARGET_TYPE_4 });
-        }
-    };
-
-    static String[] internalTypeToRawTargets(String internalType) {
-        String[] rawTargets = INT_TYPE_TO_RAW_TARGETS.get(internalType);
-        if (rawTargets == null) {
-            rawTargets = new String[] { Tag.TARGET_OTHER };
-        }
-        return rawTargets;
-    }
-
-    static String[] internalTypeToNdefTargets(String internalType) {
-        String[] ndefTargets = INT_TYPE_TO_NDEF_TARGETS.get(internalType);
-        if (ndefTargets == null) {
-            ndefTargets = new String[] { NdefTag.TARGET_OTHER };
-        }
-        return ndefTargets;
-    }
-}