• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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