NfcService.java revision e260fc52ed2b4e6e1b7394d6f841d01c98888327
1f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly/* 2f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Copyright (C) 2010 The Android Open Source Project 3f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 4f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * you may not use this file except in compliance with the License. 6f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * You may obtain a copy of the License at 7f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 8f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * 10f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * Unless required by applicable law or agreed to in writing, software 11f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * See the License for the specific language governing permissions and 14f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly * limitations under the License. 15f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly */ 16f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellypackage com.android.nfc; 18f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 19d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.internal.nfc.LlcpServiceSocket; 20d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamiltonimport com.android.internal.nfc.LlcpSocket; 2124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport com.android.nfc.RegisteredComponentCache.ComponentInfo; 22ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport com.android.nfc.ndefpush.NdefPushClient; 23ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport com.android.nfc.ndefpush.NdefPushServer; 24d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.Activity; 261a9eca5f84036d7dd3e28000290caa2f641856deNick Pellyimport android.app.ActivityManagerNative; 272f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application; 2824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.app.IActivityManager; 2905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.PendingIntent; 30ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamiltonimport android.app.PendingIntent.CanceledException; 3124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.app.StatusBarManager; 32b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.content.ActivityNotFoundException; 3313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.BroadcastReceiver; 3405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.content.ComponentName; 3513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Context; 3613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Intent; 3713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.IntentFilter; 380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.content.SharedPreferences; 3924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.ResolveInfo; 403fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.net.Uri; 41f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ErrorCodes; 42f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.FormatException; 43f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpConnectionlessSocket; 44f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpServiceSocket; 45f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpSocket; 460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.INfcAdapter; 473fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.nfc.INfcSecureElement; 48f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.INfcTag; 49f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pInitiator; 50f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pTarget; 51f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.LlcpPacket; 52f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NdefMessage; 533fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.nfc.NdefRecord; 54f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter; 550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag; 5624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.nfc.TechListParcel; 579d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenenimport android.nfc.TransceiveResult; 587c034a7fe7d36b1ab039af2c44717812ea02657eNick Pellyimport android.os.AsyncTask; 59b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamiltonimport android.os.Bundle; 60b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler; 61b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message; 62533043d1003de2f6a20a29201100d94c3c7bc9caNick Pellyimport android.os.PowerManager; 63f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException; 6413d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager; 65f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log; 66f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 6757d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.ByteArrayOutputStream; 6857d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileInputStream; 6957d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileNotFoundException; 7057d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileOutputStream; 7157d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException; 723fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.nio.charset.Charsets; 7324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.ArrayList; 743fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.util.Arrays; 753ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap; 762436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Feririmport java.util.Iterator; 770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasimport java.util.Timer; 780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomasimport java.util.TimerTask; 793ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton 802f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application { 81ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton static final boolean DBG = false; 82fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 8357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton private static final String MY_TAG_FILE_NAME = "mytag"; 8457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 8513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly static { 8613d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly System.loadLibrary("nfc_jni"); 8713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly } 8813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 893fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** 903fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" 913fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 923fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * This is a mapping of "URI Identifier Codes" to URI string prefixes, 933fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * per section 3.2.2 of the NFC Forum URI Record Type Definition document. 943fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 953fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private static final String[] URI_PREFIX_MAP = new String[] { 963fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "", // 0x00 973fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://www.", // 0x01 983fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://www.", // 0x02 993fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://", // 0x03 1003fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://", // 0x04 1013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tel:", // 0x05 1023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "mailto:", // 0x06 1033fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://anonymous:anonymous@", // 0x07 1043fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://ftp.", // 0x08 1053fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftps://", // 0x09 1063fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sftp://", // 0x0A 1073fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "smb://", // 0x0B 1083fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "nfs://", // 0x0C 1093fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://", // 0x0D 1103fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "dav://", // 0x0E 1113fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "news:", // 0x0F 1123fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "telnet://", // 0x10 1133fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "imap:", // 0x11 1143fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "rtsp://", // 0x12 1153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:", // 0x13 1163fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "pop:", // 0x14 1173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sip:", // 0x15 1183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sips:", // 0x16 1193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tftp:", // 0x17 1203fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btspp://", // 0x18 1213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btl2cap://", // 0x19 1223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btgoep://", // 0x1A 1233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tcpobex://", // 0x1B 1243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "irdaobex://", // 0x1C 1253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "file://", // 0x1D 1263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:id:", // 0x1E 1273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:tag:", // 0x1F 1283fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:pat:", // 0x20 1293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:raw:", // 0x21 1303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:", // 0x22 1313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton }; 1323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 133d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static final String SERVICE_NAME = "nfc"; 134fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 135f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String TAG = "NfcService"; 136f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 137bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM = android.Manifest.permission.NFC; 138bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM_ERROR = "NFC permission required"; 139bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 140bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 141bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF = "NfcServicePrefs"; 143f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_NFC_ON = "nfc_on"; 1450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean NFC_ON_DEFAULT = true; 146f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_SECURE_ELEMENT_ON = "secure_element_on"; 1480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean SECURE_ELEMENT_ON_DEFAULT = false; 149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_SECURE_ELEMENT_ID = "secure_element_id"; 1510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int SECURE_ELEMENT_ID_DEFAULT = 0; 152f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_LTO = "llcp_lto"; 154e1fac398523a97e3bcf513393a91478d79a8763fSylvain Fonteneau private static final int LLCP_LTO_DEFAULT = 150; 1550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_LTO_MAX = 255; 156f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Maximum Information Unit */ 1580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_MIU = "llcp_miu"; 1590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_DEFAULT = 128; 1600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_MAX = 2176; 161f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Well Known Service List */ 1630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_WKS = "llcp_wks"; 1640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_DEFAULT = 1; 1650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_MAX = 15; 166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_OPT = "llcp_opt"; 1680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_DEFAULT = 0; 1690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_MAX = 3; 170f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_A = "discovery_a"; 1720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_A_DEFAULT = true; 173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_B = "discovery_b"; 1750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_B_DEFAULT = true; 176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_F = "discovery_f"; 1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_F_DEFAULT = true; 179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_15693 = "discovery_15693"; 1810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_15693_DEFAULT = true; 182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip"; 184a989351c7383aa6b3a6086b10f32c39c1d28fa5dJeff Hamilton private static final boolean DISCOVERY_NFCIP_DEFAULT = true; 185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** NFC Reader Discovery mode for enableDiscovery() */ 1870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int DISCOVERY_MODE_READER = 0; 188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_LLCP_LTO = 0; 190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; 1910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_MIU = 1; 192f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; 1930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_WKS = 2; 194f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; 1950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_OPT = 3; 196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; 197f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_NFC_DISCOVERY_A = 4; 198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; 1990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_B = 5; 200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; 2010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_F = 6; 202f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; 2030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; 204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; 2050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; 206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; 207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 208b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_NDEF_TAG = 0; 209b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_CARD_EMULATION = 1; 210b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_ACTIVATION = 2; 211b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_DEACTIVATED = 3; 212b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_TARGET_DESELECTED = 4; 21357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_SHOW_MY_TAG_ICON = 5; 21457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_HIDE_MY_TAG_ICON = 6; 215b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton static final int MSG_MOCK_NDEF = 7; 216c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_ACTIVATED = 8; 217c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_DEACTIVATED = 9; 218b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 21905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Locked on mNfcAdapter 22005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent mDispatchOverrideIntent; 22124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] mDispatchOverrideFilters; 22224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] mDispatchOverrideTechLists; 22305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 22474180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 22574180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private int mGeneratedSocketHandle = 0; 22774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick private volatile boolean mIsNfcEnabled = false; 228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private int mSelectedSeId = 0; 2290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private boolean mNfcSecureElementState; 230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Secure element 2320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private Timer mTimerOpenSmx; 2330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private boolean isClosed = false; 2340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private boolean isOpened = false; 2350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private boolean mOpenSmxPending = false; 2360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private NativeNfcSecureElement mSecureElement; 2370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private int mSecureElementHandle; 2380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2392f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are used in multiple threads and protected by synchronized(this) 2402f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 2412f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 24265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly private boolean mScreenOn; 2432f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2442f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are final after onCreate() 24505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Context mContext; 2460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private NativeNfcManager mManager; 2470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences mPrefs; 2480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences.Editor mPrefsEditor; 249533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly private PowerManager.WakeLock mWakeLock; 2501a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly private IActivityManager mIActivityManager; 251ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushClient mNdefPushClient; 252ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushServer mNdefPushServer; 25324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton RegisteredComponentCache mTechListFilters; 254d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 255d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton private static NfcService sService; 256d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 257d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static NfcService getInstance() { 258d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return sService; 259d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 2620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onCreate() { 2632f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onCreate(); 2642f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Log.i(TAG, "Starting NFC service"); 2662f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 267d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton sService = this; 268d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext = this; 270b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mManager = new NativeNfcManager(mContext, this); 2710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.initializeNativeStructure(); 27274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick 273ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushClient = new NdefPushClient(this); 274ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer = new NdefPushServer(); 27557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 27624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mTechListFilters = new RegisteredComponentCache(this, 27724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED, NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED); 27824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 2790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElement = new NativeNfcSecureElement(); 2800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); 2820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor = mPrefs.edit(); 283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 284d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly mIsNfcEnabled = false; // real preference read later 285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 286533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 28752028e699e43e6322021098bbefd761fe6596747Nick Pelly mScreenOn = pm.isScreenOn(); 288533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 289533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly 2901a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager = ActivityManagerNative.getDefault(); 2911a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly 292d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 294eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 29565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_OFF); 29665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_ON); 2970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext.registerReceiver(mReceiver, filter); 2980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 2990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Thread t = new Thread() { 3000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void run() { 3020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 3030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (nfc_on) { 3040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly _enable(false); 305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 3080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly t.start(); 3090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly public void onTerminate() { 3132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onTerminate(); 3142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // NFC application is persistent, it should not be destroyed by framework 3150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Log.wtf(TAG, "NFC service is under attack!"); 3160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 3193ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton /** Protected by "this" */ 3203ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton NdefMessage mLocalMessage = null; 3214acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly 322fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean enable() throws RemoteException { 324d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 3250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 3270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 3280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!previouslyEnabled) { 3290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly reset(); 3300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = _enable(previouslyEnabled); 331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 335fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disable() throws RemoteException { 3370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 338d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 3390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 340ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 3410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (previouslyEnabled) { 3436f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton /* tear down the my tag server */ 344ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.stop(); 345e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 346e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // Stop watchdog if tag present 347e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // A convenient way to stop the watchdog properly consists of 348e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // disconnecting the tag. The polling loop shall be stopped before 349e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // to avoid the tag being discovered again. 350e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir maybeDisableDiscovery(); 351e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir maybeDisconnectTarget(); 352e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 3530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = mManager.deinitialize(); 354ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 3550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 3560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 357a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Clear out any old dispatch overrides and NDEF push message 35805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 35905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 36005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 36105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 362a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mNdefPushClient.setForegroundMessage(null); 3630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 364f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(previouslyEnabled); 3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 370f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 371fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 37205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void enableForegroundDispatch(ComponentName activity, PendingIntent intent, 37324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] filters, TechListParcel techListsParcel) { 374a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Permission check 37505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 376a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 377a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Argument validation 378a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (activity == null || intent == null) { 379ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 380ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 381a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 382a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Validate the IntentFilters 383a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters != null) { 384a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters.length == 0) { 385a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton filters = null; 386a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 387a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : filters) { 388a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter == null) { 389a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton throw new IllegalArgumentException("null IntentFilter"); 390a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 391a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 392a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 393a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 394a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 39524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Validate the tech lists 39624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] techLists = null; 39724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (techListsParcel != null) { 39824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton techLists = techListsParcel.getTechLists(); 39924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 40024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 40105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 402a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent != null) { 40305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "Replacing active dispatch overrides"); 40405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 40505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = intent; 406a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = filters; 40724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = techLists; 40805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 40905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 41005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 41105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 41205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void disableForegroundDispatch(ComponentName activity) { 41305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 41405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 415a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent == null) { 41605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "No active foreground dispatching"); 41705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 41805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 419a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = null; 42005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 42105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 42205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 42305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 424ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void enableForegroundNdefPush(ComponentName activity, NdefMessage msg) { 425ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 426ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (activity == null || msg == null) { 427ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 428ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 429ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (mNdefPushClient.setForegroundMessage(msg)) { 430ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "Replacing active NDEF push message"); 431ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 432ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 433ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 434ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 435ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void disableForegroundNdefPush(ComponentName activity) { 436ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 437ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (!mNdefPushClient.setForegroundMessage(null)) { 438ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "No active foreground NDEF push message"); 439ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 440ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 441ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 442ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 4430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 444d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 445bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 450f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 4510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check SAP is not already used */ 4520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4531878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Store the socket handle */ 4541878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int sockeHandle = mGeneratedSocketHandle; 4551878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpConnectionlessSocket socket; 456f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 4571878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpConnectionlessSocket(sap); 4581878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 4591878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 4601878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 4611878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 4620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4631878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 4641878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 4651878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 4681878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 4691878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 4701878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 4711878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 4721878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 4731878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 4741878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 4751878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 4761878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 4771878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 4781878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 482fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 4830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 4840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 485d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 486bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 487f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 4921878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpServiceSocket socket; 4930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4941878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 4951878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 4961878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 4971878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 4981878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 4990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5001878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5011878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5051878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5061878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5071878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5081878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5091878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5101878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5111878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5121878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5131878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5141878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5151878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 519fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 5210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 522d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 523bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5291878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (DBG) Log.d(TAG, "creating llcp socket"); 5301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpSocket socket; 531bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 5321878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5341878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5351878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5361878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5371878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5391878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5401878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5411878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 5420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5441878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5451878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5461878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5471878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 5481878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5491878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5501878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5511878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5521878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5531878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5541878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5551878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5561878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 557f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 558f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 559f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 560fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int deselectSecureElement() throws RemoteException { 562d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 563f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 564f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 565f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 566f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 567f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 568f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (mSelectedSeId == 0) { 5700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NO_SE_CONNECTED; 571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 5720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doDeselectSecureElement(mSelectedSeId); 5740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mNfcSecureElementState = false; 5750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mSelectedSeId = 0; 5760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* store preference */ 5780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, false); 5790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, 0); 5802f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 5810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 583f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 584f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 585fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 587d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 5880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpConnectionlessSocketService; 5890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 590bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 591fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpSocket getLlcpInterface() throws RemoteException { 593d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 5940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpSocket; 5950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 596f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 597fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 599d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpServerSocketService; 6010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 602f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 603fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public INfcTag getNfcTagInterface() throws RemoteException { 605d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mNfcTagService; 6070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 609fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 611d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pInitiatorService; 6130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 615fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pTarget getP2pTargetInterface() throws RemoteException { 617d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pTargetService; 6190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public INfcSecureElement getNfcSecureElementInterface() { 6220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return mSecureElementService; 6240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 626fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public String getProperties(String param) throws RemoteException { 628d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null) { 6310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 6320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 6350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 6360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 6370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 6380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 6390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 6400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 6410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 6420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT)); 6440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT)); 6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 6470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT)); 6480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT)); 6500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT)); 652f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 6530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return "Unknown property"; 654f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 655f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 656f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 657fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int[] getSecureElementList() throws RemoteException { 659d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 660bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int[] list = null; 6620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (mIsNfcEnabled == true) { 6630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly list = mManager.doGetSecureElementList(); 6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return list; 6660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 668fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getSelectedSecureElement() throws RemoteException { 670d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mSelectedSeId; 6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 675fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean isEnabled() throws RemoteException { 6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mIsNfcEnabled; 6780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 680fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void openTagConnection(Tag tag) throws RemoteException { 682b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau // TODO: Remove obsolete code 6830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 685fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int selectSecureElement(int seId) throws RemoteException { 687d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 688f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 689f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 690f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 691f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 692f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 693f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (mSelectedSeId == seId) { 6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SE_ALREADY_SELECTED; 6960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (mSelectedSeId != 0) { 6990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SE_CONNECTED; 7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mSelectedSeId = seId; 7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSelectSecureElement(mSelectedSeId); 7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* store */ 7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_SECURE_ELEMENT_ON, true); 7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_SECURE_ELEMENT_ID, mSelectedSeId); 7082f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mNfcSecureElementState = true; 7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 7130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 716fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int setProperties(String param, String value) throws RemoteException { 718d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 7190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isEnabled()) { 7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NFC_ON; 7220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int val; 7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params validity */ 7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null || value == null) { 7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_LTO_MAX) 7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_LTO, val); 7402f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, val); 7440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX)) 7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_MIU, val); 7542f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, val); 7580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 7600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_WKS_MAX) 7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_WKS, val); 7682f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, val); 7720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_OPT_MAX) 7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_OPT, val); 7822f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, val); 7860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 7880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b); 7922f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0); 7960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b); 8022f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0); 8060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b); 8122f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0); 8160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b); 8222f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0); 8260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b); 8322f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0); 8360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 837f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 839f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 8400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 842f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 843d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 844d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 845d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public NdefMessage localGet() throws RemoteException { 84657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 84757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 84857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 84957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton return mLocalMessage; 85057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 851d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 852d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 853d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 854d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public void localSet(NdefMessage message) throws RemoteException { 85557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mContext.enforceCallingOrSelfPermission(ADMIN_PERM, ADMIN_PERM_ERROR); 85657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 85757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 85857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mLocalMessage = message; 85957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = NfcService.this.getApplicationContext(); 86057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 86157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Send a message to the UI thread to show or hide the icon so the requests are 86257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // serialized and the icon can't get out of sync with reality. 86357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (message != null) { 86457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileOutputStream out = null; 86557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 86657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 86757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE); 86857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] bytes = message.toByteArray(); 86957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (bytes.length == 0) { 87057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.w(TAG, "Setting a empty mytag"); 87157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 87257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 87357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.write(bytes); 87457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 87557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not write mytag file", e); 87657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 87757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 87857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (out != null) { 87957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.flush(); 88057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.close(); 88157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 88257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 88357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 88457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 88557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 88657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 88757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Only show the icon if NFC is enabled. 88857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 88957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_SHOW_MY_TAG_ICON, null); 89057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 89157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 89257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 89357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 89457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 89557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 896d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 8970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 8980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 900f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 901f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpSocket findSocket(int nativeHandle) { 902bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 903bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpSocket)) { 904f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 905f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 906bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpSocket) socket; 907f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 908f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 909fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int close(int nativeHandle) throws RemoteException { 911d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 912bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 913f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 914f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 915f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 916f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 917f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 921f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 9231878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 9241878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 9251878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 9261878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.SUCCESS; 927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 9280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 929f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 930f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 931f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 932fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle, int sap) throws RemoteException { 934d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 935bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 9370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 938f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 939f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 940f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 942f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 945f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 94793915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnect(sap); 9480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 9490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 950f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 952f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 953f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 954f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 959fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connectByName(int nativeHandle, String sn) throws RemoteException { 961d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 962bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 964f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 965f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 966f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 967f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 972f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 97493915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnectBy(sn); 975f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 976f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 977f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 979f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 986fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSap(int nativeHandle) throws RemoteException { 988d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 989bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 9900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 991f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 992f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 993f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 994f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 995f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 9970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 998f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 9990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getSap(); 1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 10020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 1003f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1004f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1005f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1006fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 1008d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1009bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 10100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 1011f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1013f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 10140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1015f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1016f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1017f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1018f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1019f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 10200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getMiu(); 10210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 1023f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1025f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1026fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketRw(int nativeHandle) throws RemoteException { 1028d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1029bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 10300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 1031f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1032f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1033f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1034f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1035f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1036f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1037f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1038f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getRw(); 10410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 10430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1046fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 1048d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1058f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketMiu() != 0) { 10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketMiu(); 10620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1070fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 1072d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1082f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketRw() != 0) { 10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketRw(); 10860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1094fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 1096d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1106f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 110828f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return socket.doReceive(receiveBuffer); 11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 111028f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return 0; 11110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1114fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int send(int nativeHandle, byte[] data) throws RemoteException { 1116d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 11190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1127f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = socket.doSend(data); 11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 11320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1143f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpServiceSocket findSocket(int nativeHandle) { 1144bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1145bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpServiceSocket)) { 1146f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1147f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1148bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpServiceSocket) socket; 1149f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1150f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1151fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int accept(int nativeHandle) throws RemoteException { 1153d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket clientSocket = null; 11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1164f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 116693915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly clientSocket = socket.doAccept(socket.getMiu(), 11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly socket.getRw(), socket.getLinearBufferLength()); 11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (clientSocket != null) { 11690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Add the socket into the socket map */ 11702f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 11711878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 11721878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, clientSocket); 11731878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 11742f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 11750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1183fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void close(int nativeHandle) throws RemoteException { 1185d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return; 11920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1195f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 11971878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 1198f63da5f0887eba86d877faaee41dc5dfb8fccd50Jeff Hamilton synchronized (this) { 11990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Remove the socket closed from the hmap */ 12000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly RemoveSocket(nativeHandle); 12010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 12020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 12030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1204f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 1207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1208f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpConnectionlessSocket findSocket(int nativeHandle) { 1209bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1210bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpConnectionlessSocket)) { 1211f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1212f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1213bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpConnectionlessSocket) socket; 1214f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1215f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1216fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public void close(int nativeHandle) throws RemoteException { 1218d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1219bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1220f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1221f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1223f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1224f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return; 1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1228f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 12301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 12311878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 12321878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 1233f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1235f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1236fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1237f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getSap(int nativeHandle) throws RemoteException { 1238d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1239bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1241f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1243f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1244f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1248f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return socket.getSap(); 1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return 0; 1253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1256fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1258d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1259bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1261f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LlcpPacket packet; 1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1269f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly packet = socket.doReceiveFrom(socket.getLinkMiu()); 1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (packet != null) { 1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return packet; 1274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1281fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1283d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1284bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1288f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1289f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1294f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 1298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1299f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final INfcTag mNfcTagService = new INfcTag.Stub() { 1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1310fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int close(int nativeHandle) throws RemoteException { 1312d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1313bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1315f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1317f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1318f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1324b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* Remove the device from the hmap */ 1325b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 132621545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly tag.disconnect(); 1327b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.SUCCESS; 1328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1329f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 133065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly maybeEnableDiscovery(); 1331f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_DISCONNECT; 1332f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1334fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1335ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen public int connect(int nativeHandle, int technology) throws RemoteException { 1336d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1337bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1340f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1347b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1348b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.ERROR_DISCONNECT; 1349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1350ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen 1351ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // Note that on most tags, all technologies are behind a single 1352ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // handle. This means that the connect at the lower levels 1353ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // will do nothing, as the tag is already connected to that handle. 1354ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen if (tag.connect(technology)) { 1355ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.SUCCESS; 1356ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } else { 1357ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1358ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } 1359f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1360f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1361fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1362aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen public int reconnect(int nativeHandle) throws RemoteException { 1363aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1364aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1365aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen NativeNfcTag tag = null; 1366aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1367aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // Check if NFC is enabled 1368aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (!mIsNfcEnabled) { 1369aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 1370aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1371aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1372aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen /* find the tag in the hmap */ 1373aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 1374aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag != null) { 1375aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag.reconnect()) { 1376aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.SUCCESS; 1377aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } else { 1378aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1379aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1380aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1381aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1382aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1383aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1384aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen @Override 1385b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton public int[] getTechList(int nativeHandle) throws RemoteException { 1386d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1387bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1388f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1389f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1390f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1391f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1392f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1393f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1394b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle); 1395f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1396b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton return tag.getTechList(); 1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1401fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public byte[] getUid(int nativeHandle) throws RemoteException { 1403f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] uid; 1405f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1407f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1410f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly uid = tag.getUid(); 1415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return uid; 1416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1420fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1421b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public boolean isPresent(int nativeHandle) throws RemoteException { 1422b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau NativeNfcTag tag = null; 1423b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1424b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau // Check if NFC is enabled 1425b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (!mIsNfcEnabled) { 1426b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1427b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1428b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1429b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* find the tag in the hmap */ 1430b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau tag = (NativeNfcTag) findObject(nativeHandle); 1431b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1432b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1433b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1434b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1435b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return tag.presenceCheck(); 1436b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1437b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1438fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1439f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public boolean isNdef(int nativeHandle) throws RemoteException { 1440f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1441f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1442f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1443f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1444f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1445f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1446f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1447f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 14503ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen int[] ndefInfo = new int[2]; 1451f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14523ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen isSuccess = tag.checkNdef(ndefInfo); 1453f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1455f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1456f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1457fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14589d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 145997c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1460d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1461bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1463f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] response; 1464f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1466f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1467f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1468f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1469f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1470f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14739d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen int[] targetLost = new int[1]; 14749d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response = tag.transceive(data, raw, targetLost); 14759d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen TransceiveResult transResult = new TransceiveResult( 14769d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (response != null) ? true : false, 14779d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (targetLost[0] == 1) ? true : false, 14789d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response); 14799d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen return transResult; 1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1482f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1483f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1484fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14853fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1486d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1487bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1488f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1493f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1494f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1495f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1496f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1498b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau byte[] buf = tag.read(); 1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (buf == null) 1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Create an NdefMessage */ 1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly try { 1504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return new NdefMessage(buf); 1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } catch (FormatException e) { 1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1507f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1512fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15133fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1514d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1515bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1521f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1522f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1523f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1524f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag == null) { 1526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1529b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag.write(msg.toByteArray())) { 1530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1531f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1532f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly else { 1533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1534f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1535f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1536f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1537f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1538fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1539f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getLastError(int nativeHandle) throws RemoteException { 1540bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return(mManager.doGetLastError()); 1541f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1543fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 15453fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton throw new UnsupportedOperationException(); 1546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1547f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1548fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15493fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 155003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 155103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 155203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen NativeNfcTag tag; 155303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 155403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen // Check if NFC is enabled 155503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (!mIsNfcEnabled) { 155603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 155703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 155803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 155903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* find the tag in the hmap */ 156003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 156103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag == null) { 156203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 156303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 156403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 156503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag.makeReadonly()) { 156603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.SUCCESS; 156703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 156803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen else { 156903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 157003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 1571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15730aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen @Override 15740aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 15750aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 15760aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15770aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen NativeNfcTag tag; 15780aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15790aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen // Check if NFC is enabled 15800aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (!mIsNfcEnabled) { 15810aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 15820aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15830aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15840aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* find the tag in the hmap */ 15850aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 15860aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag == null) { 15870aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 15880aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15890aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15900aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag.formatNdef(key)) { 15910aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.SUCCESS; 15920aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15930aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen else { 15940aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 15950aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15960aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15970aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15981b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 15991b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void setIsoDepTimeout(int timeout) throws RemoteException { 16001b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 16011b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 16021b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.setIsoDepTimeout(timeout); 16031b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 1604f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16051b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 16061b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void resetIsoDepTimeout() throws RemoteException { 16071b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 16081b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 16091b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.resetIsoDepTimeout(); 16101b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 16110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1612f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1614f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1615fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1617d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1618f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1620f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 16300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 16310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 16330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1636f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1637fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1639d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1640f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1642f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 16460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1647f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 16520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1653f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 1654f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1655f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1656fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] receive(int nativeHandle) throws RemoteException { 1658d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1659f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1661f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1666f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doReceive(); 16710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 167665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly maybeEnableDiscovery(); 16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1679f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1680fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1682d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1683f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 16850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1686f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 16900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1691f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = device.doSend(data); 16960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 16980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1700f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1702f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1703fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle) throws RemoteException { 1705d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1706f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1708f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1713f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device.doConnect()) { 17180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 17190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_CONNECT; 17220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1723f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1724fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disconnect(int nativeHandle) throws RemoteException { 1726d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1727f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1730f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 17340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1735f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess = device.doDisconnect()) { 17400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* remove the device from the hmap */ 1741b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 174365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly maybeEnableDiscovery(); 17440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1745f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 17460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1747f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1749f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1750fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1752d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1753f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 17560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1759f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1760f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 17650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 17660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 17680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1771f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1772fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1774d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1775f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1777f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1781f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1782f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 17870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 17890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1790f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1791fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 179297c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen public byte[] transceive(int nativeHandle, byte[] data) 179397c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1794d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1795f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1797f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 18000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1801f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1802f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 18040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 18050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 18060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doTransceive(data); 18070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 18080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 18100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1814f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private INfcSecureElement mSecureElementService = new INfcSecureElement.Stub() { 18160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public int openSecureElementConnection() throws RemoteException { 18180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas Log.d(TAG, "openSecureElementConnection"); 18190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int handle; 18200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if NFC is enabled 18220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!mIsNfcEnabled) { 18230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return 0; 18240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check in an open is already pending 18270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (mOpenSmxPending) { 18280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return 0; 18290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas handle = mSecureElement.doOpenSecureElementConnection(); 18320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (handle == 0) { 18340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mOpenSmxPending = false; 18350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } else { 18360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElementHandle = handle; 18370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Start timer */ 18390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx = new Timer(); 18400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 18410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Update state */ 18430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isOpened = true; 18440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isClosed = false; 18450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mOpenSmxPending = true; 18460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return handle; 18490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public int closeSecureElementConnection(int nativeHandle) 18520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas throws RemoteException { 18530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if NFC is enabled 18550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!mIsNfcEnabled) { 18560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return ErrorCodes.ERROR_NOT_INITIALIZED; 18570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is closed 18600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (isClosed) { 18610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return -1; 18620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is opened 18650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!isOpened) { 18660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return -1; 18670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (mSecureElement.doDisconnect(nativeHandle)) { 18700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Stop timer */ 18720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.cancel(); 18730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Restart polling loop for notification */ 18750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mManager.enableDiscovery(DISCOVERY_MODE_READER); 18760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Update state */ 18780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isOpened = false; 18790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isClosed = true; 18800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mOpenSmxPending = false; 18810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return ErrorCodes.SUCCESS; 18830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } else { 18840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Stop timer */ 18860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.cancel(); 18870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Restart polling loop for notification */ 18890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mManager.enableDiscovery(DISCOVERY_MODE_READER); 18900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Update state */ 18920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isOpened = false; 18930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas isClosed = true; 18940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mOpenSmxPending = false; 18950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 18960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return ErrorCodes.ERROR_DISCONNECT; 18970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 18990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public int[] getSecureElementTechList(int nativeHandle) 19010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas throws RemoteException { 19020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if NFC is enabled 19030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!mIsNfcEnabled) { 19040bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is closed 19080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (isClosed) { 19090bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19100bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19110bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is opened 19130bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!isOpened) { 19140bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19150bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19160bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19170bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas int[] techList = mSecureElement.doGetTechList(nativeHandle); 19180bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Stop and Restart timer */ 19200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.cancel(); 19210bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx = new Timer(); 19220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 19230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return techList; 19250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public byte[] getSecureElementUid(int nativeHandle) 19280bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas throws RemoteException { 19290bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas byte[] uid; 19300bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19310bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if NFC is enabled 19320bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!mIsNfcEnabled) { 19330bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19340bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is closed 19370bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (isClosed) { 19380bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19390bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19400bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19410bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is opened 19420bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!isOpened) { 19430bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas uid = mSecureElement.doGetUid(nativeHandle); 19470bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19480bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Stop and Restart timer */ 19490bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.cancel(); 19500bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx = new Timer(); 19510bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 19520bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19530bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return uid; 19540bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19550bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public byte[] exchangeAPDU(int nativeHandle, byte[] data) 19570bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas throws RemoteException { 19580bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas byte[] response; 19590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19600bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if NFC is enabled 19610bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!mIsNfcEnabled) { 19620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19630bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19640bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19650bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is closed 19660bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (isClosed) { 19670bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19680bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19690bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas // Check if the SE connection is opened 19710bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (!isOpened) { 19720bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return null; 19730bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas response = mSecureElement.doTransceive(nativeHandle, data); 19760bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas /* Stop and Restart timer */ 19780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.cancel(); 19790bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx = new Timer(); 19800bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mTimerOpenSmx.schedule(new TimerOpenSecureElement(), 30000); 19810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas return response; 19830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19850bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas }; 19860bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19870bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas class TimerOpenSecureElement extends TimerTask { 19880bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 19890bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas @Override 19900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas public void run() { 19910bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas if (mSecureElementHandle != 0) { 19920bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas Log.d(TAG, "Open SMX timer expired"); 19930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas try { 19940bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElementService 19950bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas .closeSecureElementConnection(mSecureElementHandle); 19960bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } catch (RemoteException e) { 19970bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19980bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19990bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 20000bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 20010bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 20020bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 20030bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 20040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private boolean _enable(boolean oldEnabledState) { 20056efda9f3970382554437be037aed863be9889499Sylvain Fonteneau applyProperties(); 20066efda9f3970382554437be037aed863be9889499Sylvain Fonteneau 20070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = mManager.initialize(); 20080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 20090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check Secure Element setting */ 20100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mNfcSecureElementState = mPrefs.getBoolean(PREF_SECURE_ELEMENT_ON, 20110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly SECURE_ELEMENT_ON_DEFAULT); 2012f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (mNfcSecureElementState) { 20140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int secureElementId = mPrefs.getInt(PREF_SECURE_ELEMENT_ID, 20150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly SECURE_ELEMENT_ID_DEFAULT); 20160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int[] Se_list = mManager.doGetSecureElementList(); 20170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (Se_list != null) { 20180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly for (int i = 0; i < Se_list.length; i++) { 20190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (Se_list[i] == secureElementId) { 20200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSelectSecureElement(Se_list[i]); 20210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mSelectedSeId = Se_list[i]; 20220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly break; 20230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 20240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 20250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2026f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2027f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 202865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mIsNfcEnabled = true; 202965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 20300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Start polling loop */ 203165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly maybeEnableDiscovery(); 203257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 203357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton /* bring up the my tag server */ 2034ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.start(); 203557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2036f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 20370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 2038f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(oldEnabledState); 2041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 2043f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2044f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 204565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly /** Enable active tag discovery if screen is on and NFC is enabled */ 204665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly private synchronized void maybeEnableDiscovery() { 204765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly if (mScreenOn && mIsNfcEnabled) { 204865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mManager.enableDiscovery(DISCOVERY_MODE_READER); 204965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 205065945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 205165945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 205265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly /** Disable active tag discovery if necessary */ 205365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly private synchronized void maybeDisableDiscovery() { 205465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly if (mIsNfcEnabled) { 205565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mManager.disableDiscovery(); 205665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 205765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 205865945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 20592436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir /** Disconnect any target if present */ 20602436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir private synchronized void maybeDisconnectTarget() { 20612436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir if (mIsNfcEnabled) { 20622436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Iterator<?> iterator = mObjectMap.values().iterator(); 20632436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir while(iterator.hasNext()) { 20642436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Object object = iterator.next(); 2065663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if(object instanceof NativeNfcTag) { 2066663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from tags 20672436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir NativeNfcTag tag = (NativeNfcTag) object; 20682436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir tag.disconnect(); 20692436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 2070663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else if(object instanceof NativeP2pDevice) { 2071663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from P2P devices 2072663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau NativeP2pDevice device = (NativeP2pDevice) object; 2073663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2074663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is target, request disconnection 2075663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2076663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2077663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else { 2078663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is initiator, we cannot disconnect 2079663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Just wait for field removal 2080663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2081663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2082663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau iterator.remove(); 20832436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20842436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20852436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 20862436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir 2087f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly private void applyProperties() { 2088f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 2089f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 2090f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 2091f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 2092f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, 2093f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0); 2094f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, 2095f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0); 2096f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, 2097f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0); 2098f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, 2099f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0); 2100f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, 2101f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0); 2102f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly } 2103f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly 21040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void updateNfcOnSetting(boolean oldEnabledState) { 21050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 21062f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 21070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 21082f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 21094acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly if (oldEnabledState != mIsNfcEnabled) { 21102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 21114acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 21122f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 21132f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly mContext.sendBroadcast(intent); 21142f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 211557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 211657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 211757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 211857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = getApplicationContext(); 211957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 212057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Set this to null by default. If there isn't a tag on disk 212157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // or if there was an error reading the tag then this will cause 212257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // the status bar icon to be removed. 212357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton NdefMessage myTag = null; 212457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 212557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileInputStream input = null; 212657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 212757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 212857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input = context.openFileInput(MY_TAG_FILE_NAME); 212957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 213057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 213157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] buffer = new byte[4096]; 213257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton int read = 0; 213357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton while ((read = input.read(buffer)) > 0) { 213457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton bytes.write(buffer, 0, read); 213557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 213657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 213757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton myTag = new NdefMessage(bytes.toByteArray()); 213857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FileNotFoundException e) { 213957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore. 214057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 214157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not read mytag file: ", e); 214257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 214357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FormatException e) { 214457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Invalid NdefMessage for mytag", e); 214557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 214657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 214757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 214857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (input != null) { 214957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input.close(); 215057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 215157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 215257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 215357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 215457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 215557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 215657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 215757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mNfcAdapter.localSet(myTag); 215857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (RemoteException e) { 215957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 216057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 216157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 216257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 216357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 21640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2165f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2166f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2167f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset all internals 21682f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized void reset() { 216974180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 217074180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 2171f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Clear tables 2173f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mObjectMap.clear(); 2174f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.clear(); 2175f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2176f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset variables 2177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mIsNfcEnabled = false; 2178f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSelectedSeId = 0; 2179f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2180f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 21812f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findObject(int key) { 2182f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Object device = null; 2183f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly device = mObjectMap.get(key); 2185f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (device == null) { 2186f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Log.w(TAG, "Handle not found !"); 2187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2188f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2189f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return device; 2190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2191f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 21922f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void registerTagObject(NativeNfcTag nativeTag) { 2193b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.put(nativeTag.getHandle(), nativeTag); 2194b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2195b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 21962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void unregisterObject(int handle) { 2197b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.remove(handle); 2198f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22002f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findSocket(int key) { 2201bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (mSocketMap == null) { 2202bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return null; 2203bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly } 2204bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return mSocketMap.get(key); 2205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2206f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private void RemoveSocket(int key) { 2208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.remove(key); 2209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2211d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2212d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 2213d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2214d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 22151be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 22161be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 22171be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 22181be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2219d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpSocket(mLlcpSocket, handle); 2220d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2221d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2222d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2223d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2224d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2225d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2226d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2227d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 2228d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int linearBufferLength) { 2229d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2230d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 22311be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 22321be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 22331be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 22341be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2235d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 2236d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2237d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2238d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2239d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2240d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2241d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 22420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void activateLlcpLink() { 22430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Broadcast Intent Link LLCP activated */ 22440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Intent LlcpLinkIntent = new Intent(); 22450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 22480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NfcAdapter.LLCP_LINK_STATE_ACTIVATED); 2249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2250ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP activation"); 22510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 22520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2253f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 225457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton public void sendMockNdefTag(NdefMessage msg) { 2255b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton sendMessage(MSG_MOCK_NDEF, msg); 225657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 225757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2258b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau void sendMessage(int what, Object obj) { 2259b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau Message msg = mHandler.obtainMessage(); 2260b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.what = what; 2261b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.obj = obj; 2262b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mHandler.sendMessage(msg); 2263b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2264b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2265b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton final class NfcServiceHandler extends Handler { 2266232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2267232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen public NdefMessage[] findAndReadNdef(NativeNfcTag nativeTag) { 2268232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Try to find NDEF on any of the technologies. 2269232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] technologies = nativeTag.getTechList(); 2270232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] handles = nativeTag.getHandleList(); 2271232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int techIndex = 0; 2272232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int lastHandleScanned = 0; 2273232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen boolean ndefFoundAndConnected = false; 2274232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen NdefMessage[] ndefMsgs = null; 2275eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen boolean foundFormattable = false; 2276e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen int formattableHandle = 0; 2277e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen int formattableTechnology = 0; 2278232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2279232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen while ((!ndefFoundAndConnected) && (techIndex < technologies.length)) { 2280232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (handles[techIndex] != lastHandleScanned) { 2281232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // We haven't seen this handle yet, connect and checkndef 2282232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.connect(technologies[techIndex])) { 2283eb488e0b323ec2d4fe03528e2b9f3a73e66ae17dMartijn Coenen // Check if this type is NDEF formatable 2284434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen if (!foundFormattable) { 2285434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen if (nativeTag.isNdefFormatable()) { 2286434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen foundFormattable = true; 2287434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen formattableHandle = nativeTag.getConnectedHandle(); 2288434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen formattableTechnology = nativeTag.getConnectedTechnology(); 2289434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // We'll only add formattable tech if no ndef is 2290434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // found - this is because libNFC refuses to format 2291434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen // an already NDEF formatted tag. 2292434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen } 2293434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen nativeTag.reconnect(); 2294434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen } // else, already found formattable technology 2295434bb34457422a9cad664b73ed0d425db4a3093dMartijn Coenen 2296232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int[] ndefinfo = new int[2]; 2297232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.checkNdef(ndefinfo)) { 2298232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefFoundAndConnected = true; 2299232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen boolean generateEmptyNdef = false; 2300232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2301232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int supportedNdefLength = ndefinfo[0]; 2302232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen int cardState = ndefinfo[1]; 2303232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen byte[] buff = nativeTag.read(); 2304232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (buff != null) { 2305232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs = new NdefMessage[1]; 2306232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen try { 2307232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs[0] = new NdefMessage(buff); 2308232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.addNdefTechnology(ndefMsgs[0], 2309ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.getConnectedHandle(), 23100a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen nativeTag.getConnectedLibNfcType(), 2311f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen nativeTag.getConnectedTechnology(), 2312232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen supportedNdefLength, cardState); 2313232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.reconnect(); 2314232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } catch (FormatException e) { 2315232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Create an intent anyway, without NDEF messages 2316232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen generateEmptyNdef = true; 2317232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2318232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2319232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen generateEmptyNdef = true; 2320232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2321232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2322232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (generateEmptyNdef) { 2323232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen ndefMsgs = new NdefMessage[] { }; 2324ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.addNdefTechnology(null, 2325ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen nativeTag.getConnectedHandle(), 23260a58617a63e32d2f43e3aabc705fb7b9de464482Martijn Coenen nativeTag.getConnectedLibNfcType(), 2327f34ea55002a5f7fbe8486c6ab6f4a17481a9558fMartijn Coenen nativeTag.getConnectedTechnology(), 2328ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen supportedNdefLength, cardState); 2329232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.reconnect(); 2330232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2331232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } // else, no NDEF on this tech, continue loop 2332232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2333232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // Connect failed, tag maybe lost. Try next handle 2334232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // anyway. 2335232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2336232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2337232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen lastHandleScanned = handles[techIndex]; 2338232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen techIndex++; 2339232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2340e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen if (ndefMsgs == null && foundFormattable) { 2341e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen // Tag is not NDEF yet, and found a formattable target, 2342e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen // so add formattable tech to tech list. 2343e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen nativeTag.addNdefFormatableTechnology( 2344e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen formattableHandle, 2345e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen formattableTechnology); 2346e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen } 2347232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2348232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen return ndefMsgs; 2349232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2350232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2351b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau @Override 2352b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public void handleMessage(Message msg) { 2353f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly switch (msg.what) { 2354b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton case MSG_MOCK_NDEF: { 2355b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NdefMessage ndefMsg = (NdefMessage) msg.obj; 2356b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2357b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new int[] { }, 2358b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new Bundle[] { }); 235957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 236057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, tag.toString()); 23613fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchTag(tag, new NdefMessage[] { ndefMsg }); 236257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 236357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 236457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2365f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_NDEF_TAG: 2366ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2367f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeNfcTag nativeTag = (NativeNfcTag) msg.obj; 2368232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen NdefMessage[] ndefMsgs = findAndReadNdef(nativeTag); 2369232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2370232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (ndefMsgs != null) { 237198eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 2372232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen dispatchNativeTag(nativeTag, ndefMsgs); 2373232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2374232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // No ndef found or connect failed, just try to reconnect and dispatch 2375232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.reconnect()) { 237698eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 23773fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchNativeTag(nativeTag, null); 2378232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2379232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen Log.w(TAG, "Failed to connect to tag"); 2380232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.disconnect(); 2381f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2382f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2383f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 23843fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 2385f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_CARD_EMULATION: 2386ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Card Emulation message"); 2387f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly byte[] aid = (byte[]) msg.obj; 2388f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Send broadcast ordered */ 2389f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent TransactionIntent = new Intent(); 2390f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED); 2391f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid); 2392ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting Card Emulation event"); 2393f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(TransactionIntent, NFC_PERM); 2394f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2395f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2396f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_ACTIVATION: 2397f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeP2pDevice device = (NativeP2pDevice) msg.obj; 2398f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2399f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.d(TAG, "LLCP Activation message"); 2400f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2401f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2402ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2403f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.doConnect()) { 2404f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2405f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2406f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2407f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2408ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2409663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2410663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2411eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2412eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 2413eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton /* should not happen */ 2414eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect."); 2415eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device.doDisconnect(); 2416b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2417b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2418f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else { 2419ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2420f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly device.doDisconnect(); 2421b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2422eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 24237f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted..."); 24247f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir /* The polling loop should have been restarted in failing doConnect */ 2425f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2426f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2427f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) { 2428ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2429f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2430f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2431f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2432f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2433ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2434663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2435663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2436eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2437eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } 24386f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton } else { 2439ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton Log.w(TAG, "checkLlcp failed"); 2440f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2441b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2442f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2443f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2444f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_DEACTIVATED: 2445eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device = (NativeP2pDevice) msg.obj; 2446eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2447eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2448663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau synchronized (NfcService.this) { 2449663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Check if the device has been already unregistered */ 2450663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (mObjectMap.remove(device.getHandle()) != null) { 2451663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Disconnect if we are initiator */ 2452663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2453663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "disconnecting from target"); 2454663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Restart polling loop */ 2455663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2456663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } else { 2457663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2458663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2459663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2460cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton } 2461eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2462f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Link LLCP activated */ 2463f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent LlcpLinkIntent = new Intent(); 2464f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2465f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2466f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); 2467ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP deactivation"); 2468f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2469f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2470f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2471f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_TARGET_DESELECTED: 2472f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Target Deselected */ 2473ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Deselected"); 2474f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent TargetDeselectedIntent = new Intent(); 2475f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION); 2476ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting Intent"); 2477f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM); 2478f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2479f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 248057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_SHOW_MY_TAG_ICON: { 248157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 248257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 248357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0); 248457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 248557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 248657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 248757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_HIDE_MY_TAG_ICON: { 248857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 248957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 249057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.removeIcon("nfc"); 249157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 249257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 249357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2494c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_ACTIVATED:{ 2495c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2496c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOnIntent = new Intent(); 2497c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas eventFieldOnIntent.setAction(NfcAdapter.ACTION_RF_FIELD_ON_DETECTED); 2498c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 2499c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas mContext.sendBroadcast(eventFieldOnIntent, NFC_PERM); 2500c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2501c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2502c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2503c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_DEACTIVATED:{ 2504c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2505c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOffIntent = new Intent(); 2506c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas eventFieldOffIntent.setAction(NfcAdapter.ACTION_RF_FIELD_OFF_DETECTED); 2507c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 2508c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas mContext.sendBroadcast(eventFieldOffIntent, NFC_PERM); 2509c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2510c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2511c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2512f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly default: 2513f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.e(TAG, "Unknown message received"); 2514f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2515f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2516b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2517d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 25183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Intent buildTagIntent(Tag tag, NdefMessage[] msgs, String action) { 25193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent = new Intent(action); 2520b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2521b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2522b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, msgs); 2523b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2524d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return intent; 2525d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 25263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private void dispatchNativeTag(NativeNfcTag nativeTag, NdefMessage[] msgs) { 25283fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Tag tag = new Tag(nativeTag.getUid(), nativeTag.getTechList(), 25290c322dc2d942285bfcd9fe5c0bba1a5f36a967f5Jeff Hamilton nativeTag.getTechExtras(), nativeTag.getHandle(), mNfcTagService); 25303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (dispatchTag(tag, msgs)) { 25313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton registerTagObject(nativeTag); 25323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } else { 25333fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton nativeTag.disconnect(); 25343fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25363fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25373fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public byte[] concat(byte[]... arrays) { 25383fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int length = 0; 25393fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 25403fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton length += array.length; 25413fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25423fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] result = new byte[length]; 25433fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int pos = 0; 25443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 25453fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton System.arraycopy(array, 0, result, pos, array.length); 25463fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton pos += array.length; 25473fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25483fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return result; 25493fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25503fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25513fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Uri parseWellKnownUriRecord(NdefRecord record) { 25523fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] payload = record.getPayload(); 25533fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25543fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /* 25553fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[0] contains the URI Identifier Code, per the 25563fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" section 3.2.2. 25573fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 25583fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[1]...payload[payload.length - 1] contains the rest of 25593fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * the URI. 25603fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 25613fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton String prefix = URI_PREFIX_MAP[(payload[0] & 0xff)]; 25623fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] fullUri = concat(prefix.getBytes(Charsets.UTF_8), 25633fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Arrays.copyOfRange(payload, 1, payload.length)); 25643fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return Uri.parse(new String(fullUri, Charsets.UTF_8)); 25653fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 25663fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 25673fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean setTypeOrDataFromNdef(Intent intent, NdefRecord record) { 25683fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton short tnf = record.getTnf(); 25693fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] type = record.getType(); 2570adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2571adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton switch (tnf) { 2572adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_MIME_MEDIA: { 2573adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType(new String(type, Charsets.US_ASCII)); 25743fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 2575adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 2576adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_ABSOLUTE_URI: { 2577adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(Uri.parse(new String(record.getPayload(), Charsets.UTF_8))); 2578adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2579adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 2580adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_WELL_KNOWN: { 2581adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton byte[] payload = record.getPayload(); 2582adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (payload == null || payload.length == 0) return false; 2583adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (Arrays.equals(type, NdefRecord.RTD_TEXT)) { 2584adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType("text/plain"); 2585adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2586adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_SMART_POSTER)) { 2587adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // Parse the smart poster looking for the URI 2588adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2589adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefMessage msg = new NdefMessage(record.getPayload()); 2590adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton for (NdefRecord subRecord : msg.getRecords()) { 2591adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton short subTnf = subRecord.getTnf(); 2592adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (subTnf == NdefRecord.TNF_WELL_KNOWN 2593adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton && Arrays.equals(subRecord.getType(), 2594adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefRecord.RTD_URI)) { 2595adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(subRecord)); 2596adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2597adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (subTnf == NdefRecord.TNF_ABSOLUTE_URI) { 2598adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(Uri.parse(new String(subRecord.getPayload(), 2599adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Charsets.UTF_8))); 2600adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2601adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 26023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2603adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (FormatException e) { 2604adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26053fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2606adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_URI)) { 2607adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(record)); 2608adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 26093fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2610adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26113fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26123fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2613adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 2614adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (Exception e) { 2615adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Log.e(TAG, "failed to parse record", e); 2616adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 26173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26203fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** Returns false if no activities were found to dispatch to */ 26213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean dispatchTag(Tag tag, NdefMessage[] msgs) { 26223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (DBG) { 26233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, "Dispatching tag"); 26243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, tag.toString()); 26253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 262705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton IntentFilter[] overrideFilters; 262805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent overrideIntent; 262924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists; 2630a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean foregroundNdefPush = mNdefPushClient.getForegroundMessage() != null; 263105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 263205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideFilters = mDispatchOverrideFilters; 263305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideIntent = mDispatchOverrideIntent; 263424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists = mDispatchOverrideTechLists; 263505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 263605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 263705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // First look for dispatch overrides 2638a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (overrideIntent != null) { 263905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Attempting to dispatch tag with override"); 264005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton try { 264124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (dispatchTagInternal(tag, msgs, overrideIntent, overrideFilters, 264224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 264305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Dispatched to override"); 264405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 264505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 264605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch override registered, but no filters matched"); 264705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (CanceledException e) { 264805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch overrides pending intent was canceled"); 264905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 265005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 265105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 265224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = null; 265305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 265405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 265505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 265605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 2657a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // If there is not foreground NDEF push setup try a normal dispatch. 2658a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // 2659a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // This is avoided when disabled in the NDEF push case to avoid the situation where each 2660a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // user has a different app in the foreground, causing each to launch itself on the 2661a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // remote device and the apps swapping which is in the foreground on each phone. 2662a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (!foregroundNdefPush) { 2663a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton try { 266424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return dispatchTagInternal(tag, msgs, null, null, null); 2665a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } catch (CanceledException e) { 2666a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.e(TAG, "CanceledException unexpected here", e); 2667a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2668a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 266905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2670a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2671a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 267205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 267305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 267424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton /** Returns true if the tech list filter matches the techs on the tag */ 267524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton private boolean filterMatch(String[] tagTechs, String[] filterTechs) { 267624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterTechs == null || filterTechs.length == 0) return false; 267724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 267824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String tech : filterTechs) { 267924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (Arrays.binarySearch(tagTechs, tech) < 0) { 268024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return false; 268124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 268224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 268324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 268424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 268524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 268605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Dispatch to either an override pending intent or a standard startActivity() 268705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean dispatchTagInternal(Tag tag, NdefMessage[] msgs, 268824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton PendingIntent overrideIntent, IntentFilter[] overrideFilters, 268924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists) 269005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton throws CanceledException{ 26913fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent; 269224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 269324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 269424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Try the NDEF content specific dispatch 269524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 26963fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (msgs != null && msgs.length > 0) { 26973fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefMessage msg = msgs[0]; 26983fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord[] records = msg.getRecords(); 26993fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (records.length > 0) { 27003fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Found valid NDEF data, try to dispatch that first 27013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord record = records[0]; 27023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 27033fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_NDEF_DISCOVERED); 2704adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (setTypeOrDataFromNdef(intent, record)) { 2705adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // The record contains filterable data, try to start a matching activity 270624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, 270724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 2708adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // If an activity is found then skip further dispatching 2709adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2710adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else { 2711adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (DBG) Log.d(TAG, "No activities for NDEF handling of " + intent); 2712adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 27133fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27143fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27163fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 271724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 27183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the technology specific dispatch 271924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 272024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[] tagTechs = tag.getTechList(); 272124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Arrays.sort(tagTechs); 272224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 272324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideIntent != null) { 272424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // There are dispatch overrides in place 272524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideTechLists != null) { 272624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String[] filterTechs : overrideTechLists) { 272724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterMatch(tagTechs, filterTechs)) { 272824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // An override matched, send it to the foreground activity. 272924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = buildTagIntent(tag, msgs, 273024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED); 273124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 273224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 273324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 273424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 273524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 273605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 273724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Standard tech dispatch path 273824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>(); 273924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ComponentInfo> registered = mTechListFilters.getComponents(); 274024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 274124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Check each registered activity to see if it matches 274224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (ComponentInfo info : registered) { 274324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Don't allow wild card matching 274424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterMatch(tagTechs, info.techs)) { 274524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton matches.add(info.resolveInfo); 274624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 274724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 274824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 274924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (matches.size() == 1) { 275024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Single match, launch directly 275124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED); 275224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ResolveInfo info = matches.get(0); 275324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.setClassName(info.activityInfo.packageName, info.activityInfo.name); 275424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 275524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 275624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 275724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 275824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 275924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 276024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (matches.size() > 1) { 276124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Multiple matches, show a custom activity chooser dialog 276224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = new Intent(mContext, TechListChooserActivity.class); 276324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 276424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putExtra(Intent.EXTRA_INTENT, 276524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECHNOLOGY_DISCOVERED)); 276624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putParcelableArrayListExtra(TechListChooserActivity.EXTRA_RESOLVE_INFOS, 276724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton matches); 276824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 276924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 277024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 277124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 277224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 277324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 277424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else { 277524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // No matches, move on 277624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 277724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 27783fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27793fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 278024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 27813fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the generic intent 278224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 27833fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TAG_DISCOVERED); 278424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, overrideTechLists)) { 27853fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 278605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 27873fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.e(TAG, "No tag fallback activity found for " + intent); 27883fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return false; 27893fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27903fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 279105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 279205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean startDispatchActivity(Intent intent, PendingIntent overrideIntent, 279324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] overrideFilters, String[][] overrideTechLists) 279424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throws CanceledException { 279505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (overrideIntent != null) { 2796a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean found = false; 279724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideFilters == null && overrideTechLists == null) { 2798a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // No filters means to always dispatch regardless of match 2799a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 280024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (overrideFilters != null) { 2801a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : overrideFilters) { 2802a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter.match(mContext.getContentResolver(), intent, false, TAG) >= 0) { 2803a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 2804a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton break; 2805a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 280605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 280705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2808a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2809a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (found) { 2810a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.i(TAG, "Dispatching to override intent " + overrideIntent); 2811a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 2812a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return true; 2813a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 2814a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2815a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 281605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 281705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton try { 28181a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // If the current app called stopAppSwitches() then our startActivity() 28191a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // can be delayed for several seconds. This happens with the default home 28201a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // screen. As a system service we can override this behavior with 28211a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // resumeAppSwitches() 28221a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager.resumeAppSwitches(); 28231a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly } catch (RemoteException e) { } 28241a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly try { 282505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.startActivity(intent); 282605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 282705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (ActivityNotFoundException e) { 282805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return false; 282905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 283005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 283105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2832b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton } 2833b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2834b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton private NfcServiceHandler mHandler = new NfcServiceHandler(); 2835b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton 28367c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2837fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 28387c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly protected Void doInBackground(Boolean... enable) { 2839df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly if (enable != null && enable.length > 0 && enable[0]) { 2840161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2841161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly mScreenOn = true; 2842161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly maybeEnableDiscovery(); 2843161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 28447c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } else { 2845533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.acquire(); 2846161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2847161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly mScreenOn = false; 2848161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly maybeDisableDiscovery(); 28492436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir maybeDisconnectTarget(); 2850161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 2851533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.release(); 28527c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28537c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly return null; 28547c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28557c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 28567c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly 28570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 28580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 28590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onReceive(Context context, Intent intent) { 2860eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton if (intent.getAction().equals( 2861f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2862ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 28630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 2864f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 286565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly maybeEnableDiscovery(); 2866f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 286765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 28687c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery enable in thread to protect against ANR when the 28697c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 28707c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 28717c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2872df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly new EnableDisableDiscoveryTask().execute(new Boolean(true)); 287365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 28747c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery disable in thread to protect against ANR when the 28757c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 28767c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 28777c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2878df4e65b5dacb313e7d68bad797a843a175febbedNick Pelly new EnableDisableDiscoveryTask().execute(new Boolean(false)); 2879f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2880f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2881f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 288274180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick} 2883