1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.ndef.cts; 18 19 import java.nio.charset.Charset; 20 import java.util.Arrays; 21 22 import android.net.Uri; 23 import android.nfc.NdefMessage; 24 import android.nfc.NdefRecord; 25 import android.nfc.FormatException; 26 27 import junit.framework.TestCase; 28 29 /** 30 * NDEF is a NFC-Forum defined data format.<p> 31 * NDEF is often used with NFC, but it is just a data format and no NFC 32 * hardware is required, so these API's are mandatory even on Android 33 * devices without NFC hardware. 34 */ 35 public class NdefTest extends TestCase { 36 static final Charset ASCII = Charset.forName("US-ASCII"); 37 static final Charset UTF8 = Charset.forName("UTF-8"); 38 testConstructor()39 public void testConstructor() { 40 NdefRecord r; 41 42 r = new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null); 43 assertEquals(new byte[0], r.getId()); 44 assertEquals(new byte[0], r.getType()); 45 assertEquals(new byte[0], r.getPayload()); 46 assertEquals(NdefRecord.TNF_EMPTY, r.getTnf()); 47 } 48 testEquals()49 public void testEquals() { 50 assertEquals(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 51 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)); 52 assertEquals( 53 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 54 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9}), 55 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 56 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})); 57 assertNotEquals( 58 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 59 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9}), 60 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 61 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9,10})); 62 assertEquals( 63 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 64 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})), 65 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 66 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9}))); 67 assertNotEquals( 68 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 69 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})), 70 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 71 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9,10}))); 72 assertNotEquals( 73 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 74 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})), 75 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 76 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9}), 77 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null))); 78 79 // test hashCode 80 assertEquals(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null).hashCode(), 81 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null).hashCode()); 82 assertEquals( 83 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 84 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})).hashCode(), 85 new NdefMessage(new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, 86 new byte[] {1,2,3}, new byte[] {4,5,6}, new byte[] {7,8,9})).hashCode()); 87 } 88 testInvalidParsing()89 public void testInvalidParsing() throws FormatException { 90 final byte[][] invalidNdefMessages = { 91 {}, // too short 92 {(byte)0xD0}, // too short 93 {(byte)0xD0, 0}, // too short 94 {(byte)0xD0, 0, 0, 0, 0}, // too long 95 {(byte)0x50, 0, 0}, // missing MB 96 {(byte)0x90, 0, 0}, // missing ME 97 {(byte)0xC0, 0, 0, 0}, // long record, too short 98 {(byte)0xC0, 0, 0, 0, 0}, // long record, too short 99 {(byte)0xC0, 0, 0, 0, 0, 0, 0}, // long record, too long 100 {(byte)0xD8, 1, 3, 1, 0, 0, 0, 0}, // SR w/ payload&type&id, too short 101 {(byte)0xD8, 1, 3, 1, 0, 0, 0, 0, 0, 0}, // SR w/ payload&type&id, too long 102 {(byte)0xD8, 0, 0, 1, 0}, // TNF_EMPTY cannot have id field 103 {(byte)0x90, 0, 0, (byte)0x10, 0, 0}, // 2 records, missing ME 104 {(byte)0xF5, 0, 0}, // CF and ME set 105 {(byte)0xD6, 0, 0}, // TNF_UNCHANGED without chunking 106 {(byte)0xB6, 0, 1, 1, (byte)0x56, 0, 1, 2}, // TNF_UNCHANGED in first chunk 107 {(byte)0xC5, 0, (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF}, // heap-smash check 108 }; 109 110 for (byte[] b : invalidNdefMessages) { 111 try { 112 new NdefMessage(b); 113 fail("expected FormatException for input " + bytesToString(b)); 114 } catch (FormatException e) { } 115 } 116 } 117 testValidParsing()118 public void testValidParsing() throws FormatException { 119 // short record 120 assertEquals(new NdefMessage(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)), 121 new NdefMessage(new byte[] {(byte)0xD0, 0, 0})); 122 123 // full length record 124 assertEquals(new NdefMessage(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)), 125 new NdefMessage(new byte[] {(byte)0xC0, 0, 0, 0, 0, 0})); 126 127 // SR with ID flag and 0-length id 128 assertEquals(new NdefMessage(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)), 129 new NdefMessage(new byte[] {(byte)0xD8, 0, 0, 0})); 130 131 // SR with ID flag and 1-length id 132 assertEquals(new NdefMessage( 133 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, null, new byte[] {0}, null)), 134 new NdefMessage(new byte[] {(byte)0xD9, 0, 0, 1, 0})); 135 136 // ID flag and 1-length id 137 assertEquals(new NdefMessage( 138 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, null, new byte[] {0}, null)), 139 new NdefMessage(new byte[] {(byte)0xC9, 0, 0, 0, 0, 0, 1, 0})); 140 141 // SR with payload 142 assertEquals(new NdefMessage( 143 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, null, null, new byte[] {1, 2, 3})), 144 new NdefMessage(new byte[] {(byte)0xD1, 0, 3, 1, 2, 3})); 145 146 // SR with payload and type 147 assertEquals(new NdefMessage(new NdefRecord( 148 NdefRecord.TNF_WELL_KNOWN, new byte[] {9}, null, new byte[] {1, 2, 3})), 149 new NdefMessage(new byte[] {(byte)0xD1, 1, 3, 9, 1, 2, 3})); 150 151 // SR with payload, type and id 152 assertEquals(new NdefMessage(new NdefRecord( 153 NdefRecord.TNF_WELL_KNOWN, new byte[] {8}, new byte[] {9}, new byte[] {1, 2, 3})), 154 new NdefMessage(new byte[] {(byte)0xD9, 1, 3, 1, 8, 9, 1, 2, 3})); 155 156 // payload, type and id 157 assertEquals(new NdefMessage(new NdefRecord( 158 NdefRecord.TNF_WELL_KNOWN, new byte[] {8}, new byte[] {9}, new byte[] {1, 2, 3})), 159 new NdefMessage(new byte[] {(byte)0xC9, 1, 0, 0, 0, 3, 1, 8, 9, 1, 2, 3})); 160 161 // 2 records 162 assertEquals(new NdefMessage( 163 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 164 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)), 165 new NdefMessage(new byte[] {(byte)0x90, 0, 0, (byte)0x50, 0, 0})); 166 167 // 3 records 168 assertEquals(new NdefMessage( 169 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 170 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 171 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)), 172 new NdefMessage(new byte[] {(byte)0x90, 0, 0, (byte)0x10, 0, 0, (byte)0x50, 0, 0})); 173 174 // chunked record (2 chunks) 175 assertEquals(new NdefMessage( 176 new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, new byte[] {1, 2})), 177 new NdefMessage(new byte[] {(byte)0xB5, 0, 1, 1, (byte)0x56, 0, 1, 2})); 178 179 // chunked record (3 chunks) 180 assertEquals(new NdefMessage(new NdefRecord( 181 NdefRecord.TNF_UNKNOWN, null, null, new byte[] {1, 2})), 182 new NdefMessage( 183 new byte[] {(byte)0xB5, 0, 0, (byte)0x36, 0, 1, 1, (byte)0x56, 0, 1, 2})); 184 185 // chunked with id and type 186 assertEquals(new NdefMessage(new NdefRecord( 187 NdefRecord.TNF_MIME_MEDIA, new byte[] {8}, new byte[] {9}, new byte[] {1, 2})), 188 new NdefMessage(new byte[] {(byte)0xBA, 1, 0, 1, 8, 9, (byte)0x36, 0, 1, 1, 189 (byte)0x56, 0, 1, 2})); 190 191 // 3 records, 7 chunks 192 assertEquals(new NdefMessage( 193 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, new byte[] {0x21}, null, new byte[] {1,2,3,4}), 194 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 195 new NdefRecord(NdefRecord.TNF_MIME_MEDIA, new byte[] {0x21}, null, new byte[] {11,12,13,14})), 196 new NdefMessage(new byte[] { 197 (byte)0xB4, 1, 1, (byte)0x21, 1, (byte)0x36, 0, 2, 2, 3, (byte)0x16, 0, 1, 4, 198 (byte)0x10, 0, 0, 199 (byte)0x32, 1, 2, (byte)0x21, 11, 12, (byte)0x36, 0, 1, 13, (byte)0x56, 0, 1, 14 200 })); 201 202 // 255 byte payload 203 assertEquals(new NdefMessage( 204 new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, new byte[] { 205 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 206 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 207 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 208 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 209 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 210 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 211 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 212 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7})), 213 new NdefMessage(new byte[] {(byte)0xC5, 0, 0, 0, 0, (byte)0xFF, 214 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 215 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 216 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 217 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 218 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 219 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 220 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 221 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7})); 222 223 // 256 byte payload 224 assertEquals(new NdefMessage( 225 new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, new byte[] { 226 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 227 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 228 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 229 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 230 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 231 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 232 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 233 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,})), 234 new NdefMessage(new byte[] {(byte)0xC5, 0, 0, 0, 1, 0, 235 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 236 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 237 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 238 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 239 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 240 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 241 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 242 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,})); 243 244 // 255 byte type 245 assertEquals(new NdefMessage( 246 new NdefRecord(NdefRecord.TNF_MIME_MEDIA, new byte[] { 247 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 248 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 249 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 250 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 251 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 252 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 253 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 254 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7}, 255 null, null)), 256 new NdefMessage(new byte[] {(byte)0xD2, (byte)0xFF, 0, 257 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 258 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 259 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 260 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 261 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 262 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 263 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 264 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,})); 265 266 // 255 byte id 267 assertEquals(new NdefMessage( 268 new NdefRecord(NdefRecord.TNF_MIME_MEDIA, null, new byte[] { 269 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 270 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 271 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 272 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 273 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 274 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 275 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 276 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7}, 277 null)), 278 new NdefMessage(new byte[] {(byte)0xDA, 0, 0, (byte)0xFF, 279 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 280 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 281 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 282 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 283 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 284 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 285 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 286 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,})); 287 // NdefRecord parsing ignores incorrect MB 288 assertEquals(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 289 new NdefRecord(new byte[] {(byte)0x50, 0, 0})); 290 291 // NdefRecord parsing ignores incorrect ME 292 assertEquals(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null), 293 new NdefRecord(new byte[] {(byte)0x90, 0, 0})); 294 295 // NdefRecord parsing can handle chunking with incorrect MB, ME 296 assertEquals(new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, new byte[] {1, 2}), 297 new NdefRecord(new byte[] {(byte)0x35, 0, 1, 1, (byte)0x16, 0, 1, 2})); 298 299 //A Smart Poster containing a URL and no text (nested NDEF Messages) */ 300 assertEquals(new NdefMessage(new NdefRecord( 301 NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_SMART_POSTER, null, 302 new NdefMessage(NdefRecord.createUri("http://www.google.com")).toByteArray())), 303 new NdefMessage(new byte[] { 304 (byte) 0xd1, (byte) 0x02, (byte) 0x0f, (byte) 0x53, (byte) 0x70, (byte) 0xd1, 305 (byte) 0x01, (byte) 0x0b, (byte) 0x55, (byte) 0x01, (byte) 0x67, (byte) 0x6f, 306 (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, 307 (byte) 0x6f, (byte) 0x6d})); 308 } 309 testCreateUri()310 public void testCreateUri() { 311 assertEquals(new byte[] { 312 (byte)0xD1, 1, 8, 'U', (byte)0x01, 'n', 'f', 'c', '.', 'c', 'o', 'm'}, 313 new NdefMessage( 314 NdefRecord.createUri(Uri.parse("http://www.nfc.com"))).toByteArray()); 315 316 assertEquals(new byte[] {(byte)0xD1, 1, 13, 'U', (byte)0x05, 317 '+', '3', '5', '8', '9', '1', '2', '3', '4', '5', '6', '7'}, 318 new NdefMessage(NdefRecord.createUri("tel:+35891234567")).toByteArray()); 319 320 assertEquals(new byte[] { 321 (byte)0xD1, 1, 4, 'U', (byte)0x00, 'f', 'o', 'o'}, 322 new NdefMessage(NdefRecord.createUri("foo")).toByteArray()); 323 324 // make sure UTF-8 encoding is used 325 assertEquals(new byte[] { 326 (byte)0xD1, 1, 3, 'U', (byte)0x00, (byte)0xC2, (byte)0xA2}, 327 new NdefMessage(NdefRecord.createUri("\u00A2")).toByteArray()); 328 } 329 testCreateMime()330 public void testCreateMime() { 331 assertEquals( 332 new NdefRecord(NdefRecord.TNF_MIME_MEDIA, "text/plain".getBytes(ASCII), null, 333 "foo".getBytes()), 334 NdefRecord.createMime("text/plain", "foo".getBytes())); 335 336 try { 337 NdefRecord.createMime("", null); 338 fail("IllegalArgumentException not throw"); 339 } catch (IllegalArgumentException e) { } 340 341 try { 342 NdefRecord.createMime("/", null); 343 fail("IllegalArgumentException not throw"); 344 } catch (IllegalArgumentException e) { } 345 346 try { 347 NdefRecord.createMime("a/", null); 348 fail("IllegalArgumentException not throw"); 349 } catch (IllegalArgumentException e) { } 350 351 try { 352 NdefRecord.createMime("/b", null); 353 fail("IllegalArgumentException not throw"); 354 } catch (IllegalArgumentException e) { } 355 356 // The following are valid MIME types and should not throw 357 NdefRecord.createMime("foo/bar", null); 358 NdefRecord.createMime(" ^@#/* ", null); 359 NdefRecord.createMime("text/plain; charset=us_ascii", null); 360 } 361 testCreateExternal()362 public void testCreateExternal() { 363 try { 364 NdefRecord.createExternal("", "c", null); 365 fail("IllegalArgumentException not throw"); 366 } catch (IllegalArgumentException e) { } 367 368 try { 369 NdefRecord.createExternal("a", "", null); 370 fail("IllegalArgumentException not throw"); 371 } catch (IllegalArgumentException e) { } 372 373 try { 374 NdefRecord.createExternal(" ", "c", null); 375 fail("IllegalArgumentException not throw"); 376 } catch (IllegalArgumentException e) { } 377 378 assertEquals( 379 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, "a.b:c".getBytes(ASCII), null, null), 380 NdefRecord.createExternal("a.b", "c", null)); 381 382 // test force lowercase 383 assertEquals( 384 new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, "a.b:c!".getBytes(ASCII), null, null), 385 NdefRecord.createExternal("A.b", "C!", null)); 386 } 387 testCreateApplicationRecord()388 public void testCreateApplicationRecord() throws FormatException { 389 NdefMessage m; 390 NdefRecord r; 391 392 // some failure cases 393 try { 394 NdefRecord.createApplicationRecord(null); 395 fail("NullPointerException not thrown"); 396 } catch (NullPointerException e) {} 397 try { 398 NdefRecord.createApplicationRecord(""); 399 fail("IllegalArgumentException not thrown"); 400 } catch (IllegalArgumentException e) {} 401 402 // create an AAR 403 r = NdefRecord.createApplicationRecord("com.foo.bar"); 404 assertEquals(new byte[] { 405 (byte)0xd4, (byte)0x0f, (byte)0x0b, (byte)0x61, 406 (byte)0x6e, (byte)0x64, (byte)0x72, (byte)0x6f, 407 (byte)0x69, (byte)0x64, (byte)0x2e, (byte)0x63, 408 (byte)0x6f, (byte)0x6d, (byte)0x3a, (byte)0x70, 409 (byte)0x6b, (byte)0x67, (byte)0x63, (byte)0x6f, 410 (byte)0x6d, (byte)0x2e, (byte)0x66, (byte)0x6f, 411 (byte)0x6f, (byte)0x2e, (byte)0x62, (byte)0x61, 412 (byte)0x72,}, 413 r.toByteArray()); 414 415 // parse an AAR 416 m = new NdefMessage(new byte[] { 417 (byte)0xd4, (byte)0x0f, (byte)0x0b, (byte)0x61, 418 (byte)0x6e, (byte)0x64, (byte)0x72, (byte)0x6f, 419 (byte)0x69, (byte)0x64, (byte)0x2e, (byte)0x63, 420 (byte)0x6f, (byte)0x6d, (byte)0x3a, (byte)0x70, 421 (byte)0x6b, (byte)0x67, (byte)0x63, (byte)0x6f, 422 (byte)0x6d, (byte)0x2e, (byte)0x66, (byte)0x6f, 423 (byte)0x6f, (byte)0x2e, (byte)0x62, (byte)0x61, 424 (byte)0x72}); 425 NdefRecord[] rs = m.getRecords(); 426 assertEquals(1, rs.length); 427 r = rs[0]; 428 assertEquals(NdefRecord.TNF_EXTERNAL_TYPE, r.getTnf()); 429 assertEquals("android.com:pkg".getBytes(), r.getType()); 430 assertEquals(new byte[] {}, r.getId()); 431 assertEquals("com.foo.bar".getBytes(), r.getPayload()); 432 } 433 testToByteArray()434 public void testToByteArray() throws FormatException { 435 NdefRecord r; 436 437 // single short record 438 assertEquals(new byte[] {(byte)0xD8, 0, 0, 0}, 439 new NdefMessage( 440 new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null)).toByteArray()); 441 442 // with id 443 assertEquals(new byte[] {(byte)0xDD, 0, 0, 1, 9}, 444 new NdefMessage(new NdefRecord( 445 NdefRecord.TNF_UNKNOWN, null, new byte[] {9}, null)).toByteArray()); 446 447 // with type 448 assertEquals(new byte[] {(byte)0xD4, 1, 0, 9}, 449 new NdefMessage(new NdefRecord( 450 NdefRecord.TNF_EXTERNAL_TYPE, new byte[] {9}, null, null)).toByteArray()); 451 452 // with payload 453 assertEquals(new byte[] {(byte)0xD5, 0, 1, 9}, 454 new NdefMessage(new NdefRecord( 455 NdefRecord.TNF_UNKNOWN, null, null, new byte[] {9})).toByteArray()); 456 457 // 3 records 458 r = new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null); 459 assertEquals(new byte[] {(byte)0x98, 0, 0, 0, (byte)0x18, 0, 0, 0, (byte)0x58, 0, 0, 0}, 460 new NdefMessage(r, r, r).toByteArray()); 461 462 // 256 byte payload 463 assertEquals(new byte[] {(byte)0xC5, 0, 0, 0, 1, 0, 464 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 465 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 466 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 467 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 468 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 469 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 470 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 471 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,}, 472 new NdefMessage(new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, new byte[] { 473 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 474 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 475 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 476 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 477 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 478 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 479 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8, 480 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,})).toByteArray()); 481 } 482 testToUri()483 public void testToUri() { 484 // absolute uri 485 assertEquals(Uri.parse("http://www.android.com"), 486 new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, 487 "http://www.android.com".getBytes(), null, null).toUri()); 488 // wkt uri 489 assertEquals(Uri.parse("http://www.android.com"), 490 NdefRecord.createUri("http://www.android.com").toUri()); 491 // smart poster with absolute uri 492 assertEquals(Uri.parse("http://www.android.com"), 493 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_SMART_POSTER, null, 494 new NdefMessage(new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, 495 "http://www.android.com".getBytes(), null, null)).toByteArray()).toUri()); 496 // smart poster with wkt uri 497 assertEquals(Uri.parse("http://www.android.com"), 498 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_SMART_POSTER, null, 499 new NdefMessage( 500 NdefRecord.createUri("http://www.android.com")).toByteArray()).toUri()); 501 // smart poster with text and wkt uri 502 assertEquals(Uri.parse("http://www.android.com"), 503 new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_SMART_POSTER, null, 504 new NdefMessage(new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, null, 505 null), NdefRecord.createUri("http://www.android.com")).toByteArray()).toUri()); 506 // external type 507 assertEquals(Uri.parse("vnd.android.nfc://ext/com.foo.bar:type"), 508 NdefRecord.createExternal("com.foo.bar", "type", null).toUri()); 509 // check normalization 510 assertEquals(Uri.parse("http://www.android.com"), 511 new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, "HTTP://www.android.com".getBytes(), 512 null, null).toUri()); 513 514 // not uri's 515 assertEquals(null, NdefRecord.createMime("text/plain", null).toUri()); 516 assertEquals(null, new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null).toUri()); 517 } 518 testToMimeType()519 public void testToMimeType() { 520 assertEquals(null, NdefRecord.createUri("http://www.android.com").toMimeType()); 521 assertEquals(null, new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null).toMimeType()); 522 assertEquals(null, NdefRecord.createExternal("com.foo.bar", "type", null).toMimeType()); 523 524 assertEquals("a/b", NdefRecord.createMime("a/b", null).toMimeType()); 525 assertEquals("text/plain", new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, 526 null, null).toMimeType()); 527 assertEquals("a/b", NdefRecord.createMime("A/B", null).toMimeType()); 528 assertEquals("a/b", new NdefRecord(NdefRecord.TNF_MIME_MEDIA, " A/B ".getBytes(), 529 null, null).toMimeType()); 530 } 531 assertEquals(byte[] expected, byte[] actual)532 static void assertEquals(byte[] expected, byte[] actual) { 533 assertTrue("expected equals:<" + bytesToString(expected) + "> was:<" + 534 bytesToString(actual) + ">", Arrays.equals(expected, actual)); 535 } 536 assertNotEquals(Object expected, Object actual)537 static void assertNotEquals(Object expected, Object actual) { 538 assertFalse("expected not equals:<" + expected + "> was:<" + actual + ">", 539 expected.equals(actual)); 540 } 541 bytesToString(byte[] bs)542 static String bytesToString(byte[] bs) { 543 StringBuilder s = new StringBuilder(); 544 for (byte b : bs) { 545 s.append(String.format("%02X ", b)); 546 } 547 return s.toString(); 548 } 549 } 550