NfcService.java revision 3fb14d0868594c78a777e805545209636814e223
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; 248afd14d3b23d3124c48ee275ba2845aede6542a1Jeff Hamiltonimport com.android.nfc3.R; 25d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.Activity; 271a9eca5f84036d7dd3e28000290caa2f641856deNick Pellyimport android.app.ActivityManagerNative; 282f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellyimport android.app.Application; 2924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.app.IActivityManager; 30275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parksimport android.app.KeyguardManager; 3105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.app.PendingIntent; 3293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamiltonimport android.app.PendingIntent.CanceledException; 33bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport android.app.StatusBarManager; 34b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.content.ActivityNotFoundException; 3513d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.BroadcastReceiver; 3605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamiltonimport android.content.ComponentName; 3713d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Context; 3813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.Intent; 3913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.content.IntentFilter; 400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.content.SharedPreferences; 4193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamiltonimport android.content.pm.PackageManager; 4224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.content.pm.ResolveInfo; 43160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenenimport android.content.pm.PackageManager; 443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.net.Uri; 45bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport android.nfc.ApduList; 46f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ErrorCodes; 47f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.FormatException; 48f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpConnectionlessSocket; 49f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpServiceSocket; 50f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.ILlcpSocket; 512094515fca0cfa0ac87e9cc260d3953d416afe3eJason parksimport android.nfc.INdefPushCallback; 520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.INfcAdapter; 5349d53329a0c720a7e430220d77805bc1763545b1Nick Pellyimport android.nfc.INfcAdapterExtras; 54f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.INfcTag; 55f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pInitiator; 56f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.IP2pTarget; 57f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.LlcpPacket; 58f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NdefMessage; 593fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport android.nfc.NdefRecord; 60f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.nfc.NfcAdapter; 610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pellyimport android.nfc.Tag; 623fb14d0868594c78a777e805545209636814e223Martijn Coenenimport android.nfc.tech.TagTechnology; 6324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport android.nfc.TechListParcel; 649d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenenimport android.nfc.TransceiveResult; 651b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenenimport android.nfc.tech.TagTechnology; 667c034a7fe7d36b1ab039af2c44717812ea02657eNick Pellyimport android.os.AsyncTask; 67b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamiltonimport android.os.Bundle; 68b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Handler; 6949d53329a0c720a7e430220d77805bc1763545b1Nick Pellyimport android.os.IBinder; 70b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneauimport android.os.Message; 71533043d1003de2f6a20a29201100d94c3c7bc9caNick Pellyimport android.os.PowerManager; 72f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.os.RemoteException; 7313d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pellyimport android.os.ServiceManager; 74f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pellyimport android.util.Log; 75f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 7657d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.ByteArrayOutputStream; 77bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.io.DataInputStream; 78bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.io.DataOutputStream; 7957d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileInputStream; 8057d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileNotFoundException; 8157d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.FileOutputStream; 8257d376f1ee1a3939977b95759525585abb9601fbJeff Hamiltonimport java.io.IOException; 833fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.nio.charset.Charsets; 8424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamiltonimport java.util.ArrayList; 853fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamiltonimport java.util.Arrays; 863ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamiltonimport java.util.HashMap; 872436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Feririmport java.util.Iterator; 88bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parksimport java.util.List; 893ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton 902f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pellypublic class NfcService extends Application { 91bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks private static final String ACTION_MASTER_CLEAR_NOTIFICATION = "android.intent.action.MASTER_CLEAR_NOTIFICATION"; 92bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 93ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton static final boolean DBG = false; 94fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 9557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton private static final String MY_TAG_FILE_NAME = "mytag"; 96a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String SE_RESET_SCRIPT_FILE_NAME = "/system/etc/se-reset-script"; 9757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 9813d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly static { 9913d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly System.loadLibrary("nfc_jni"); 10013d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly } 10113d8819d9d716c8f0ba03288d058f0bd462d70a7Nick Pelly 1023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** 1033fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" 1043fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 1053fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * This is a mapping of "URI Identifier Codes" to URI string prefixes, 1063fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * per section 3.2.2 of the NFC Forum URI Record Type Definition document. 1073fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 1083fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private static final String[] URI_PREFIX_MAP = new String[] { 1093fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "", // 0x00 1103fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://www.", // 0x01 1113fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://www.", // 0x02 1123fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "http://", // 0x03 1133fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "https://", // 0x04 1143fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tel:", // 0x05 1153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "mailto:", // 0x06 1163fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://anonymous:anonymous@", // 0x07 1173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://ftp.", // 0x08 1183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftps://", // 0x09 1193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sftp://", // 0x0A 1203fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "smb://", // 0x0B 1213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "nfs://", // 0x0C 1223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "ftp://", // 0x0D 1233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "dav://", // 0x0E 1243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "news:", // 0x0F 1253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "telnet://", // 0x10 1263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "imap:", // 0x11 1273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "rtsp://", // 0x12 1283fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:", // 0x13 1293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "pop:", // 0x14 1303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sip:", // 0x15 1313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "sips:", // 0x16 1323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tftp:", // 0x17 1333fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btspp://", // 0x18 1343fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btl2cap://", // 0x19 1353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "btgoep://", // 0x1A 1363fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "tcpobex://", // 0x1B 1373fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "irdaobex://", // 0x1C 1383fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "file://", // 0x1D 1393fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:id:", // 0x1E 1403fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:tag:", // 0x1F 1413fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:pat:", // 0x20 1423fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:raw:", // 0x21 1433fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton "urn:epc:", // 0x22 1443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton }; 1453fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 146d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static final String SERVICE_NAME = "nfc"; 147fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks 148f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String TAG = "NfcService"; 149f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 150bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM = android.Manifest.permission.NFC; 151bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String NFC_PERM_ERROR = "NFC permission required"; 152bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM = android.Manifest.permission.WRITE_SECURE_SETTINGS; 153bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly private static final String ADMIN_PERM_ERROR = "WRITE_SECURE_SETTINGS permission required"; 154a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String NFCEE_ADMIN_PERM = "com.android.nfc.permission.NFCEE_ADMIN"; 15593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton private static final String NFCEE_ADMIN_PERM_ERROR = "NFCEE_ADMIN permission required"; 156bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 157225ae2587712b06a354b4ad4625aadc780fa4e80Martijn Coenen /*package*/ static final String PREF = "NfcServicePrefs"; 158f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_NFC_ON = "nfc_on"; 1600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean NFC_ON_DEFAULT = true; 161f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 162a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final String PREF_FIRST_BOOT = "first_boot"; 163a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly 1640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_LTO = "llcp_lto"; 165e1fac398523a97e3bcf513393a91478d79a8763fSylvain Fonteneau private static final int LLCP_LTO_DEFAULT = 150; 1660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_LTO_MAX = 255; 167f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Maximum Information Unit */ 1690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_MIU = "llcp_miu"; 1700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_DEFAULT = 128; 1710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_MIU_MAX = 2176; 172f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** Well Known Service List */ 1740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_WKS = "llcp_wks"; 1750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_DEFAULT = 1; 1760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_WKS_MAX = 15; 177f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_LLCP_OPT = "llcp_opt"; 1790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_DEFAULT = 0; 1800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int LLCP_OPT_MAX = 3; 181f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_A = "discovery_a"; 1830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_A_DEFAULT = true; 184f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_B = "discovery_b"; 1860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_B_DEFAULT = true; 187f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_F = "discovery_f"; 1890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_F_DEFAULT = true; 190f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_15693 = "discovery_15693"; 1920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final boolean DISCOVERY_15693_DEFAULT = true; 193f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final String PREF_DISCOVERY_NFCIP = "discovery_nfcip"; 195a989351c7383aa6b3a6086b10f32c39c1d28fa5dJeff Hamilton private static final boolean DISCOVERY_NFCIP_DEFAULT = true; 196f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /** NFC Reader Discovery mode for enableDiscovery() */ 1980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int DISCOVERY_MODE_READER = 0; 199f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 200f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_LLCP_LTO = 0; 201f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; 2020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_MIU = 1; 203f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; 2040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_WKS = 2; 205f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; 2060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_LLCP_OPT = 3; 207f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; 208f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final int PROPERTY_NFC_DISCOVERY_A = 4; 209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; 2100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_B = 5; 211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; 2120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_F = 6; 213f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; 2140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; 215f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; 2160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; 217f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; 218f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 219b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_NDEF_TAG = 0; 220b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_CARD_EMULATION = 1; 221b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_ACTIVATION = 2; 222b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_LLCP_LINK_DEACTIVATED = 3; 223b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau static final int MSG_TARGET_DESELECTED = 4; 22457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_SHOW_MY_TAG_ICON = 5; 22557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton static final int MSG_HIDE_MY_TAG_ICON = 6; 226b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton static final int MSG_MOCK_NDEF = 7; 227c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_ACTIVATED = 8; 228c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas static final int MSG_SE_FIELD_DEACTIVATED = 9; 229b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 23049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Copied from com.android.nfc_extras to avoid library dependency 23149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Must keep in sync with com.android.nfc_extras 23249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_OFF = 1; 23349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly static final int ROUTE_ON_WHEN_SCREEN_ON = 2; 23449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_ON_DETECTED = 23549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; 23649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_RF_FIELD_OFF_DETECTED = 23749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; 23849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String ACTION_AID_SELECTED = 23949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly "com.android.nfc_extras.action.AID_SELECTED"; 24049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID"; 24149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 24205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Locked on mNfcAdapter 24305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent mDispatchOverrideIntent; 24424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] mDispatchOverrideFilters; 24549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly String[][] mDispatchOverrideTechLists; 24605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 24774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 24874180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private int mGeneratedSocketHandle = 0; 25074180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick private volatile boolean mIsNfcEnabled = false; 25149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private boolean mIsDiscoveryOn = false; 25249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 25349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // NFC Execution Environment 25449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // fields below are protected by this 25549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private static final int SECURE_ELEMENT_ID = 11259375; //TODO: remove hard-coded value 2560bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas private NativeNfcSecureElement mSecureElement; 25749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private OpenSecureElement mOpenEe; // null when EE closed 25849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private int mEeRoutingState; // contactless interface routing 2590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 2602f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are used in multiple threads and protected by synchronized(this) 2612f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); 2622f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>(); 263275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks private boolean mScreenUnlocked; 264a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private String mSePackageName; 2652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 2662f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // fields below are final after onCreate() 26705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Context mContext; 2680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private NativeNfcManager mManager; 2690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences mPrefs; 2700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private SharedPreferences.Editor mPrefsEditor; 271533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly private PowerManager.WakeLock mWakeLock; 2721a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly private IActivityManager mIActivityManager; 273ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushClient mNdefPushClient; 274ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton NdefPushServer mNdefPushServer; 27524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton RegisteredComponentCache mTechListFilters; 276275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks private KeyguardManager mKeyguard; 277d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 278d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton private static NfcService sService; 279d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 28093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceAdminPerm(Context context) { 28193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int admin = context.checkCallingOrSelfPermission(ADMIN_PERM); 28293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton int nfcee = context.checkCallingOrSelfPermission(NFCEE_ADMIN_PERM); 28393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton if (admin != PackageManager.PERMISSION_GRANTED 28493d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton && nfcee != PackageManager.PERMISSION_GRANTED) { 28593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton throw new SecurityException(ADMIN_PERM_ERROR); 28693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 28793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 28893d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 28993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton public static void enforceNfceeAdminPerm(Context context) { 29093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton context.enforceCallingOrSelfPermission(NFCEE_ADMIN_PERM, NFCEE_ADMIN_PERM_ERROR); 29193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton } 29293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton 293d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public static NfcService getInstance() { 294d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return sService; 295d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 297160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen private static boolean isComponentEnabled(PackageManager pm, ResolveInfo info) { 298160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen boolean enabled = false; 299160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen ComponentName compname = new ComponentName( 300160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen info.activityInfo.packageName, info.activityInfo.name); 301160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen try { 302160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen // Note that getActivityInfo() will internally call 303160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen // isEnabledLP() to determine whether the component 304160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen // enabled. If it's not, null is returned. 305160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen if (pm.getActivityInfo(compname,0) != null) { 306160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen enabled = true; 307160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen } 308160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen } catch (PackageManager.NameNotFoundException e) { 309160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen enabled = false; 310160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen } 311160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen if (!enabled) { 312160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen Log.d(TAG, "Component not enabled: " + compname); 313160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen } 314160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen return enabled; 315160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen } 316160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen 3170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onCreate() { 3192f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onCreate(); 3202f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 3212f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Log.i(TAG, "Starting NFC service"); 3222f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly 323d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton sService = this; 324d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 3250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext = this; 326275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mManager = new NativeNfcManager(this, this); 3270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.initializeNativeStructure(); 32874180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick 329ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushClient = new NdefPushClient(this); 330ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer = new NdefPushServer(); 33157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 33224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mTechListFilters = new RegisteredComponentCache(this, 3338d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED); 33424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 3350bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas mSecureElement = new NativeNfcSecureElement(); 3360bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 337275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mPrefs = getSharedPreferences(PREF, Context.MODE_PRIVATE); 3380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor = mPrefs.edit(); 339f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 340d6fdd3fbb880f1503d56616608e6823b51320dc3Nick Pelly mIsNfcEnabled = false; // real preference read later 341f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 342275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 343275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 344533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NfcService"); 345275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mKeyguard = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 346275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = !mKeyguard.isKeyguardLocked() && !mKeyguard.isKeyguardSecure(); 347533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly 3481a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager = ActivityManagerNative.getDefault(); 3491a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly 350d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton ServiceManager.addService(SERVICE_NAME, mNfcAdapter); 351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 352eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton IntentFilter filter = new IntentFilter(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION); 35365945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_OFF); 35465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly filter.addAction(Intent.ACTION_SCREEN_ON); 355bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(ACTION_MASTER_CLEAR_NOTIFICATION); 356275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks filter.addAction(Intent.ACTION_USER_PRESENT); 357275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks registerReceiver(mReceiver, filter); 358bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 359bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter = new IntentFilter(); 360bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addAction(Intent.ACTION_PACKAGE_REMOVED); 361bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks filter.addDataScheme("package"); 362bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 363275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks registerReceiver(mReceiver, filter); 3640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Thread t = new Thread() { 3660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void run() { 3680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean nfc_on = mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT); 3690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (nfc_on) { 3700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly _enable(false); 371f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 372a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly resetSeOnFirstBoot(); 373f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 3750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly t.start(); 3760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 3792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly public void onTerminate() { 3802f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly super.onTerminate(); 3812f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly // NFC application is persistent, it should not be destroyed by framework 3820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Log.wtf(TAG, "NFC service is under attack!"); 3830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 3840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() { 3863ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton /** Protected by "this" */ 3873ca6ffff72f4599e80f85de5ae8e7f55012f38d6Jeff Hamilton NdefMessage mLocalMessage = null; 3884acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly 389fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 3900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean enable() throws RemoteException { 39193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 3920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 3930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 3940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 3950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!previouslyEnabled) { 3960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly reset(); 3970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = _enable(previouslyEnabled); 398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 402fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 4030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disable() throws RemoteException { 4040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 40593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 4060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean previouslyEnabled = isEnabled(); 407ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Disabling NFC. previous=" + previouslyEnabled); 4080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (previouslyEnabled) { 4106f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton /* tear down the my tag server */ 411ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.stop(); 412e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 413e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // Stop watchdog if tag present 414e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // A convenient way to stop the watchdog properly consists of 415e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // disconnecting the tag. The polling loop shall be stopped before 416e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir // to avoid the tag being discovered again. 41749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mIsDiscoveryOn = false; 41849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 419e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir maybeDisconnectTarget(); 420e260fc52ed2b4e6e1b7394d6f841d01c98888327Arnaud Ferir 4210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = mManager.deinitialize(); 422ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NFC success of deinitialize = " + isSuccess); 4230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 4240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 425a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Clear out any old dispatch overrides and NDEF push message 42605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 42705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 42805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 42905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 430a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mNdefPushClient.setForegroundMessage(null); 4310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 432f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 4330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(previouslyEnabled); 4350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 4360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 437f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 438f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 439fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 44005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void enableForegroundDispatch(ComponentName activity, PendingIntent intent, 44124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] filters, TechListParcel techListsParcel) { 442a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Permission check 44305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 444a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 445a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Argument validation 446a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (activity == null || intent == null) { 447ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 448ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 449a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 450a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // Validate the IntentFilters 451a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters != null) { 452a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filters.length == 0) { 453a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton filters = null; 454a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 455a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : filters) { 456a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter == null) { 457a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton throw new IllegalArgumentException("null IntentFilter"); 458a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 459a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 460a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 461a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 462a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 46324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Validate the tech lists 46424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] techLists = null; 46524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (techListsParcel != null) { 46624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton techLists = techListsParcel.getTechLists(); 46724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 46849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 46905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 470a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent != null) { 47105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "Replacing active dispatch overrides"); 47205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 47305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = intent; 474a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = filters; 47524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = techLists; 47605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 47705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 47805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 47905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 48005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton public void disableForegroundDispatch(ComponentName activity) { 48105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 48205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (this) { 483a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (mDispatchOverrideIntent == null) { 48405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.e(TAG, "No active foreground dispatching"); 48505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 48605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 487a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton mDispatchOverrideFilters = null; 48805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 48905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 49005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 49105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton @Override 492ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void enableForegroundNdefPush(ComponentName activity, NdefMessage msg) { 493ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 494ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (activity == null || msg == null) { 495ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton throw new IllegalArgumentException(); 496ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 497ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton if (mNdefPushClient.setForegroundMessage(msg)) { 498ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "Replacing active NDEF push message"); 499ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 500ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 501ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 502ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 5032094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks public void enableForegroundNdefPushWithCallback(ComponentName activity, 5042094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks INdefPushCallback callback) { 5052094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 5062094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (activity == null || callback == null) { 5072094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks throw new IllegalArgumentException(); 5082094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 5092094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (mNdefPushClient.setForegroundCallback(callback)) { 5102094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks Log.e(TAG, "Replacing active NDEF push message"); 5112094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 5122094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks } 5132094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks 5142094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks @Override 515ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton public void disableForegroundNdefPush(ComponentName activity) { 516ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 5172094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks boolean hadMsg = mNdefPushClient.setForegroundMessage(null); 5182094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks boolean hadCallback = mNdefPushClient.setForegroundCallback(null); 5192094515fca0cfa0ac87e9cc260d3953d416afe3eJason parks if (!hadMsg || !hadCallback) { 520ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton Log.e(TAG, "No active foreground NDEF push message"); 521ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 522ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton } 523ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton 524ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton @Override 5250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpConnectionlessSocket(int sap) throws RemoteException { 526d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 527bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 529f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 531f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 532f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check SAP is not already used */ 5340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5351878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Store the socket handle */ 5361878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int sockeHandle = mGeneratedSocketHandle; 5371878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpConnectionlessSocket socket; 538f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5391878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpConnectionlessSocket(sap); 5401878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5411878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5421878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5431878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5451878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5461878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5471878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 548f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 549f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5501878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5511878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5521878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5531878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5541878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5551878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5561878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5571878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5581878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5591878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5601878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 561f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 562f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 563f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 564fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 5650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) 5660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 567d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 568bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 569f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 570f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 571f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 572f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 573f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 5741878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpServiceSocket socket; 5750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5761878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 5771878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 5781878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 5791878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 5801878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 5810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 5821878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 5831878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 5841878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 585f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 586f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 5871878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 5881878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 5891878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 5901878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 5911878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 5921878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 5931878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 5941878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 5951878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 5961878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 5971878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 598f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 599f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 600f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 601fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) 6030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly throws RemoteException { 604d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 605bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 606f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 607f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 608f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 609f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 610f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 6111878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (DBG) Log.d(TAG, "creating llcp socket"); 6121878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau NativeLlcpSocket socket; 613bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 6141878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); 615f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 6161878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau if (socket != null) { 6171878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau synchronized(NfcService.this) { 6181878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* update socket handle generation */ 6191878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 6200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6211878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Add the socket into the socket map */ 6221878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, socket); 6231878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 6240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 625f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 6261878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Get Error Status */ 6271878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau int errorStatus = mManager.doGetLastError(); 6281878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6291878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(errorStatus)); 6301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau 6311878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau switch (errorStatus) { 6321878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_BUFFER_TO_SMALL: 6331878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_BUFFER_TO_SMALL; 6341878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: 6351878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; 6361878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau default: 6371878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.ERROR_SOCKET_CREATION; 6381878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau } 639f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 640f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 641f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 642fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { 644d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpConnectionlessSocketService; 6460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 647bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 648fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpSocket getLlcpInterface() throws RemoteException { 650d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpSocket; 6520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 653f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 654fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { 656d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mLlcpServerSocketService; 6580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 659f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 660fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public INfcTag getNfcTagInterface() throws RemoteException { 662d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mNfcTagService; 6640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 666fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { 668d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pInitiatorService; 6700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 672fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public IP2pTarget getP2pTargetInterface() throws RemoteException { 674d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mP2pTargetService; 6760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 678bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 67949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public INfcAdapterExtras getNfcAdapterExtrasInterface() { 68093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 68149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mExtrasService; 6820bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 6830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 684fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 6850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public String getProperties(String param) throws RemoteException { 686d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 6870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null) { 6890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 6900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 6910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 6920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 6930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 6940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 6950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 6960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 6970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 6980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 6990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Integer.toString(mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 7000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 7010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT)); 7020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 7030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT)); 7040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 7050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT)); 7060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 7070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT)); 7080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 7090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return Boolean.toString(mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT)); 710f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 7110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return "Unknown property"; 712f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 713f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 714f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 715fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean isEnabled() throws RemoteException { 7170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return mIsNfcEnabled; 7180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 720fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 7210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int setProperties(String param, String value) throws RemoteException { 72293d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 7230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isEnabled()) { 7250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NFC_ON; 7260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly int val; 7290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params validity */ 7310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param == null || value == null) { 7320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 7340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { 7360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_LTO_MAX) 7400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_LTO, val); 7442f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, val); 7480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { 7500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if ((val < LLCP_MIU_DEFAULT) || (val > LLCP_MIU_MAX)) 7540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_MIU, val); 7582f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, val); 7620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { 7640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_WKS_MAX) 7680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_WKS, val); 7722f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, val); 7760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { 7780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly val = Integer.parseInt(value); 7790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Check params */ 7810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (val > LLCP_OPT_MAX) 7820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 7830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putInt(PREF_LLCP_OPT, val); 7862f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, val); 7900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { 7920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 7930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 7950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_A, b); 7962f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 7970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 7980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 7990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, b ? 1 : 0); 8000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { 8020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_B, b); 8062f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, b ? 1 : 0); 8100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { 8120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_F, b); 8162f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, b ? 1 : 0); 8200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { 8220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_15693, b); 8262f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, b ? 1 : 0); 8300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { 8320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean b = Boolean.parseBoolean(value); 8330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Store value */ 8350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_DISCOVERY_NFCIP, b); 8362f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 8370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Update JNI */ 8390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, b ? 1 : 0); 8400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 841f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 8420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 843f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 8440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 8450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 846f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 847d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 848d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 849d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public NdefMessage localGet() throws RemoteException { 85057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 85157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 85257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 85357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton return mLocalMessage; 85457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 855d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 856d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton 857d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton @Override 858d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton public void localSet(NdefMessage message) throws RemoteException { 85993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceAdminPerm(mContext); 86057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 86157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton synchronized (this) { 86257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mLocalMessage = message; 86357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = NfcService.this.getApplicationContext(); 86457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 86557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Send a message to the UI thread to show or hide the icon so the requests are 86657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // serialized and the icon can't get out of sync with reality. 86757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (message != null) { 86857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileOutputStream out = null; 86957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 87057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 87157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out = context.openFileOutput(MY_TAG_FILE_NAME, Context.MODE_PRIVATE); 87257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] bytes = message.toByteArray(); 87357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (bytes.length == 0) { 87457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.w(TAG, "Setting a empty mytag"); 87557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 87657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 87757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.write(bytes); 87857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 87957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not write mytag file", e); 88057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 88157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 88257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (out != null) { 88357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.flush(); 88457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton out.close(); 88557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 88657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 88757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 88857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 88957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 89057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 89157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Only show the icon if NFC is enabled. 89257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 89357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_SHOW_MY_TAG_ICON, null); 89457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 89557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 89657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 89757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 89857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 89957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 900d65348455ae09a467f288d65dbf924fc60c8d290Jeff Hamilton } 9013fb14d0868594c78a777e805545209636814e223Martijn Coenen 9020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 9030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 9040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { 905f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 906f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpSocket findSocket(int nativeHandle) { 907bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 908bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpSocket)) { 909f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 910f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 911bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpSocket) socket; 912f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 913f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 914fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int close(int nativeHandle) throws RemoteException { 916d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 917bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 918f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 919f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 920f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 921f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 922f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 923f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 924f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 925f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 926f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 927f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 9281878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 9291878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 9301878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 9311878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return ErrorCodes.SUCCESS; 932f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 9330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 934f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 935f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 936f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 937fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle, int sap) throws RemoteException { 939d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 940bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 941f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 9420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 943f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 944f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 945f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 946f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 947f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 948f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 949f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 950f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 951f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 95293915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnect(sap); 9530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 9540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 955f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 956f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 957f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 958f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 959f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 960f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 962f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 963f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 964fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connectByName(int nativeHandle, String sn) throws RemoteException { 966d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 967bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 968f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpSocket socket = null; 969f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 970f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 971f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 972f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 973f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 974f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 975f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 976f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 977f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 978f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 97993915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly isSuccess = socket.doConnectBy(sn); 980f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 982f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 983f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 985f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 987f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 9880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 989f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 990f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 991fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 9920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSap(int nativeHandle) throws RemoteException { 993d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 994bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 9950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 996f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 997f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 998f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 999f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1000f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1001f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 10020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1003f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getSap(); 1006f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 10070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 1008f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1009f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1010f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1011fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketMiu(int nativeHandle) throws RemoteException { 1013d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1014bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 10150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 1016f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1017f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1018f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 10190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1020f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1021f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1022f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1023f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 10250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getMiu(); 10260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 1028f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1029f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1030f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1031fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getLocalSocketRw(int nativeHandle) throws RemoteException { 1033d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1034bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 10350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 1036f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1037f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1038f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1039f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1040f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1042f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1043f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.getRw(); 10460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return 0; 10480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1051fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { 1053d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1063f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketMiu() != 0) { 10660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketMiu(); 10670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1075fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 10760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getRemoteSocketRw(int nativeHandle) throws RemoteException { 1077d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 10780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 10800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 10820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 10830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 10840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 10860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1087f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 10880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 10890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket.doGetRemoteSocketRw() != 0) { 10900e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return socket.doGetRemoteSocketRw(); 10910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 10950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; 10960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 10980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1099fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { 1101d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 11040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1111f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 111328f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return socket.doReceive(receiveBuffer); 11140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 111528f72bd9880d0b00c486603489d3862733eb638fSylvain Fonteneau return 0; 11160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1119fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int send(int nativeHandle, byte[] data) throws RemoteException { 1121d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket socket = null; 11240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 11250e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1132f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 11340e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = socket.doSend(data); 11350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 11360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 11370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 11450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { 11470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1148f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpServiceSocket findSocket(int nativeHandle) { 1149bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1150bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpServiceSocket)) { 1151f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1152f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1153bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpServiceSocket) socket; 1154f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1155f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1156fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int accept(int nativeHandle) throws RemoteException { 1158d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpSocket clientSocket = null; 11620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 11660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1169f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 11700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 117193915e1c6fe6d5d16fcebeda610782bf5812c9b4Nick Pelly clientSocket = socket.doAccept(socket.getMiu(), 11720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly socket.getRw(), socket.getLinearBufferLength()); 11730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (clientSocket != null) { 11740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Add the socket into the socket map */ 11752f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 11761878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mGeneratedSocketHandle++; 11771878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau mSocketMap.put(mGeneratedSocketHandle, clientSocket); 11781878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau return mGeneratedSocketHandle; 11792f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 11800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } else { 11840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_IO; 11850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 1188fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 11890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void close(int nativeHandle) throws RemoteException { 1190d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 11910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeLlcpServiceSocket socket = null; 11930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 11950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 11960e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return; 11970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 11980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 11990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the socket in the hmap */ 1200f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 12010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (socket != null) { 12021878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 1203f63da5f0887eba86d877faaee41dc5dfb8fccd50Jeff Hamilton synchronized (this) { 12040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Remove the socket closed from the hmap */ 12050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly RemoveSocket(nativeHandle); 12060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 12070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 12080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1209f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1210f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1211f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { 1212f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1213f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau private NativeLlcpConnectionlessSocket findSocket(int nativeHandle) { 1214bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly Object socket = NfcService.this.findSocket(nativeHandle); 1215bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (!(socket instanceof NativeLlcpConnectionlessSocket)) { 1216f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau return null; 1217f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1218bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return (NativeLlcpConnectionlessSocket) socket; 1219f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau } 1220f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau 1221fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1222f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public void close(int nativeHandle) throws RemoteException { 1223d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1224bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1225f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1226f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1227f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1228f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1229f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return; 1230f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1231f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1232f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1233f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1234f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 12351878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau socket.doClose(); 12361878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau /* Remove the socket closed from the hmap */ 12371878c7b6e2cef1e52138ee3a5588913cc165faa5Sylvain Fonteneau RemoveSocket(nativeHandle); 1238f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1239f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1240f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1241fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1242f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getSap(int nativeHandle) throws RemoteException { 1243d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1244bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1245f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1246f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1247f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1248f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1249f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1250f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1251f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1252f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1253f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1254f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1255f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return socket.getSap(); 1256f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1257f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return 0; 1258f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1259f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1260f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1261fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { 1263d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1264bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1265f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1266f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly LlcpPacket packet; 1267f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1274f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly packet = socket.doReceiveFrom(socket.getLinkMiu()); 1277f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (packet != null) { 1278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return packet; 1279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1286fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { 1288d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1289bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1290f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeLlcpConnectionlessSocket socket = null; 1291f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1292f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1293f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1296f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1297f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1298f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the socket in the hmap */ 1299f5d6f3253dca74631ba78c715f224cfa80e61d29Sylvain Fonteneau socket = findSocket(nativeHandle); 1300f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (socket != null) { 1301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); 1302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (isSuccess) { 1303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1307f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 1308f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1309f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1310f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1311f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 1312f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1313f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private final INfcTag mNfcTagService = new INfcTag.Stub() { 1314f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1315fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1316f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int close(int nativeHandle) throws RemoteException { 1317d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1318bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1319f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1320f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1321f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1322f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1323f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1324f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1325f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1326f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1327f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1328f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1329b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* Remove the device from the hmap */ 1330b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 133121545af22f9b913ec9cb124287aab2fcb0cf2b3bNick Pelly tag.disconnect(); 1332b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.SUCCESS; 1333f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1334f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 133549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 1336f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_DISCONNECT; 1337f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1338f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1339fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1340ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen public int connect(int nativeHandle, int technology) throws RemoteException { 1341d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1342bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1343f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1344f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1346f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1347f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1348f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1350f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1351f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1352b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1353b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return ErrorCodes.ERROR_DISCONNECT; 1354f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1355ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen 13561b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen if (technology == TagTechnology.NFC_B) { 13571b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen return ErrorCodes.ERROR_NOT_SUPPORTED; 13581b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen } 13591b1e68327701225b728d43226049ad7a5dee4bcdMartijn Coenen 1360ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // Note that on most tags, all technologies are behind a single 1361ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // handle. This means that the connect at the lower levels 1362ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen // will do nothing, as the tag is already connected to that handle. 1363ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen if (tag.connect(technology)) { 1364ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.SUCCESS; 1365ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } else { 1366ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1367ae7d8d800ba73502d21e54d1deef16be0f061866Martijn Coenen } 1368f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1369f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1370fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1371aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen public int reconnect(int nativeHandle) throws RemoteException { 1372aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1373aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1374aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen NativeNfcTag tag = null; 1375aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1376aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen // Check if NFC is enabled 1377aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (!mIsNfcEnabled) { 1378aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 1379aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1380aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1381aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen /* find the tag in the hmap */ 1382aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 1383aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag != null) { 1384aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen if (tag.reconnect()) { 1385aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.SUCCESS; 1386aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } else { 1387aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1388aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1389aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1390aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen return ErrorCodes.ERROR_DISCONNECT; 1391aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen } 1392aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen 1393aae427142dc22e7e419c146bc7748d9daff518e8Martijn Coenen @Override 1394b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton public int[] getTechList(int nativeHandle) throws RemoteException { 1395d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1396bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1397f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1398f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1399f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1400f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1401f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1402f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1403b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NativeNfcTag tag = (NativeNfcTag) findObject(nativeHandle); 1404f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1405b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton return tag.getTechList(); 1406f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1407f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1408f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1409f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1410fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1411f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public byte[] getUid(int nativeHandle) throws RemoteException { 1412f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1413f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] uid; 1414f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1415f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1416f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1417f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1418f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1419f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1420f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1421f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1422f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1423f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly uid = tag.getUid(); 1424f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return uid; 1425f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1426f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1427f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1428f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1429fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1430b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public boolean isPresent(int nativeHandle) throws RemoteException { 1431b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau NativeNfcTag tag = null; 1432b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1433b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau // Check if NFC is enabled 1434b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (!mIsNfcEnabled) { 1435b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1436b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1437b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1438b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau /* find the tag in the hmap */ 1439b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau tag = (NativeNfcTag) findObject(nativeHandle); 1440b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag == null) { 1441b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau return false; 1442b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1443b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1444ab2b44b97936d2c5dbf6eda1245ca793e840713fMartijn Coenen return tag.isPresent(); 1445b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 1446b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 1447fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1448f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public boolean isNdef(int nativeHandle) throws RemoteException { 1449f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1450f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly boolean isSuccess = false; 1451f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1452f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1453f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1454f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1455f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1456f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1457f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1458f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 14593ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen int[] ndefInfo = new int[2]; 1460f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14613ba3b10867c36bff57b72ff99c7b56d63d418f3fMartijn Coenen isSuccess = tag.checkNdef(ndefInfo); 1462f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1463f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return isSuccess; 1464f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1465f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1466fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14679d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen public TransceiveResult transceive(int nativeHandle, byte[] data, boolean raw) 146897c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1469d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1470bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1471f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag = null; 1472f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly byte[] response; 1473f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1474f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1475f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1476f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1477f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1478f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1479f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1480f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1481f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 14829d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen int[] targetLost = new int[1]; 14839d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response = tag.transceive(data, raw, targetLost); 14849d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen TransceiveResult transResult = new TransceiveResult( 14859d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (response != null) ? true : false, 14869d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen (targetLost[0] == 1) ? true : false, 14879d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen response); 14889d5511f2640903a79d24578a12a93e50a96f0c0eMartijn Coenen return transResult; 1489f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1490f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1491f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1492f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1493fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 14943fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public NdefMessage ndefRead(int nativeHandle) throws RemoteException { 1495d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1496bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1497f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1498f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1499f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1500f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1501f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1502f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1503f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1504f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1505f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1506f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag != null) { 1507b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau byte[] buf = tag.read(); 1508f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (buf == null) 1509f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1510f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1511f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Create an NdefMessage */ 1512f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly try { 1513f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return new NdefMessage(buf); 1514f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } catch (FormatException e) { 1515f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1516f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1517f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1518f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return null; 1519f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1520f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1521fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefWrite(int nativeHandle, NdefMessage msg) throws RemoteException { 1523d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1524bebaa6cc1a1eb2ce0656e17b0e09ed4747878d8eNick Pelly 1525f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcTag tag; 1526f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1527f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Check if NFC is enabled 1528f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (!mIsNfcEnabled) { 1529f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1530f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1531f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1532f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* find the tag in the hmap */ 1533f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly tag = (NativeNfcTag) findObject(nativeHandle); 1534f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (tag == null) { 1535f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1536f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1537f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1538b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau if (tag.write(msg.toByteArray())) { 1539f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.SUCCESS; 1540f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1541f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly else { 1542f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_IO; 1543f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1544f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1545f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1546f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1547fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 1548f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly public int getLastError(int nativeHandle) throws RemoteException { 1549bb78d3749bd0cc3801fdd9d5df06b0f6ee7a400fMartijn Coenen return(mManager.doGetLastError()); 1550f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1551f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1552fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15533fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public boolean ndefIsWritable(int nativeHandle) throws RemoteException { 15543fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton throw new UnsupportedOperationException(); 1555f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1556f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1557fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 15583fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public int ndefMakeReadOnly(int nativeHandle) throws RemoteException { 155903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 156003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 156103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen NativeNfcTag tag; 156203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 156303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen // Check if NFC is enabled 156403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (!mIsNfcEnabled) { 156503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 156603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 156703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 156803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen /* find the tag in the hmap */ 156903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 157003ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag == null) { 157103ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 157203ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 157303ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen 157403ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen if (tag.makeReadonly()) { 157503ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.SUCCESS; 157603ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 157703ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen else { 157803ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen return ErrorCodes.ERROR_IO; 157903ee488afaa982ce934c5de399db9f9fa88c7d1eMartijn Coenen } 1580f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1581f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 15820aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen @Override 15830aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen public int formatNdef(int nativeHandle, byte[] key) throws RemoteException { 15840aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 15850aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15860aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen NativeNfcTag tag; 15870aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15880aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen // Check if NFC is enabled 15890aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (!mIsNfcEnabled) { 15900aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_NOT_INITIALIZED; 15910aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15920aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15930aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen /* find the tag in the hmap */ 15940aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 15950aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag == null) { 15960aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 15970aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 15980aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 15990aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen if (tag.formatNdef(key)) { 16000aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.SUCCESS; 16010aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 16020aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen else { 16030aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen return ErrorCodes.ERROR_IO; 16040aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 16050aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen } 16060aac9419555e69512a886a6b7fa6ce2d1947c72fMartijn Coenen 16071b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 16083fb14d0868594c78a777e805545209636814e223Martijn Coenen public Tag rediscover(int nativeHandle) throws RemoteException { 16093fb14d0868594c78a777e805545209636814e223Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 16103fb14d0868594c78a777e805545209636814e223Martijn Coenen 16113fb14d0868594c78a777e805545209636814e223Martijn Coenen NativeNfcTag tag = null; 16123fb14d0868594c78a777e805545209636814e223Martijn Coenen 16133fb14d0868594c78a777e805545209636814e223Martijn Coenen // Check if NFC is enabled 16143fb14d0868594c78a777e805545209636814e223Martijn Coenen if (!mIsNfcEnabled) { 16153fb14d0868594c78a777e805545209636814e223Martijn Coenen return null; 16163fb14d0868594c78a777e805545209636814e223Martijn Coenen } 16173fb14d0868594c78a777e805545209636814e223Martijn Coenen 16183fb14d0868594c78a777e805545209636814e223Martijn Coenen /* find the tag in the hmap */ 16193fb14d0868594c78a777e805545209636814e223Martijn Coenen tag = (NativeNfcTag) findObject(nativeHandle); 16203fb14d0868594c78a777e805545209636814e223Martijn Coenen if (tag != null) { 16213fb14d0868594c78a777e805545209636814e223Martijn Coenen // For now the prime usecase for rediscover() is to be able 16223fb14d0868594c78a777e805545209636814e223Martijn Coenen // to access the NDEF technology after formatting without 16233fb14d0868594c78a777e805545209636814e223Martijn Coenen // having to remove the tag from the field, or similar 16243fb14d0868594c78a777e805545209636814e223Martijn Coenen // to have access to NdefFormatable in case low-level commands 16253fb14d0868594c78a777e805545209636814e223Martijn Coenen // were used to remove NDEF. So instead of doing a full stack 16263fb14d0868594c78a777e805545209636814e223Martijn Coenen // rediscover (which is poorly supported at the moment anyway), 16273fb14d0868594c78a777e805545209636814e223Martijn Coenen // we simply remove these two technologies and detect them 16283fb14d0868594c78a777e805545209636814e223Martijn Coenen // again. 16293fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.removeTechnology(TagTechnology.NDEF); 16303fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.removeTechnology(TagTechnology.NDEF_FORMATABLE); 16313fb14d0868594c78a777e805545209636814e223Martijn Coenen NdefMessage[] msgs = findAndReadNdef(tag); 16323fb14d0868594c78a777e805545209636814e223Martijn Coenen // Build a new Tag object to return 16333fb14d0868594c78a777e805545209636814e223Martijn Coenen Tag newTag = new Tag(tag.getUid(), tag.getTechList(), 16343fb14d0868594c78a777e805545209636814e223Martijn Coenen tag.getTechExtras(), tag.getHandle(), mNfcTagService); 16353fb14d0868594c78a777e805545209636814e223Martijn Coenen return newTag; 16363fb14d0868594c78a777e805545209636814e223Martijn Coenen } 16373fb14d0868594c78a777e805545209636814e223Martijn Coenen return null; 16383fb14d0868594c78a777e805545209636814e223Martijn Coenen } 16393fb14d0868594c78a777e805545209636814e223Martijn Coenen 16403fb14d0868594c78a777e805545209636814e223Martijn Coenen 16413fb14d0868594c78a777e805545209636814e223Martijn Coenen @Override 16421b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void setIsoDepTimeout(int timeout) throws RemoteException { 16431b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 16441b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 16451b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.setIsoDepTimeout(timeout); 16461b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 1647f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16481b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen @Override 16491b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen public void resetIsoDepTimeout() throws RemoteException { 16501b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 16511b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen 16521b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen mManager.resetIsoDepTimeout(); 16531b61f1dee91101e249b9be65d95366fa745b3b78Martijn Coenen } 16540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1655f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { 1657f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1658fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1660d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1661f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1663f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16660e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16670e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1668f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16690e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16700e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 16730e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 16740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 16760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 16770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 16780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1679f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1680fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 16810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1682d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1683f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16840e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1685f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16860e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 16870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 16880e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 16890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1690f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 16910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 16920e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 16930e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 16940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 16950e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1696f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 1697f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1698f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1699fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] receive(int nativeHandle) throws RemoteException { 1701d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1702f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17030e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1704f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1709f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doReceive(); 17140e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 17150e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 17170e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17180e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 171949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 17200e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 17210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1722f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1723fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17240e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean send(int nativeHandle, byte[] data) throws RemoteException { 1725d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1726f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1729f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 17330e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1734f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17360e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17370e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly isSuccess = device.doSend(data); 17390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 17410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1743f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { 1745f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1746fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int connect(int nativeHandle) throws RemoteException { 1748d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1749f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1751f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 17550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1756f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17570e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17580e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17590e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17600e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device.doConnect()) { 17610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.SUCCESS; 17620e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17630e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 17640e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_CONNECT; 17650e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1766f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1767fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17680e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public boolean disconnect(int nativeHandle) throws RemoteException { 1769d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1770f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17710e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17720e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = false; 1773f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17740e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 17750e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 17760e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 17770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1778f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 17800e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 17810e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 17820e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess = device.doDisconnect()) { 17830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* remove the device from the hmap */ 1784b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau unregisterObject(nativeHandle); 17850e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Restart polling loop for notification */ 178649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 17870e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1788f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 17890e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 1790f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17910e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1792f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1793fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 17940e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { 1795d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1796f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 17970e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 17980e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 17990e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 18000e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 18010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1802f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1803f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 18050e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 18060e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 18070e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.getGeneralBytes(); 18080e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 18090e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18100e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 18110e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18120e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18130e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1814f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1815fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 18160e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public int getMode(int nativeHandle) throws RemoteException { 1817d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1818f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18190e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1820f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18210e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 18220e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 18230e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_NOT_INITIALIZED; 1824f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1825f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18260e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 18270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 18280e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 18290e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return device.getMode(); 18300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return ErrorCodes.ERROR_INVALID_PARAM; 18320e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 1833f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 1834fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 183597c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen public byte[] transceive(int nativeHandle, byte[] data) 183697c6942c7c7f9df3bb8dbcc01cf7bb6e2e090005Martijn Coenen throws RemoteException { 1837d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton mContext.enforceCallingOrSelfPermission(NFC_PERM, NFC_PERM_ERROR); 1838f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NativeP2pDevice device; 1840f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly // Check if NFC is enabled 18420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (!mIsNfcEnabled) { 18430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 1844f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 1845f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 18460e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* find the device in the hmap */ 18470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly device = (NativeP2pDevice) findObject(nativeHandle); 18480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (device != null) { 18490e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly byte[] buff = device.doTransceive(data); 18500e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (buff == null) 18510e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18520e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return buff; 18530e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18540e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return null; 18550e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 18560e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly }; 1857f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 185849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private INfcAdapterExtras mExtrasService = new INfcAdapterExtras.Stub() { 185949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeNoException() { 186049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 186149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", 0); 186249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 186349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 186449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private Bundle writeIoException(IOException e) { 186549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle p = new Bundle(); 186649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putInt("e", -1); 186749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly p.putString("m", e.getMessage()); 186849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return p; 186949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18700bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1871bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 187249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle open(IBinder b) throws RemoteException { 187393d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1874bd555ee64250126b60b24814120a2049943920caNick Pelly 187549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 187649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 187749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly _open(b); 187849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 187949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 188049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 18810bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 188249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 188349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 188549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private void _open(IBinder b) throws IOException, RemoteException { 188649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 188749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 188849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC adapter is disabled"); 188949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 189049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe != null) { 189149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE already open"); 189249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 18930bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 189449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly int handle = mSecureElement.doOpenSecureElementConnection(); 189549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (handle == 0) { 189649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE failed to open"); 189749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 1898ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly mManager.doSetIsoDepTimeout(10000); 1899ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly 190049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe = new OpenSecureElement(getCallingPid(), handle); 190149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 190249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly b.linkToDeath(mOpenEe, 0); 190349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (RemoteException e) { 190449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe.binderDied(); 190549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 190649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 19070bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19080bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1909bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 191049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle close() throws RemoteException { 191193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 19120bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 191349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 191449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 191549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly _close(); 191649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 191749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 191849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 19190bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 192049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 192149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 19220bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 192349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly void _close() throws IOException, RemoteException { 192449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // Blocks until a pending open() or transceive() times out. 192549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly //TODO: This is incorrect behavior - the close should interrupt pending 192649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly // operations. However this is not supported by current hardware. 19270bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 192849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 192949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 193049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC adapter is disabled"); 1931221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 193249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe == null) { 193349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE closed"); 193449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 193549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe.pid != -1 && getCallingPid() != mOpenEe.pid) { 193649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new SecurityException("Wrong PID"); 1937221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 1938221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas 1939ba6401757f8017faeb77423f2d08fd51be1d1051Nick Pelly mManager.doResetIsoDepTimeout(); 194049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mSecureElement.doDisconnect(mOpenEe.handle); 194149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mOpenEe = null; 194249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 194349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 19440bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19450bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19460bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1947bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 194849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public Bundle transceive(byte[] in) throws RemoteException { 194993d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 1950bd555ee64250126b60b24814120a2049943920caNick Pelly 195149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Bundle result; 195249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly byte[] out; 195349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 195449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly out = _transceive(in); 195549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeNoException(); 195649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result.putByteArray("out", out); 195749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (IOException e) { 195849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly result = writeIoException(e); 19590bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 196049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return result; 196149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 19620bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 196349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private byte[] _transceive(byte[] data) throws IOException, RemoteException { 196449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized(NfcService.this) { 196549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (!mIsNfcEnabled) { 196649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC is not enabled"); 196749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 196849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mOpenEe == null){ 196949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new IOException("NFC EE is not open"); 197049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 197149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (getCallingPid() != mOpenEe.pid) { 197249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly throw new SecurityException("Wrong PID"); 197349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 19740bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19750bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 197649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mSecureElement.doTransceive(mOpenEe.handle, data); 19770bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19780bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1979bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 198049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int getCardEmulationRoute() throws RemoteException { 198193d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 198249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly return mEeRoutingState; 19830bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 19840bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 1985bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 198649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void setCardEmulationRoute(int route) throws RemoteException { 198793d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton NfcService.enforceNfceeAdminPerm(mContext); 198849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mEeRoutingState = route; 198949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 19900bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 1991bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1992bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 1993bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks public void registerTearDownApdus(String packageName, ApduList apdu) throws RemoteException { 1994bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks NfcService.enforceNfceeAdminPerm(mContext); 1995a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.w(TAG, "NOP"); 1996a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //TODO: Remove this API 1997bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 1998bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 1999bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 2000bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks public void unregisterTearDownApdus(String packageName) throws RemoteException { 2001bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks NfcService.enforceNfceeAdminPerm(mContext); 2002a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.w(TAG, "NOP"); 2003a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //TODO: Remove this API 2004bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 20050bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas }; 20060bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 200749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** resources kept while secure element is open */ 200849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private class OpenSecureElement implements IBinder.DeathRecipient { 200949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int pid; // pid that opened SE 201049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public int handle; // low-level handle 201149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public OpenSecureElement(int pid, int handle) { 201249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.pid = pid; 201349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly this.handle = handle; 201449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } 2015bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks @Override 201649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly public void binderDied() { 201749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly synchronized (NfcService.this) { 201849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.d(TAG, "Tracked app " + pid + " died"); 201949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly pid = -1; 20200bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas try { 202149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mExtrasService.close(); 202249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } catch (RemoteException e) { /* local call never fails */ } 20230bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 20240bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 20250bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas } 20260bd11735e8a28db1692f28abcc3e065abae0e8ddDaniel Tomas 20270e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private boolean _enable(boolean oldEnabledState) { 20286efda9f3970382554437be037aed863be9889499Sylvain Fonteneau applyProperties(); 20296efda9f3970382554437be037aed863be9889499Sylvain Fonteneau 20300e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly boolean isSuccess = mManager.initialize(); 20310e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly if (isSuccess) { 203265945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly mIsNfcEnabled = true; 203349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mIsDiscoveryOn = true; 203465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 20350e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Start polling loop */ 203649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 203757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 203857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton /* bring up the my tag server */ 2039ca1a86ecb8edce740a232c3439355e8d5b706e7aJeff Hamilton mNdefPushServer.start(); 204057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2041f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } else { 20420e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mIsNfcEnabled = false; 2043f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2044f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20450e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly updateNfcOnSetting(oldEnabledState); 2046f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 20470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly return isSuccess; 2048f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2049f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 205049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /** apply NFC discovery and EE routing */ 205149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly private synchronized void applyRouting() { 205249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsNfcEnabled && mOpenEe == null) { 2053275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (mScreenUnlocked) { 205449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mEeRoutingState == ROUTE_ON_WHEN_SCREEN_ON) { 205549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing ON"); 205649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doSelectSecureElement(SECURE_ELEMENT_ID); 205749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 205849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 205949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doDeselectSecureElement(SECURE_ELEMENT_ID); 2060221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 206149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (mIsDiscoveryOn) { 206249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery ON"); 206349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.enableDiscovery(DISCOVERY_MODE_READER); 206449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly } else { 206549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 206649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.disableDiscovery(); 2067221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 2068221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } else { 206949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-EE routing OFF"); 207049d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.doDeselectSecureElement(SECURE_ELEMENT_ID); 207149d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Log.d(TAG, "NFC-C discovery OFF"); 207249d53329a0c720a7e430220d77805bc1763545b1Nick Pelly mManager.disableDiscovery(); 2073221b4d6ee301fbfe19402798f7d3c11e6878c888daniel_tomas } 207465945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 207565945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } 207665945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly 20772436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir /** Disconnect any target if present */ 20782436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir private synchronized void maybeDisconnectTarget() { 20792436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir if (mIsNfcEnabled) { 20802436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Iterator<?> iterator = mObjectMap.values().iterator(); 20812436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir while(iterator.hasNext()) { 20822436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir Object object = iterator.next(); 2083663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if(object instanceof NativeNfcTag) { 2084663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from tags 20852436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir NativeNfcTag tag = (NativeNfcTag) object; 20862436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir tag.disconnect(); 20872436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 2088663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else if(object instanceof NativeP2pDevice) { 2089663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Disconnect from P2P devices 2090663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau NativeP2pDevice device = (NativeP2pDevice) object; 2091663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2092663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is target, request disconnection 2093663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2094663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2095663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau else { 2096663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Remote peer is initiator, we cannot disconnect 2097663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Just wait for field removal 2098663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2099663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2100663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau iterator.remove(); 21012436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 21022436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 21032436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir } 21042436ffe91853535fad87b7a8e03d8883bae20f20Arnaud Ferir 2105a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //TODO: dont hardcode this 2106a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private static final byte[][] SE_RESET_APDUS = { 2107a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 2108a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x20, (byte)0x10, (byte)0x00}, 2109a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x80, (byte)0xe2, (byte)0x01, (byte)0x03, (byte)0x00}, 2110a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 2111a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x30, (byte)0x30, (byte)0x00}, 2112a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x80, (byte)0xb4, (byte)0x00, (byte)0x00, (byte)0x00}, 2113a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00}, 2114a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly }; 2115bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2116a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private void resetSeOnFirstBoot() { 2117a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (mPrefs.getBoolean(PREF_FIRST_BOOT, true)) { 2118a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.i(TAG, "First Boot"); 2119a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly executeSeReset(); 2120a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); 2121a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mPrefsEditor.apply(); 2122a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 2123a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 2124bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2125a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private synchronized void executeSeReset() { 2126a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly // TODO: read SE reset list from /system/etc 2127a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly //List<byte[]> apdus = readSeResetApdus(); 2128a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly byte[][]apdus = SE_RESET_APDUS; 2129a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (apdus == null) { 2130a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return; 2131a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 2132a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.i(TAG, "Executing SE Reset Script"); 2133a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int handle = mSecureElement.doOpenSecureElementConnection(); 2134a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (handle == 0) { 2135a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "Could not open the secure element!"); 2136a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return; 2137a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } 2138bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2139a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly for (byte[] cmd : apdus) { 2140a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mSecureElement.doTransceive(handle, cmd); 2141bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2142a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly 2143a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly mSecureElement.doDisconnect(handle); 2144bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2145bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2146a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly private List<byte[]> readSeResetApdus() { 2147a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly FileInputStream input = null; 2148a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly List<byte[]> apdus = null; 2149bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2150bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2151a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly input = openFileInput(SE_RESET_SCRIPT_FILE_NAME); 2152a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly DataInputStream stream = new DataInputStream(input); 2153bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2154a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int commandsSize = stream.readInt(); 2155a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus = new ArrayList<byte[]>(commandsSize); 2156bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2157a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly for (int i = 0 ; i < commandsSize ; i++) { 2158a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly int length = stream.readInt(); 2159bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2160a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly byte[] cmd = new byte[length]; 2161bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2162a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly stream.read(cmd); 2163a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus.add(cmd); 2164bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2165bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2166a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return apdus; 2167a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly } catch (FileNotFoundException e) { 2168a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "SE Reset Script not found: " + SE_RESET_SCRIPT_FILE_NAME); 2169bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2170a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly Log.e(TAG, "SE Reset Script corrupt: ", e); 2171a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly apdus = null; 2172bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } finally { 2173bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks try { 2174a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (input != null) { 2175a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly input.close(); 2176bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2177bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } catch (IOException e) { 2178bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks // Ignore 2179bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2180bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2181a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly return apdus; 2182bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 2183bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks 2184f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly private void applyProperties() { 2185f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_LTO, mPrefs.getInt(PREF_LLCP_LTO, LLCP_LTO_DEFAULT)); 2186f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_MIU, mPrefs.getInt(PREF_LLCP_MIU, LLCP_MIU_DEFAULT)); 2187f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_WKS, mPrefs.getInt(PREF_LLCP_WKS, LLCP_WKS_DEFAULT)); 2188f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_LLCP_OPT, mPrefs.getInt(PREF_LLCP_OPT, LLCP_OPT_DEFAULT)); 2189f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, 2190f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_A, DISCOVERY_A_DEFAULT) ? 1 : 0); 2191f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, 2192f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_B, DISCOVERY_B_DEFAULT) ? 1 : 0); 2193f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, 2194f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_F, DISCOVERY_F_DEFAULT) ? 1 : 0); 2195f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, 2196f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_15693, DISCOVERY_15693_DEFAULT) ? 1 : 0); 2197f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, 2198f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly mPrefs.getBoolean(PREF_DISCOVERY_NFCIP, DISCOVERY_NFCIP_DEFAULT) ? 1 : 0); 2199f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly } 2200f5280191c0e422a730504eebeced4acbcfc1bd9fNick Pelly 22010e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void updateNfcOnSetting(boolean oldEnabledState) { 22020e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled); 22032f386c612159a48933c12dbcaf6735bd9ad1c660Brad Fitzpatrick mPrefsEditor.apply(); 22040e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 22052f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized(this) { 22064acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly if (oldEnabledState != mIsNfcEnabled) { 22072f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE); 22084acf84356e35861f7df6d07a2b9ff84842a9f221Nick Pelly intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 22092f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled); 22102f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly mContext.sendBroadcast(intent); 22112f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly } 221257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 221357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (mIsNfcEnabled) { 221457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 221557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context context = getApplicationContext(); 221657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 221757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Set this to null by default. If there isn't a tag on disk 221857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // or if there was an error reading the tag then this will cause 221957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // the status bar icon to be removed. 222057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton NdefMessage myTag = null; 222157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 222257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton FileInputStream input = null; 222357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 222457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 222557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input = context.openFileInput(MY_TAG_FILE_NAME); 222657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 222757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 222857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton byte[] buffer = new byte[4096]; 222957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton int read = 0; 223057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton while ((read = input.read(buffer)) > 0) { 223157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton bytes.write(buffer, 0, read); 223257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 223357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 223457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton myTag = new NdefMessage(bytes.toByteArray()); 223557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FileNotFoundException e) { 223657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore. 223757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 223857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Could not read mytag file: ", e); 223957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 224057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (FormatException e) { 224157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.e(TAG, "Invalid NdefMessage for mytag", e); 224257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton context.deleteFile(MY_TAG_FILE_NAME); 224357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } finally { 224457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 224557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton if (input != null) { 224657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton input.close(); 224757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 224857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (IOException e) { 224957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 225057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 225157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 225257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 225357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton try { 225457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton mNfcAdapter.localSet(myTag); 225557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } catch (RemoteException e) { 225657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton // Ignore 225757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 225857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } else { 225957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sendMessage(MSG_HIDE_MY_TAG_ICON, null); 226057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 22610e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2262f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2263f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2264f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset all internals 22652f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized void reset() { 226674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // TODO: none of these appear to be synchronized but are 226774180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick // read/written from different threads (notably Binder threads)... 2268f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2269f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Clear tables 2270f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mObjectMap.clear(); 2271f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.clear(); 2272f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2273f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly // Reset variables 2274f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mIsNfcEnabled = false; 2275f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2276f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22772f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findObject(int key) { 2278f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Object device = null; 2279f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2280f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly device = mObjectMap.get(key); 2281f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly if (device == null) { 2282f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly Log.w(TAG, "Handle not found !"); 2283f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2284f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2285f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly return device; 2286f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2287f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22882f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void registerTagObject(NativeNfcTag nativeTag) { 2289b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.put(nativeTag.getHandle(), nativeTag); 2290b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2291b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 22922f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly synchronized void unregisterObject(int handle) { 2293b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mObjectMap.remove(handle); 2294f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2295f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 22962f8ac1e6cdeb32569bc6477d53a2d0d5608758b1Nick Pelly private synchronized Object findSocket(int key) { 2297bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly if (mSocketMap == null) { 2298bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return null; 2299bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly } 2300bfb74ec41fe9d2d1ce72467888432f0b3296425fNick Pelly return mSocketMap.get(key); 2301f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2302f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2303f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly private void RemoveSocket(int key) { 2304f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly mSocketMap.remove(key); 2305f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 2306f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2307d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2308d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) { 2309d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2310d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpSocket(sap, miu, rw, linearBufferLength); 23111be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 23121be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 23131be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 23141be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2315d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpSocket(mLlcpSocket, handle); 2316d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2317d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2318d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2319d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2320d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2321d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 2322d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton /** For use by code in this process */ 2323d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw, 2324d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int linearBufferLength) { 2325d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton try { 2326d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton int handle = mNfcAdapter.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); 23271be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton if (ErrorCodes.isError(handle)) { 23281be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton Log.e(TAG, "unable to create socket: " + ErrorCodes.asString(handle)); 23291be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton return null; 23301be4eb6d61c4b6e02c5a5cb7ac3b3a68cae7d7a2Jeff Hamilton } 2331d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return new LlcpServiceSocket(mLlcpServerSocketService, mLlcpSocket, handle); 2332d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } catch (RemoteException e) { 2333d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton // This will never happen since the code is calling into it's own process 2334d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton throw new IllegalStateException("unable to talk to myself", e); 2335d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2336d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 2337d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 23380e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private void activateLlcpLink() { 23390e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly /* Broadcast Intent Link LLCP activated */ 23400e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly Intent LlcpLinkIntent = new Intent(); 23410e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2342f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 23430e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 23440e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly NfcAdapter.LLCP_LINK_STATE_ACTIVATED); 2345f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 2346ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP activation"); 23470e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 23480e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly } 2349f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 235057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton public void sendMockNdefTag(NdefMessage msg) { 2351b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton sendMessage(MSG_MOCK_NDEF, msg); 235257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 235357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2354b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau void sendMessage(int what, Object obj) { 2355b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau Message msg = mHandler.obtainMessage(); 2356b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.what = what; 2357b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau msg.obj = obj; 2358b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau mHandler.sendMessage(msg); 2359b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2360b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 23613fb14d0868594c78a777e805545209636814e223Martijn Coenen static public NdefMessage[] findAndReadNdef(NativeNfcTag nativeTag) { 23623fb14d0868594c78a777e805545209636814e223Martijn Coenen // Try to find NDEF on any of the technologies. 23633fb14d0868594c78a777e805545209636814e223Martijn Coenen int[] technologies = nativeTag.getTechList(); 23643fb14d0868594c78a777e805545209636814e223Martijn Coenen int[] handles = nativeTag.getHandleList(); 23653fb14d0868594c78a777e805545209636814e223Martijn Coenen int techIndex = 0; 23663fb14d0868594c78a777e805545209636814e223Martijn Coenen int lastHandleScanned = 0; 23673fb14d0868594c78a777e805545209636814e223Martijn Coenen boolean ndefFoundAndConnected = false; 23683fb14d0868594c78a777e805545209636814e223Martijn Coenen NdefMessage[] ndefMsgs = null; 23693fb14d0868594c78a777e805545209636814e223Martijn Coenen boolean foundFormattable = false; 23703fb14d0868594c78a777e805545209636814e223Martijn Coenen int formattableHandle = 0; 23713fb14d0868594c78a777e805545209636814e223Martijn Coenen int formattableLibNfcType = 0; 23723fb14d0868594c78a777e805545209636814e223Martijn Coenen 23733fb14d0868594c78a777e805545209636814e223Martijn Coenen while ((!ndefFoundAndConnected) && (techIndex < technologies.length)) { 23743fb14d0868594c78a777e805545209636814e223Martijn Coenen if (handles[techIndex] != lastHandleScanned) { 23753fb14d0868594c78a777e805545209636814e223Martijn Coenen // We haven't seen this handle yet, connect and checkndef 23763fb14d0868594c78a777e805545209636814e223Martijn Coenen if (nativeTag.connect(technologies[techIndex])) { 23773fb14d0868594c78a777e805545209636814e223Martijn Coenen // Check if this type is NDEF formatable 23783fb14d0868594c78a777e805545209636814e223Martijn Coenen if (!foundFormattable) { 23793fb14d0868594c78a777e805545209636814e223Martijn Coenen if (nativeTag.isNdefFormatable()) { 23803fb14d0868594c78a777e805545209636814e223Martijn Coenen foundFormattable = true; 23813fb14d0868594c78a777e805545209636814e223Martijn Coenen formattableHandle = nativeTag.getConnectedHandle(); 23823fb14d0868594c78a777e805545209636814e223Martijn Coenen formattableLibNfcType = nativeTag.getConnectedLibNfcType(); 23833fb14d0868594c78a777e805545209636814e223Martijn Coenen // We'll only add formattable tech if no ndef is 23843fb14d0868594c78a777e805545209636814e223Martijn Coenen // found - this is because libNFC refuses to format 23853fb14d0868594c78a777e805545209636814e223Martijn Coenen // an already NDEF formatted tag. 23863fb14d0868594c78a777e805545209636814e223Martijn Coenen } 23873fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.reconnect(); 23883fb14d0868594c78a777e805545209636814e223Martijn Coenen } // else, already found formattable technology 23893fb14d0868594c78a777e805545209636814e223Martijn Coenen 23903fb14d0868594c78a777e805545209636814e223Martijn Coenen int[] ndefinfo = new int[2]; 23913fb14d0868594c78a777e805545209636814e223Martijn Coenen if (nativeTag.checkNdef(ndefinfo)) { 23923fb14d0868594c78a777e805545209636814e223Martijn Coenen ndefFoundAndConnected = true; 23933fb14d0868594c78a777e805545209636814e223Martijn Coenen boolean generateEmptyNdef = false; 23943fb14d0868594c78a777e805545209636814e223Martijn Coenen 23953fb14d0868594c78a777e805545209636814e223Martijn Coenen int supportedNdefLength = ndefinfo[0]; 23963fb14d0868594c78a777e805545209636814e223Martijn Coenen int cardState = ndefinfo[1]; 23973fb14d0868594c78a777e805545209636814e223Martijn Coenen byte[] buff = nativeTag.read(); 23983fb14d0868594c78a777e805545209636814e223Martijn Coenen if (buff != null) { 23993fb14d0868594c78a777e805545209636814e223Martijn Coenen ndefMsgs = new NdefMessage[1]; 24003fb14d0868594c78a777e805545209636814e223Martijn Coenen try { 24013fb14d0868594c78a777e805545209636814e223Martijn Coenen ndefMsgs[0] = new NdefMessage(buff); 24023fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.addNdefTechnology(ndefMsgs[0], 24033fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedHandle(), 24043fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedLibNfcType(), 24053fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedTechnology(), 24063fb14d0868594c78a777e805545209636814e223Martijn Coenen supportedNdefLength, cardState); 24073fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.reconnect(); 24083fb14d0868594c78a777e805545209636814e223Martijn Coenen } catch (FormatException e) { 24093fb14d0868594c78a777e805545209636814e223Martijn Coenen // Create an intent anyway, without NDEF messages 24103fb14d0868594c78a777e805545209636814e223Martijn Coenen generateEmptyNdef = true; 2411232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 24123fb14d0868594c78a777e805545209636814e223Martijn Coenen } else { 24133fb14d0868594c78a777e805545209636814e223Martijn Coenen generateEmptyNdef = true; 24143fb14d0868594c78a777e805545209636814e223Martijn Coenen } 2415232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 24163fb14d0868594c78a777e805545209636814e223Martijn Coenen if (generateEmptyNdef) { 24173fb14d0868594c78a777e805545209636814e223Martijn Coenen ndefMsgs = new NdefMessage[] { }; 24183fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.addNdefTechnology(null, 24193fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedHandle(), 24203fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedLibNfcType(), 24213fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.getConnectedTechnology(), 24223fb14d0868594c78a777e805545209636814e223Martijn Coenen supportedNdefLength, cardState); 24233fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.reconnect(); 24243fb14d0868594c78a777e805545209636814e223Martijn Coenen } 24253fb14d0868594c78a777e805545209636814e223Martijn Coenen } // else, no NDEF on this tech, continue loop 24263fb14d0868594c78a777e805545209636814e223Martijn Coenen } else { 24273fb14d0868594c78a777e805545209636814e223Martijn Coenen // Connect failed, tag maybe lost. Try next handle 24283fb14d0868594c78a777e805545209636814e223Martijn Coenen // anyway. 2429232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 2430e08c8939be916c393a62b995b2dee438cb8cec2fMartijn Coenen } 24313fb14d0868594c78a777e805545209636814e223Martijn Coenen lastHandleScanned = handles[techIndex]; 24323fb14d0868594c78a777e805545209636814e223Martijn Coenen techIndex++; 2433232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } 24343fb14d0868594c78a777e805545209636814e223Martijn Coenen if (ndefMsgs == null && foundFormattable) { 24353fb14d0868594c78a777e805545209636814e223Martijn Coenen // Tag is not NDEF yet, and found a formattable target, 24363fb14d0868594c78a777e805545209636814e223Martijn Coenen // so add formattable tech to tech list. 24373fb14d0868594c78a777e805545209636814e223Martijn Coenen nativeTag.addNdefFormatableTechnology( 24383fb14d0868594c78a777e805545209636814e223Martijn Coenen formattableHandle, 24393fb14d0868594c78a777e805545209636814e223Martijn Coenen formattableLibNfcType); 24403fb14d0868594c78a777e805545209636814e223Martijn Coenen } 24413fb14d0868594c78a777e805545209636814e223Martijn Coenen 24423fb14d0868594c78a777e805545209636814e223Martijn Coenen return ndefMsgs; 24433fb14d0868594c78a777e805545209636814e223Martijn Coenen } 24443fb14d0868594c78a777e805545209636814e223Martijn Coenen 24453fb14d0868594c78a777e805545209636814e223Martijn Coenen 24463fb14d0868594c78a777e805545209636814e223Martijn Coenen final class NfcServiceHandler extends Handler { 2447232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2448b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau @Override 2449b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau public void handleMessage(Message msg) { 2450f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly switch (msg.what) { 2451b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton case MSG_MOCK_NDEF: { 2452b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton NdefMessage ndefMsg = (NdefMessage) msg.obj; 2453b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton Tag tag = Tag.createMockTag(new byte[] { 0x00 }, 2454b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new int[] { }, 2455b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton new Bundle[] { }); 245657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, "mock NDEF tag, starting corresponding activity"); 245757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Log.d(TAG, tag.toString()); 24583fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchTag(tag, new NdefMessage[] { ndefMsg }); 245957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 246057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 246157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2462f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_NDEF_TAG: 2463ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Tag detected, notifying applications"); 2464f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeNfcTag nativeTag = (NativeNfcTag) msg.obj; 2465232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen NdefMessage[] ndefMsgs = findAndReadNdef(nativeTag); 2466232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen 2467232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (ndefMsgs != null) { 246898eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 2469232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen dispatchNativeTag(nativeTag, ndefMsgs); 2470232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2471232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen // No ndef found or connect failed, just try to reconnect and dispatch 2472232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen if (nativeTag.reconnect()) { 247398eb4249dcec63009b1839c005f0cf9048e1f7beMartijn Coenen nativeTag.startPresenceChecking(); 24743fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton dispatchNativeTag(nativeTag, null); 2475232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen } else { 2476232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen Log.w(TAG, "Failed to connect to tag"); 2477232eabb7c6f04506dbf272e06b115178311a57b9Martijn Coenen nativeTag.disconnect(); 2478f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2479f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2480f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 24813fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 2482f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_CARD_EMULATION: 2483ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Card Emulation message"); 2484f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly byte[] aid = (byte[]) msg.obj; 248549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly /* Send broadcast */ 248649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly Intent aidIntent = new Intent(); 248749d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.setAction(ACTION_AID_SELECTED); 248849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly aidIntent.putExtra(EXTRA_AID, aid); 248949d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.d(TAG, "Broadcasting ACTION_AID_SELECTED"); 249093d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(aidIntent, NFCEE_ADMIN_PERM); 2491f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2492f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2493f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_ACTIVATION: 2494f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NativeP2pDevice device = (NativeP2pDevice) msg.obj; 2495f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2496f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.d(TAG, "LLCP Activation message"); 2497f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2498f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2499ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_TARGET"); 2500f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (device.doConnect()) { 2501f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2502f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2503f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2504f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2505ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Initiator Activate LLCP OK"); 2506663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2507663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2508eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2509eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 2510eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton /* should not happen */ 2511eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.w(TAG, "Initiator Activate LLCP NOK. Disconnect."); 2512eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device.doDisconnect(); 2513b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2514b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2515f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else { 2516ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Remote Target does not support LLCP. Disconnect."); 2517f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly device.doDisconnect(); 2518b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2519eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } else { 25207f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir if (DBG) Log.d(TAG, "Cannot connect remote Target. Polling loop restarted..."); 25217f5487be0414b1f92b41cc5f7b0b7db846d9b1c9Arnaud Ferir /* The polling loop should have been restarted in failing doConnect */ 2522f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2523f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2524f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) { 2525ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "NativeP2pDevice.MODE_P2P_INITIATOR"); 2526f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Check Llcp compliancy */ 2527f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doCheckLlcp()) { 2528f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Activate Llcp Link */ 2529f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly if (mManager.doActivateLlcp()) { 2530ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Activate LLCP OK"); 2531663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau // Register P2P device 2532663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau mObjectMap.put(device.getHandle(), device); 2533eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton activateLlcpLink(); 2534eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton } 25356f7fd8dbda9092e36e58273e843ae3e4a200e2ffJeff Hamilton } else { 2536ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton Log.w(TAG, "checkLlcp failed"); 2537f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2538b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2539f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2540f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2541f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_LLCP_LINK_DEACTIVATED: 2542eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton device = (NativeP2pDevice) msg.obj; 2543eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2544eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton Log.d(TAG, "LLCP Link Deactivated message. Restart polling loop."); 2545663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau synchronized (NfcService.this) { 2546663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Check if the device has been already unregistered */ 2547663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (mObjectMap.remove(device.getHandle()) != null) { 2548663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Disconnect if we are initiator */ 2549663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) { 2550663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "disconnecting from target"); 2551663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau /* Restart polling loop */ 2552663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau device.doDisconnect(); 2553663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } else { 2554663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau if (DBG) Log.d(TAG, "not disconnecting from initiator"); 2555663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2556663c0153d74ddbe8e8ec1f9f55780beafa2543faSylvain Fonteneau } 2557cdab1112486288ee6ccc9eb5c55456f9618f6b9cJeff Hamilton } 2558eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton 2559f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Link LLCP activated */ 2560f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent LlcpLinkIntent = new Intent(); 2561f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); 2562f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, 2563f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); 2564ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting LLCP deactivation"); 2565f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(LlcpLinkIntent, NFC_PERM); 2566f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2567f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 2568f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly case MSG_TARGET_DESELECTED: 2569f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly /* Broadcast Intent Target Deselected */ 2570ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Target Deselected"); 2571f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Intent TargetDeselectedIntent = new Intent(); 2572f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly TargetDeselectedIntent.setAction(mManager.INTERNAL_TARGET_DESELECTED_ACTION); 2573ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "Broadcasting Intent"); 2574f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly mContext.sendOrderedBroadcast(TargetDeselectedIntent, NFC_PERM); 2575f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2576f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly 257757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_SHOW_MY_TAG_ICON: { 257857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 257957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 258057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.setIcon("nfc", R.drawable.stat_sys_nfc, 0); 258157d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 258257d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 258357d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 258457d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton case MSG_HIDE_MY_TAG_ICON: { 258557d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton StatusBarManager sb = (StatusBarManager) getSystemService( 258657d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton Context.STATUS_BAR_SERVICE); 258757d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton sb.removeIcon("nfc"); 258857d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton break; 258957d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton } 259057d376f1ee1a3939977b95759525585abb9601fbJeff Hamilton 2591c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_ACTIVATED:{ 2592c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD ACTIVATED"); 2593c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOnIntent = new Intent(); 259449d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOnIntent.setAction(ACTION_RF_FIELD_ON_DETECTED); 2595c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 259693d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOnIntent, NFCEE_ADMIN_PERM); 2597c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2598c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2599c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2600c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas case MSG_SE_FIELD_DEACTIVATED:{ 2601c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "SE FIELD DEACTIVATED"); 2602c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas Intent eventFieldOffIntent = new Intent(); 260349d53329a0c720a7e430220d77805bc1763545b1Nick Pelly eventFieldOffIntent.setAction(ACTION_RF_FIELD_OFF_DETECTED); 2604c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas if (DBG) Log.d(TAG, "Broadcasting Intent"); 260593d8a69ccadfa01b0a5ec3d7edeb921a1da4bce8Jeff Hamilton mContext.sendBroadcast(eventFieldOffIntent, NFCEE_ADMIN_PERM); 2606c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas break; 2607c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas } 2608c9a2ae7cb238e4c72818d084cba0b05e76cba1efdaniel_tomas 2609f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly default: 2610f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly Log.e(TAG, "Unknown message received"); 2611f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly break; 2612f348bf5b21c5c39d7b3627327db1e61007d07539Nick Pelly } 2613b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau } 2614d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton 26153fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Intent buildTagIntent(Tag tag, NdefMessage[] msgs, String action) { 26163fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent = new Intent(action); 2617b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_TAG, tag); 2618b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_ID, tag.getId()); 2619b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, msgs); 2620b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2621d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton return intent; 2622d0ec3981792e38afd119fc1c995f111f6182f6c8Jeff Hamilton } 26233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private void dispatchNativeTag(NativeNfcTag nativeTag, NdefMessage[] msgs) { 26253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Tag tag = new Tag(nativeTag.getUid(), nativeTag.getTechList(), 26260c322dc2d942285bfcd9fe5c0bba1a5f36a967f5Jeff Hamilton nativeTag.getTechExtras(), nativeTag.getHandle(), mNfcTagService); 262710389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen registerTagObject(nativeTag); 262810389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen if (!dispatchTag(tag, msgs)) { 262910389c11abdae4c794082f6c51f11b28b422eddbMartijn Coenen unregisterObject(nativeTag.getHandle()); 26303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton nativeTag.disconnect(); 26313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26323fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26333fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26343fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton public byte[] concat(byte[]... arrays) { 26353fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int length = 0; 26363fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 26373fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton length += array.length; 26383fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26393fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] result = new byte[length]; 26403fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton int pos = 0; 26413fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton for (byte[] array : arrays) { 26423fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton System.arraycopy(array, 0, result, pos, array.length); 26433fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton pos += array.length; 26443fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26453fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return result; 26463fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26473fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26483fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private Uri parseWellKnownUriRecord(NdefRecord record) { 26493fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] payload = record.getPayload(); 26503fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26513fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /* 26523fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[0] contains the URI Identifier Code, per the 26533fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * NFC Forum "URI Record Type Definition" section 3.2.2. 26543fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * 26553fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * payload[1]...payload[payload.length - 1] contains the rest of 26563fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton * the URI. 26573fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton */ 26583fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton String prefix = URI_PREFIX_MAP[(payload[0] & 0xff)]; 26593fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] fullUri = concat(prefix.getBytes(Charsets.UTF_8), 26603fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Arrays.copyOfRange(payload, 1, payload.length)); 26613fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return Uri.parse(new String(fullUri, Charsets.UTF_8)); 26623fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 26633fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 26643fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean setTypeOrDataFromNdef(Intent intent, NdefRecord record) { 26653fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton short tnf = record.getTnf(); 26663fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton byte[] type = record.getType(); 2667adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2668adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton switch (tnf) { 2669adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_MIME_MEDIA: { 2670adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType(new String(type, Charsets.US_ASCII)); 26713fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 2672adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 267321ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton 2674adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_ABSOLUTE_URI: { 26755223d6aafa38c8dbbe684f1f8611ee0f46e7ef02Jeff Hamilton intent.setData(Uri.parse(new String(type, Charsets.UTF_8))); 2676adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2677adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 267821ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton 2679adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton case NdefRecord.TNF_WELL_KNOWN: { 2680adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton byte[] payload = record.getPayload(); 2681adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (payload == null || payload.length == 0) return false; 2682adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (Arrays.equals(type, NdefRecord.RTD_TEXT)) { 2683adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setType("text/plain"); 2684adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2685adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_SMART_POSTER)) { 2686adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // Parse the smart poster looking for the URI 2687adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton try { 2688adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefMessage msg = new NdefMessage(record.getPayload()); 2689adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton for (NdefRecord subRecord : msg.getRecords()) { 2690adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton short subTnf = subRecord.getTnf(); 2691adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (subTnf == NdefRecord.TNF_WELL_KNOWN 2692adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton && Arrays.equals(subRecord.getType(), 2693adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton NdefRecord.RTD_URI)) { 2694adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(subRecord)); 2695adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2696adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (subTnf == NdefRecord.TNF_ABSOLUTE_URI) { 26975223d6aafa38c8dbbe684f1f8611ee0f46e7ef02Jeff Hamilton intent.setData(Uri.parse(new String(subRecord.getType(), 2698adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Charsets.UTF_8))); 2699adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2700adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 27013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2702adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (FormatException e) { 2703adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 27043fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2705adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else if (Arrays.equals(type, NdefRecord.RTD_URI)) { 2706adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton intent.setData(parseWellKnownUriRecord(record)); 2707adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 27083fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2709adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 27103fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 271121ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton 271221ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton case NdefRecord.TNF_EXTERNAL_TYPE: { 271321ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton intent.setData(Uri.parse("vnd.android.nfc://ext/" + 271421ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton new String(record.getType(), Charsets.US_ASCII))); 271521ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton return true; 271621ee4b2e782188cbc8e8b7752dd992844a904615Jeff Hamilton } 27173fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 2718adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 2719adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } catch (Exception e) { 2720adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton Log.e(TAG, "failed to parse record", e); 2721adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return false; 27223fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27243fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 27253fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton /** Returns false if no activities were found to dispatch to */ 27263fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton private boolean dispatchTag(Tag tag, NdefMessage[] msgs) { 27273fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (DBG) { 27283fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, "Dispatching tag"); 27293fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.d(TAG, tag.toString()); 27303fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 27313fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 273205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton IntentFilter[] overrideFilters; 273305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton PendingIntent overrideIntent; 273424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists; 2735a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean foregroundNdefPush = mNdefPushClient.getForegroundMessage() != null; 273605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 273705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideFilters = mDispatchOverrideFilters; 273805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton overrideIntent = mDispatchOverrideIntent; 273924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists = mDispatchOverrideTechLists; 274005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 274105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 274205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // First look for dispatch overrides 2743a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (overrideIntent != null) { 274405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Attempting to dispatch tag with override"); 274549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly try { 274624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (dispatchTagInternal(tag, msgs, overrideIntent, overrideFilters, 274724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 274805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (DBG) Log.d(TAG, "Dispatched to override"); 274905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 275005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 275105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch override registered, but no filters matched"); 275205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (CanceledException e) { 275305973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton Log.w(TAG, "Dispatch overrides pending intent was canceled"); 275405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton synchronized (mNfcAdapter) { 275505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideFilters = null; 275605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mDispatchOverrideIntent = null; 275724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mDispatchOverrideTechLists = null; 275805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 275905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 276005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 276105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 2762a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // If there is not foreground NDEF push setup try a normal dispatch. 2763a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // 2764a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // This is avoided when disabled in the NDEF push case to avoid the situation where each 2765a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // user has a different app in the foreground, causing each to launch itself on the 2766a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // remote device and the apps swapping which is in the foreground on each phone. 2767a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (!foregroundNdefPush) { 2768a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton try { 276924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return dispatchTagInternal(tag, msgs, null, null, null); 2770a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } catch (CanceledException e) { 2771a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.e(TAG, "CanceledException unexpected here", e); 2772a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2773a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 277405973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2775a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2776a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 277705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 277805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 277924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton /** Returns true if the tech list filter matches the techs on the tag */ 278024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton private boolean filterMatch(String[] tagTechs, String[] filterTechs) { 278124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterTechs == null || filterTechs.length == 0) return false; 278224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 278324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String tech : filterTechs) { 278424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (Arrays.binarySearch(tagTechs, tech) < 0) { 278524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return false; 278624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 278724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 278824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 278924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 279024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 279105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton // Dispatch to either an override pending intent or a standard startActivity() 279205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean dispatchTagInternal(Tag tag, NdefMessage[] msgs, 279324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton PendingIntent overrideIntent, IntentFilter[] overrideFilters, 279424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[][] overrideTechLists) 279505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton throws CanceledException{ 27963fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Intent intent; 279724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 279824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 279924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Try the NDEF content specific dispatch 280024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28013fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (msgs != null && msgs.length > 0) { 28023fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefMessage msg = msgs[0]; 28033fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord[] records = msg.getRecords(); 28043fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton if (records.length > 0) { 28053fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Found valid NDEF data, try to dispatch that first 28063fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton NdefRecord record = records[0]; 28073fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 28083fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_NDEF_DISCOVERED); 2809adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (setTypeOrDataFromNdef(intent, record)) { 2810adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // The record contains filterable data, try to start a matching activity 281124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, 281224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideTechLists)) { 2813adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton // If an activity is found then skip further dispatching 2814adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton return true; 2815adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } else { 2816adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton if (DBG) Log.d(TAG, "No activities for NDEF handling of " + intent); 2817adb527a9ce286d019d766a3b207a2251dea89bd1Jeff Hamilton } 28183fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28193fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28203fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28213fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 282224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28233fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the technology specific dispatch 282424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 282524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton String[] tagTechs = tag.getTechList(); 282624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton Arrays.sort(tagTechs); 282724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton 282824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideIntent != null) { 282924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // There are dispatch overrides in place 283024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideTechLists != null) { 283124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (String[] filterTechs : overrideTechLists) { 283224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (filterMatch(tagTechs, filterTechs)) { 283324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // An override matched, send it to the foreground activity. 283424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = buildTagIntent(tag, msgs, 28358d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly NfcAdapter.ACTION_TECH_DISCOVERED); 283624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 283724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 283824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 283924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 284024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 284105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 284224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Standard tech dispatch path 284324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ResolveInfo> matches = new ArrayList<ResolveInfo>(); 284424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ArrayList<ComponentInfo> registered = mTechListFilters.getComponents(); 2845160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen PackageManager pm = getPackageManager(); 284649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 284724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Check each registered activity to see if it matches 284824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton for (ComponentInfo info : registered) { 284924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Don't allow wild card matching 2850160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen if (filterMatch(tagTechs, info.techs) && 2851160b03be2e1ce574d228a2564d21c5f13f8c7b53Martijn Coenen isComponentEnabled(pm, info.resolveInfo)) { 28523ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton // Add the activity as a match if it's not already in the list 28533ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton if (!matches.contains(info.resolveInfo)) { 28543ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton matches.add(info.resolveInfo); 28553ca2b3f925d434559300ee2fb10bfcdd365a0fb6Jeff Hamilton } 285624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 285724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 285849d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 285924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (matches.size() == 1) { 286024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Single match, launch directly 28618d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECH_DISCOVERED); 286224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton ResolveInfo info = matches.get(0); 286324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.setClassName(info.activityInfo.packageName, info.activityInfo.name); 286424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 286524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 286624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 286724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 286824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 286924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 287024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (matches.size() > 1) { 287124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // Multiple matches, show a custom activity chooser dialog 287224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent = new Intent(mContext, TechListChooserActivity.class); 287324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 287424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putExtra(Intent.EXTRA_INTENT, 28758d69f5205e3c4a7c2eb869bbf4983d3d9fe45ab0Nick Pelly buildTagIntent(tag, msgs, NfcAdapter.ACTION_TECH_DISCOVERED)); 287624dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton intent.putParcelableArrayListExtra(TechListChooserActivity.EXTRA_RESOLVE_INFOS, 287724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton matches); 287824dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton try { 287924dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton mContext.startActivity(intent); 288024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton return true; 288124dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } catch (ActivityNotFoundException e) { 288224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (DBG) Log.w(TAG, "No activities for technology handling of " + intent); 288324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 288424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else { 288524dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // No matches, move on 288649d53329a0c720a7e430220d77805bc1763545b1Nick Pelly if (DBG) Log.w(TAG, "No activities for technology handling"); 288724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } 28883fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 28893fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton 289024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28913fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton // Try the generic intent 289224dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton // 28933fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton intent = buildTagIntent(tag, msgs, NfcAdapter.ACTION_TAG_DISCOVERED); 289424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (startDispatchActivity(intent, overrideIntent, overrideFilters, overrideTechLists)) { 28953fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return true; 289605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 28973fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton Log.e(TAG, "No tag fallback activity found for " + intent); 28983fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton return false; 28993fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 29003fb30ae5bf51d9ffe6271a345d55905dade8040dJeff Hamilton } 290105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton 290205973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton private boolean startDispatchActivity(Intent intent, PendingIntent overrideIntent, 290324dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton IntentFilter[] overrideFilters, String[][] overrideTechLists) 290424dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton throws CanceledException { 290505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton if (overrideIntent != null) { 2906a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton boolean found = false; 290724dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton if (overrideFilters == null && overrideTechLists == null) { 2908a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton // No filters means to always dispatch regardless of match 2909a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 291024dbea55709219e42aa3b6b6578f29ffd447a786Jeff Hamilton } else if (overrideFilters != null) { 2911a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton for (IntentFilter filter : overrideFilters) { 2912a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (filter.match(mContext.getContentResolver(), intent, false, TAG) >= 0) { 2913a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton found = true; 2914a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton break; 2915a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 291605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 291705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2918a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton 2919a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton if (found) { 2920a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton Log.i(TAG, "Dispatching to override intent " + overrideIntent); 2921a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton overrideIntent.send(mContext, Activity.RESULT_OK, intent); 2922a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return true; 2923a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } else { 2924a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton return false; 2925a1935861ea244b45e29b0ec9b6f263de3c08a2d6Jeff Hamilton } 292605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } else { 292705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton try { 29281a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // If the current app called stopAppSwitches() then our startActivity() 29291a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // can be delayed for several seconds. This happens with the default home 29301a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // screen. As a system service we can override this behavior with 29311a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly // resumeAppSwitches() 29321a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly mIActivityManager.resumeAppSwitches(); 29331a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly } catch (RemoteException e) { } 29341a9eca5f84036d7dd3e28000290caa2f641856deNick Pelly try { 293505973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton mContext.startActivity(intent); 293605973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return true; 293705973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } catch (ActivityNotFoundException e) { 293805973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton return false; 293905973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 294005973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 294105973d55daf68a286c932ee4e7ffbd6bb53789e0Jeff Hamilton } 2942b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton } 2943b230214bcb557184cb54174889cbede53b92d54fSylvain Fonteneau 2944b74200f40f9d4f536b8782974d444f1f9178076fJeff Hamilton private NfcServiceHandler mHandler = new NfcServiceHandler(); 294549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly 29467c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly private class EnableDisableDiscoveryTask extends AsyncTask<Boolean, Void, Void> { 2947fa746bcc16d57ff12d373b9139558f5bc7164b30Jason parks @Override 2948275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks protected Void doInBackground(Boolean... params) { 2949275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "EnableDisableDiscoveryTask: enable = " + params[0]); 2950275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 2951275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (params != null && params.length > 0 && params[0]) { 2952161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2953275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (!mScreenUnlocked) { 2954275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = true; 2955275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks applyRouting(); 2956275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else { 2957275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "Ignoring enable request"); 2958275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } 2959161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 29607c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } else { 2961533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.acquire(); 2962161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly synchronized (NfcService.this) { 2963275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (mScreenUnlocked) { 2964275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks mScreenUnlocked = false; 2965275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks applyRouting(); 2966275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks maybeDisconnectTarget(); 2967275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else { 2968275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks if (DBG) Log.d(TAG, "Ignoring disable request"); 2969275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } 2970161f84b5487ce4c1ebef9fe24ba4de00f6f756eaNick Pelly } 2971533043d1003de2f6a20a29201100d94c3c7bc9caNick Pelly mWakeLock.release(); 29727c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 29737c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly return null; 29747c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 29757c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly } 29767c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly 29770e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 29780e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly @Override 29790e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly public void onReceive(Context context, Intent intent) { 2980eead88c5e2bdd34eb33fdf2c76717f9edb9e0396Jeff Hamilton if (intent.getAction().equals( 2981f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { 2982ef92efa7fd86d75cc35465b84e8740f941ff0f0aJeff Hamilton if (DBG) Log.d(TAG, "INERNAL_TARGET_DESELECTED_ACTION"); 29830e6a0a0f50132e14d5ecad61c46e07c67fbb26fbNick Pelly 2984f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly /* Restart polling loop for notification */ 298549d53329a0c720a7e430220d77805bc1763545b1Nick Pelly applyRouting(); 2986f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly 298765945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 29887c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery enable in thread to protect against ANR when the 29897c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 29907c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 29917c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 2992275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 2993275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // Only enable if the screen is unlocked. If the screen is locked 2994275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // Intent.ACTION_USER_PRESENT will be broadcast when the screen is 2995275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // unlocked. 2996275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks boolean enable = !mKeyguard.isKeyguardLocked() && !mKeyguard.isKeyguardSecure(); 2997275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks 2998275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(enable); 299965945ad77cadb7a3bdf171497877d2325b23def5Nick Pelly } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 30007c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // Perform discovery disable in thread to protect against ANR when the 30017c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // NFC stack wedges. This is *not* the correct way to fix this issue - 30027c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // configuration of the local NFC adapter should be very quick and should 30037c034a7fe7d36b1ab039af2c44717812ea02657eNick Pelly // be safe on the main thread, and the NFC stack should not wedge. 3004275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(Boolean.FALSE); 3005275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks } else if (intent.getAction().equals(Intent.ACTION_USER_PRESENT)) { 3006275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks // The user has unlocked the screen. Enabled! 3007275fd2b59ae8a9e3eb6e77e8663aea9ca08f1159Jason parks new EnableDisableDiscoveryTask().execute(Boolean.TRUE); 3008bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(ACTION_MASTER_CLEAR_NOTIFICATION)) { 3009a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly executeSeReset(); 3010bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) { 30117a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton boolean dataRemoved = intent.getBooleanExtra(Intent.EXTRA_DATA_REMOVED, false); 30127a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (dataRemoved) { 30137a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton Uri data = intent.getData(); 30147a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton if (data == null) return; 30157a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton String packageName = data.getSchemeSpecificPart(); 30167a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton 30177a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton synchronized (NfcService.this) { 3018a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly if (packageName.equals(mSePackageName)) { 3019a8b7cca914e4a17f5c432f7bbeed0f1b236c55b4Nick Pelly executeSeReset(); 30207a7f8f8fd82936f0ee005ccfa7ac5c36760ed902Jeff Hamilton } 3021bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 3022bcd6a9954c5abafc6b14aabcc7768d0f03cc956cJason parks } 3023f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3024f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly } 3025f067256d9556b1e01143f9ae2fd824fa5dc03138Nick Pelly }; 302674180bda362a8bc9d2f701d2c17bec0f63c20bbfBrad Fitzpatrick} 3027