Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: device/nfc/android/junit/src/org/chromium/device/nfc/NFCTest.java

Issue 2894373002: [DeviceService] Move //device/nfc to be part of the internal impl of Device Service (Closed)
Patch Set: Modify code comment Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/nfc/android/java/src/org/chromium/device/nfc/OWNERS ('k') | device/nfc/nfc.mojom » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.device.nfc;
6
7 import static org.junit.Assert.assertEquals;
8 import static org.junit.Assert.assertNotEquals;
9 import static org.junit.Assert.assertNotNull;
10 import static org.junit.Assert.assertNull;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.ArgumentMatchers.anyInt;
13 import static org.mockito.ArgumentMatchers.anyString;
14 import static org.mockito.ArgumentMatchers.isNull;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.doThrow;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.times;
20 import static org.mockito.Mockito.verify;
21
22 import android.app.Activity;
23 import android.content.Context;
24 import android.content.pm.PackageManager;
25 import android.nfc.FormatException;
26 import android.nfc.NdefMessage;
27 import android.nfc.NdefRecord;
28 import android.nfc.NfcAdapter;
29 import android.nfc.NfcAdapter.ReaderCallback;
30 import android.nfc.NfcManager;
31 import android.os.Bundle;
32
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.ArgumentCaptor;
37 import org.mockito.Captor;
38 import org.mockito.Mock;
39 import org.mockito.MockitoAnnotations;
40 import org.robolectric.annotation.Config;
41 import org.robolectric.shadows.ShadowLooper;
42
43 import org.chromium.base.Callback;
44 import org.chromium.base.test.util.Feature;
45 import org.chromium.device.nfc.mojom.Nfc.CancelAllWatchesResponse;
46 import org.chromium.device.nfc.mojom.Nfc.CancelPushResponse;
47 import org.chromium.device.nfc.mojom.Nfc.CancelWatchResponse;
48 import org.chromium.device.nfc.mojom.Nfc.PushResponse;
49 import org.chromium.device.nfc.mojom.Nfc.WatchResponse;
50 import org.chromium.device.nfc.mojom.NfcClient;
51 import org.chromium.device.nfc.mojom.NfcError;
52 import org.chromium.device.nfc.mojom.NfcErrorType;
53 import org.chromium.device.nfc.mojom.NfcMessage;
54 import org.chromium.device.nfc.mojom.NfcPushOptions;
55 import org.chromium.device.nfc.mojom.NfcPushTarget;
56 import org.chromium.device.nfc.mojom.NfcRecord;
57 import org.chromium.device.nfc.mojom.NfcRecordType;
58 import org.chromium.device.nfc.mojom.NfcRecordTypeFilter;
59 import org.chromium.device.nfc.mojom.NfcWatchMode;
60 import org.chromium.device.nfc.mojom.NfcWatchOptions;
61 import org.chromium.testing.local.LocalRobolectricTestRunner;
62
63 import java.io.IOException;
64 import java.io.UnsupportedEncodingException;
65
66 /**
67 * Unit tests for NfcImpl and NfcTypeConverter classes.
68 */
69 @RunWith(LocalRobolectricTestRunner.class)
70 @Config(manifest = Config.NONE)
71 public class NFCTest {
72 private TestNfcDelegate mDelegate;
73 @Mock
74 private Context mContext;
75 @Mock
76 private NfcManager mNfcManager;
77 @Mock
78 private NfcAdapter mNfcAdapter;
79 @Mock
80 private Activity mActivity;
81 @Mock
82 private NfcClient mNfcClient;
83 @Mock
84 private NfcTagHandler mNfcTagHandler;
85 @Captor
86 private ArgumentCaptor<NfcError> mErrorCaptor;
87 @Captor
88 private ArgumentCaptor<Integer> mWatchCaptor;
89 @Captor
90 private ArgumentCaptor<int[]> mOnWatchCallbackCaptor;
91
92 // Constants used for the test.
93 private static final String TEST_TEXT = "test";
94 private static final String TEST_URL = "https://google.com";
95 private static final String TEST_JSON = "{\"key1\":\"value1\",\"key2\":2}";
96 private static final String DOMAIN = "w3.org";
97 private static final String TYPE = "webnfc";
98 private static final String TEXT_MIME = "text/plain";
99 private static final String JSON_MIME = "application/json";
100 private static final String CHARSET_UTF8 = ";charset=UTF-8";
101 private static final String CHARSET_UTF16 = ";charset=UTF-16";
102 private static final String LANG_EN_US = "en-US";
103
104 /**
105 * Class that is used test NfcImpl implementation
106 */
107 private static class TestNfcImpl extends NfcImpl {
108 public TestNfcImpl(Context context, NfcDelegate delegate) {
109 super(context, 0, delegate);
110 }
111
112 public void processPendingOperationsForTesting(NfcTagHandler handler) {
113 super.processPendingOperations(handler);
114 }
115 }
116
117 private static class TestNfcDelegate implements NfcDelegate {
118 Activity mActivity;
119 Callback<Activity> mCallback;
120
121 public TestNfcDelegate(Activity activity) {
122 mActivity = activity;
123 }
124 public void trackActivityForHost(int hostId, Callback<Activity> callback ) {
125 mCallback = callback;
126 }
127
128 public void invokeCallback() {
129 mCallback.onResult(mActivity);
130 }
131
132 public void stopTrackingActivityForHost(int hostId) {}
133 }
134
135 @Before
136 public void setUp() {
137 MockitoAnnotations.initMocks(this);
138 mDelegate = new TestNfcDelegate(mActivity);
139 doReturn(mNfcManager).when(mContext).getSystemService(Context.NFC_SERVIC E);
140 doReturn(mNfcAdapter).when(mNfcManager).getDefaultAdapter();
141 doReturn(true).when(mNfcAdapter).isEnabled();
142 doReturn(PackageManager.PERMISSION_GRANTED)
143 .when(mContext)
144 .checkPermission(anyString(), anyInt(), anyInt());
145 doNothing()
146 .when(mNfcAdapter)
147 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
148 (Bundle) isNull());
149 doNothing().when(mNfcAdapter).disableReaderMode(any(Activity.class));
150 // Tag handler overrides used to mock connected tag.
151 doReturn(true).when(mNfcTagHandler).isConnected();
152 doReturn(false).when(mNfcTagHandler).isTagOutOfRange();
153 try {
154 doNothing().when(mNfcTagHandler).connect();
155 doNothing().when(mNfcTagHandler).write(any(NdefMessage.class));
156 doReturn(createUrlWebNFCNdefMessage()).when(mNfcTagHandler).read();
157 doNothing().when(mNfcTagHandler).close();
158 } catch (IOException | FormatException e) {
159 }
160 }
161
162 /**
163 * Test that error with type NOT_SUPPORTED is returned if NFC is not support ed.
164 */
165 @Test
166 @Feature({"NFCTest"})
167 public void testNFCNotSupported() {
168 doReturn(null).when(mNfcManager).getDefaultAdapter();
169 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
170 mDelegate.invokeCallback();
171 CancelAllWatchesResponse mockCallback = mock(CancelAllWatchesResponse.cl ass);
172 nfc.cancelAllWatches(mockCallback);
173 verify(mockCallback).call(mErrorCaptor.capture());
174 assertEquals(NfcErrorType.NOT_SUPPORTED, mErrorCaptor.getValue().errorTy pe);
175 }
176
177 /**
178 * Test that error with type SECURITY is returned if permission to use NFC i s not granted.
179 */
180 @Test
181 @Feature({"NFCTest"})
182 public void testNFCIsNotPermitted() {
183 doReturn(PackageManager.PERMISSION_DENIED)
184 .when(mContext)
185 .checkPermission(anyString(), anyInt(), anyInt());
186 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
187 CancelAllWatchesResponse mockCallback = mock(CancelAllWatchesResponse.cl ass);
188 nfc.cancelAllWatches(mockCallback);
189 verify(mockCallback).call(mErrorCaptor.capture());
190 assertEquals(NfcErrorType.SECURITY, mErrorCaptor.getValue().errorType);
191 }
192
193 /**
194 * Test that method can be invoked successfully if NFC is supported and adap ter is enabled.
195 */
196 @Test
197 @Feature({"NFCTest"})
198 public void testNFCIsSupported() {
199 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
200 mDelegate.invokeCallback();
201 WatchResponse mockCallback = mock(WatchResponse.class);
202 nfc.watch(createNfcWatchOptions(), mockCallback);
203 verify(mockCallback).call(anyInt(), mErrorCaptor.capture());
204 assertNull(mErrorCaptor.getValue());
205 }
206
207 /**
208 * Test conversion from NdefMessage to mojo NfcMessage.
209 */
210 @Test
211 @Feature({"NFCTest"})
212 public void testNdefToMojoConversion() throws UnsupportedEncodingException {
213 // Test EMPTY record conversion.
214 NdefMessage emptyNdefMessage =
215 new NdefMessage(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null));
216 NfcMessage emptyNfcMessage = NfcTypeConverter.toNfcMessage(emptyNdefMess age);
217 assertNull(emptyNfcMessage.url);
218 assertEquals(1, emptyNfcMessage.data.length);
219 assertEquals(NfcRecordType.EMPTY, emptyNfcMessage.data[0].recordType);
220 assertEquals(true, emptyNfcMessage.data[0].mediaType.isEmpty());
221 assertEquals(0, emptyNfcMessage.data[0].data.length);
222
223 // Test URL record conversion.
224 NdefMessage urlNdefMessage = new NdefMessage(NdefRecord.createUri(TEST_U RL));
225 NfcMessage urlNfcMessage = NfcTypeConverter.toNfcMessage(urlNdefMessage) ;
226 assertNull(urlNfcMessage.url);
227 assertEquals(1, urlNfcMessage.data.length);
228 assertEquals(NfcRecordType.URL, urlNfcMessage.data[0].recordType);
229 assertEquals(TEXT_MIME, urlNfcMessage.data[0].mediaType);
230 assertEquals(TEST_URL, new String(urlNfcMessage.data[0].data));
231
232 // Test TEXT record conversion.
233 NdefMessage textNdefMessage =
234 new NdefMessage(NdefRecord.createTextRecord(LANG_EN_US, TEST_TEX T));
235 NfcMessage textNfcMessage = NfcTypeConverter.toNfcMessage(textNdefMessag e);
236 assertNull(textNfcMessage.url);
237 assertEquals(1, textNfcMessage.data.length);
238 assertEquals(NfcRecordType.TEXT, textNfcMessage.data[0].recordType);
239 assertEquals(TEXT_MIME, textNfcMessage.data[0].mediaType);
240 assertEquals(TEST_TEXT, new String(textNfcMessage.data[0].data));
241
242 // Test MIME record conversion.
243 NdefMessage mimeNdefMessage =
244 new NdefMessage(NdefRecord.createMime(TEXT_MIME, TEST_TEXT.getBy tes()));
245 NfcMessage mimeNfcMessage = NfcTypeConverter.toNfcMessage(mimeNdefMessag e);
246 assertNull(mimeNfcMessage.url);
247 assertEquals(1, mimeNfcMessage.data.length);
248 assertEquals(NfcRecordType.OPAQUE_RECORD, mimeNfcMessage.data[0].recordT ype);
249 assertEquals(TEXT_MIME, textNfcMessage.data[0].mediaType);
250 assertEquals(TEST_TEXT, new String(textNfcMessage.data[0].data));
251
252 // Test JSON record conversion.
253 NdefMessage jsonNdefMessage =
254 new NdefMessage(NdefRecord.createMime(JSON_MIME, TEST_JSON.getBy tes()));
255 NfcMessage jsonNfcMessage = NfcTypeConverter.toNfcMessage(jsonNdefMessag e);
256 assertNull(jsonNfcMessage.url);
257 assertEquals(1, jsonNfcMessage.data.length);
258 assertEquals(NfcRecordType.JSON, jsonNfcMessage.data[0].recordType);
259 assertEquals(JSON_MIME, jsonNfcMessage.data[0].mediaType);
260 assertEquals(TEST_JSON, new String(jsonNfcMessage.data[0].data));
261
262 // Test NfcMessage with WebNFC external type.
263 NdefRecord jsonNdefRecord = NdefRecord.createMime(JSON_MIME, TEST_JSON.g etBytes());
264 NdefRecord extNdefRecord = NdefRecord.createExternal(DOMAIN, TYPE, TEST_ URL.getBytes());
265 NdefMessage webNdefMessage = new NdefMessage(jsonNdefRecord, extNdefReco rd);
266 NfcMessage webNfcMessage = NfcTypeConverter.toNfcMessage(webNdefMessage) ;
267 assertEquals(TEST_URL, webNfcMessage.url);
268 assertEquals(1, webNfcMessage.data.length);
269 assertEquals(NfcRecordType.JSON, webNfcMessage.data[0].recordType);
270 assertEquals(JSON_MIME, webNfcMessage.data[0].mediaType);
271 assertEquals(TEST_JSON, new String(webNfcMessage.data[0].data));
272 }
273
274 /**
275 * Test conversion from mojo NfcMessage to android NdefMessage.
276 */
277 @Test
278 @Feature({"NFCTest"})
279 public void testMojoToNdefConversion() throws InvalidNfcMessageException {
280 // Test URL record conversion.
281 NdefMessage urlNdefMessage = createUrlWebNFCNdefMessage();
282 assertEquals(2, urlNdefMessage.getRecords().length);
283 assertEquals(NdefRecord.TNF_WELL_KNOWN, urlNdefMessage.getRecords()[0].g etTnf());
284 assertEquals(TEST_URL, urlNdefMessage.getRecords()[0].toUri().toString() );
285 assertEquals(NdefRecord.TNF_EXTERNAL_TYPE, urlNdefMessage.getRecords()[1 ].getTnf());
286 assertEquals(DOMAIN + ":" + TYPE, new String(urlNdefMessage.getRecords() [1].getType()));
287
288 // Test TEXT record conversion.
289 NfcRecord textNfcRecord = new NfcRecord();
290 textNfcRecord.recordType = NfcRecordType.TEXT;
291 textNfcRecord.mediaType = TEXT_MIME;
292 textNfcRecord.data = TEST_TEXT.getBytes();
293 NfcMessage textNfcMessage = createNfcMessage(TEST_URL, textNfcRecord);
294 NdefMessage textNdefMessage = NfcTypeConverter.toNdefMessage(textNfcMess age);
295 assertEquals(2, textNdefMessage.getRecords().length);
296 short tnf = textNdefMessage.getRecords()[0].getTnf();
297 boolean isWellKnownOrMime =
298 (tnf == NdefRecord.TNF_WELL_KNOWN || tnf == NdefRecord.TNF_MIME_ MEDIA);
299 assertEquals(true, isWellKnownOrMime);
300 assertEquals(NdefRecord.TNF_EXTERNAL_TYPE, textNdefMessage.getRecords()[ 1].getTnf());
301
302 // Test MIME record conversion.
303 NfcRecord mimeNfcRecord = new NfcRecord();
304 mimeNfcRecord.recordType = NfcRecordType.OPAQUE_RECORD;
305 mimeNfcRecord.mediaType = TEXT_MIME;
306 mimeNfcRecord.data = TEST_TEXT.getBytes();
307 NfcMessage mimeNfcMessage = createNfcMessage(TEST_URL, mimeNfcRecord);
308 NdefMessage mimeNdefMessage = NfcTypeConverter.toNdefMessage(mimeNfcMess age);
309 assertEquals(2, mimeNdefMessage.getRecords().length);
310 assertEquals(NdefRecord.TNF_MIME_MEDIA, mimeNdefMessage.getRecords()[0]. getTnf());
311 assertEquals(TEXT_MIME, mimeNdefMessage.getRecords()[0].toMimeType());
312 assertEquals(TEST_TEXT, new String(mimeNdefMessage.getRecords()[0].getPa yload()));
313 assertEquals(NdefRecord.TNF_EXTERNAL_TYPE, mimeNdefMessage.getRecords()[ 1].getTnf());
314
315 // Test JSON record conversion.
316 NfcRecord jsonNfcRecord = new NfcRecord();
317 jsonNfcRecord.recordType = NfcRecordType.OPAQUE_RECORD;
318 jsonNfcRecord.mediaType = JSON_MIME;
319 jsonNfcRecord.data = TEST_JSON.getBytes();
320 NfcMessage jsonNfcMessage = createNfcMessage(TEST_URL, jsonNfcRecord);
321 NdefMessage jsonNdefMessage = NfcTypeConverter.toNdefMessage(jsonNfcMess age);
322 assertEquals(2, jsonNdefMessage.getRecords().length);
323 assertEquals(NdefRecord.TNF_MIME_MEDIA, jsonNdefMessage.getRecords()[0]. getTnf());
324 assertEquals(JSON_MIME, jsonNdefMessage.getRecords()[0].toMimeType());
325 assertEquals(TEST_JSON, new String(jsonNdefMessage.getRecords()[0].getPa yload()));
326 assertEquals(NdefRecord.TNF_EXTERNAL_TYPE, jsonNdefMessage.getRecords()[ 1].getTnf());
327 }
328
329 /**
330 * Test that invalid NfcMessage is rejected with INVALID_MESSAGE error code.
331 */
332 @Test
333 @Feature({"NFCTest"})
334 public void testInvalidNfcMessage() {
335 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
336 mDelegate.invokeCallback();
337 PushResponse mockCallback = mock(PushResponse.class);
338 nfc.push(new NfcMessage(), createNfcPushOptions(), mockCallback);
339 nfc.processPendingOperationsForTesting(mNfcTagHandler);
340 verify(mockCallback).call(mErrorCaptor.capture());
341 assertEquals(NfcErrorType.INVALID_MESSAGE, mErrorCaptor.getValue().error Type);
342 }
343
344 /**
345 * Test that Nfc.suspendNfcOperations() and Nfc.resumeNfcOperations() work c orrectly.
346 */
347 @Test
348 @Feature({"NFCTest"})
349 public void testResumeSuspend() {
350 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
351 // No activity / client or active pending operations
352 nfc.suspendNfcOperations();
353 nfc.resumeNfcOperations();
354
355 mDelegate.invokeCallback();
356 nfc.setClient(mNfcClient);
357 WatchResponse mockCallback = mock(WatchResponse.class);
358 nfc.watch(createNfcWatchOptions(), mockCallback);
359 nfc.suspendNfcOperations();
360 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
361 nfc.resumeNfcOperations();
362 // 1. Enable after watch is called, 2. after resumeNfcOperations is call ed.
363 verify(mNfcAdapter, times(2))
364 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
365 (Bundle) isNull());
366
367 nfc.processPendingOperationsForTesting(mNfcTagHandler);
368 // Check that watch request was completed successfully.
369 verify(mockCallback).call(mWatchCaptor.capture(), mErrorCaptor.capture() );
370 assertNull(mErrorCaptor.getValue());
371
372 // Check that client was notified and watch with correct id was triggere d.
373 verify(mNfcClient, times(1))
374 .onWatch(mOnWatchCallbackCaptor.capture(), any(NfcMessage.class) );
375 assertEquals(mWatchCaptor.getValue().intValue(), mOnWatchCallbackCaptor. getValue()[0]);
376 }
377
378 /**
379 * Test that Nfc.push() successful when NFC tag is connected.
380 */
381 @Test
382 @Feature({"NFCTest"})
383 public void testPush() {
384 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
385 mDelegate.invokeCallback();
386 PushResponse mockCallback = mock(PushResponse.class);
387 nfc.push(createNfcMessage(), createNfcPushOptions(), mockCallback);
388 nfc.processPendingOperationsForTesting(mNfcTagHandler);
389 verify(mockCallback).call(mErrorCaptor.capture());
390 assertNull(mErrorCaptor.getValue());
391 }
392
393 /**
394 * Test that Nfc.cancelPush() cancels pending push opration and completes su ccessfully.
395 */
396 @Test
397 @Feature({"NFCTest"})
398 public void testCancelPush() {
399 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
400 mDelegate.invokeCallback();
401 PushResponse mockPushCallback = mock(PushResponse.class);
402 CancelPushResponse mockCancelPushCallback = mock(CancelPushResponse.clas s);
403 nfc.push(createNfcMessage(), createNfcPushOptions(), mockPushCallback);
404 nfc.cancelPush(NfcPushTarget.ANY, mockCancelPushCallback);
405
406 // Check that push request was cancelled with OPERATION_CANCELLED.
407 verify(mockPushCallback).call(mErrorCaptor.capture());
408 assertEquals(NfcErrorType.OPERATION_CANCELLED, mErrorCaptor.getValue().e rrorType);
409
410 // Check that cancel request was successfuly completed.
411 verify(mockCancelPushCallback).call(mErrorCaptor.capture());
412 assertNull(mErrorCaptor.getValue());
413 }
414
415 /**
416 * Test that Nfc.watch() works correctly and client is notified.
417 */
418 @Test
419 @Feature({"NFCTest"})
420 public void testWatch() {
421 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
422 mDelegate.invokeCallback();
423 nfc.setClient(mNfcClient);
424 WatchResponse mockWatchCallback1 = mock(WatchResponse.class);
425 nfc.watch(createNfcWatchOptions(), mockWatchCallback1);
426
427 // Check that watch requests were completed successfully.
428 verify(mockWatchCallback1).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
429 assertNull(mErrorCaptor.getValue());
430 int watchId1 = mWatchCaptor.getValue().intValue();
431
432 WatchResponse mockWatchCallback2 = mock(WatchResponse.class);
433 nfc.watch(createNfcWatchOptions(), mockWatchCallback2);
434 verify(mockWatchCallback2).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
435 assertNull(mErrorCaptor.getValue());
436 int watchId2 = mWatchCaptor.getValue().intValue();
437 // Check that each watch operation is associated with unique id.
438 assertNotEquals(watchId1, watchId2);
439
440 // Mocks 'NFC tag found' event.
441 nfc.processPendingOperationsForTesting(mNfcTagHandler);
442
443 // Check that client was notified and correct watch ids were provided.
444 verify(mNfcClient, times(1))
445 .onWatch(mOnWatchCallbackCaptor.capture(), any(NfcMessage.class) );
446 assertEquals(watchId1, mOnWatchCallbackCaptor.getValue()[0]);
447 assertEquals(watchId2, mOnWatchCallbackCaptor.getValue()[1]);
448 }
449
450 /**
451 * Test that Nfc.watch() matching function works correctly.
452 */
453 @Test
454 @Feature({"NFCTest"})
455 public void testlWatchMatching() {
456 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
457 mDelegate.invokeCallback();
458 nfc.setClient(mNfcClient);
459
460 // Should match by WebNFC Id.
461 NfcWatchOptions options1 = createNfcWatchOptions();
462 options1.mode = NfcWatchMode.WEBNFC_ONLY;
463 options1.url = TEST_URL;
464 WatchResponse mockWatchCallback1 = mock(WatchResponse.class);
465 nfc.watch(options1, mockWatchCallback1);
466 verify(mockWatchCallback1).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
467 assertNull(mErrorCaptor.getValue());
468 int watchId1 = mWatchCaptor.getValue().intValue();
469
470 // Should match by media type.
471 NfcWatchOptions options2 = createNfcWatchOptions();
472 options2.mode = NfcWatchMode.ANY;
473 options2.mediaType = TEXT_MIME;
474 WatchResponse mockWatchCallback2 = mock(WatchResponse.class);
475 nfc.watch(options2, mockWatchCallback2);
476 verify(mockWatchCallback2).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
477 assertNull(mErrorCaptor.getValue());
478 int watchId2 = mWatchCaptor.getValue().intValue();
479
480 // Should match by record type.
481 NfcWatchOptions options3 = createNfcWatchOptions();
482 options3.mode = NfcWatchMode.ANY;
483 NfcRecordTypeFilter typeFilter = new NfcRecordTypeFilter();
484 typeFilter.recordType = NfcRecordType.URL;
485 options3.recordFilter = typeFilter;
486 WatchResponse mockWatchCallback3 = mock(WatchResponse.class);
487 nfc.watch(options3, mockWatchCallback3);
488 verify(mockWatchCallback3).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
489 assertNull(mErrorCaptor.getValue());
490 int watchId3 = mWatchCaptor.getValue().intValue();
491
492 // Should not match
493 NfcWatchOptions options4 = createNfcWatchOptions();
494 options4.mode = NfcWatchMode.WEBNFC_ONLY;
495 options4.url = DOMAIN;
496 WatchResponse mockWatchCallback4 = mock(WatchResponse.class);
497 nfc.watch(options4, mockWatchCallback4);
498 verify(mockWatchCallback4).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
499 assertNull(mErrorCaptor.getValue());
500 int watchId4 = mWatchCaptor.getValue().intValue();
501
502 nfc.processPendingOperationsForTesting(mNfcTagHandler);
503
504 // Check that client was notified and watch with correct id was triggere d.
505 verify(mNfcClient, times(1))
506 .onWatch(mOnWatchCallbackCaptor.capture(), any(NfcMessage.class) );
507 assertEquals(3, mOnWatchCallbackCaptor.getValue().length);
508 assertEquals(watchId1, mOnWatchCallbackCaptor.getValue()[0]);
509 assertEquals(watchId2, mOnWatchCallbackCaptor.getValue()[1]);
510 assertEquals(watchId3, mOnWatchCallbackCaptor.getValue()[2]);
511 }
512
513 /**
514 * Test that Nfc.watch() can be cancelled with Nfc.cancelWatch().
515 */
516 @Test
517 @Feature({"NFCTest"})
518 public void testCancelWatch() {
519 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
520 mDelegate.invokeCallback();
521 WatchResponse mockWatchCallback = mock(WatchResponse.class);
522 nfc.watch(createNfcWatchOptions(), mockWatchCallback);
523
524 verify(mockWatchCallback).call(mWatchCaptor.capture(), mErrorCaptor.capt ure());
525 assertNull(mErrorCaptor.getValue());
526
527 CancelWatchResponse mockCancelWatchCallback = mock(CancelWatchResponse.c lass);
528 nfc.cancelWatch(mWatchCaptor.getValue().intValue(), mockCancelWatchCallb ack);
529
530 // Check that cancel request was successfuly completed.
531 verify(mockCancelWatchCallback).call(mErrorCaptor.capture());
532 assertNull(mErrorCaptor.getValue());
533
534 // Check that watch is not triggered when NFC tag is in proximity.
535 nfc.processPendingOperationsForTesting(mNfcTagHandler);
536 verify(mNfcClient, times(0)).onWatch(any(int[].class), any(NfcMessage.cl ass));
537 }
538
539 /**
540 * Test that Nfc.cancelAllWatches() cancels all pending watch operations.
541 */
542 @Test
543 @Feature({"NFCTest"})
544 public void testCancelAllWatches() {
545 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
546 mDelegate.invokeCallback();
547 WatchResponse mockWatchCallback1 = mock(WatchResponse.class);
548 WatchResponse mockWatchCallback2 = mock(WatchResponse.class);
549 nfc.watch(createNfcWatchOptions(), mockWatchCallback1);
550 verify(mockWatchCallback1).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
551 assertNull(mErrorCaptor.getValue());
552
553 nfc.watch(createNfcWatchOptions(), mockWatchCallback2);
554 verify(mockWatchCallback2).call(mWatchCaptor.capture(), mErrorCaptor.cap ture());
555 assertNull(mErrorCaptor.getValue());
556
557 CancelAllWatchesResponse mockCallback = mock(CancelAllWatchesResponse.cl ass);
558 nfc.cancelAllWatches(mockCallback);
559
560 // Check that cancel request was successfuly completed.
561 verify(mockCallback).call(mErrorCaptor.capture());
562 assertNull(mErrorCaptor.getValue());
563 }
564
565 /**
566 * Test that Nfc.cancelWatch() with invalid id is failing with NOT_FOUND err or.
567 */
568 @Test
569 @Feature({"NFCTest"})
570 public void testCancelWatchInvalidId() {
571 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
572 mDelegate.invokeCallback();
573 WatchResponse mockWatchCallback = mock(WatchResponse.class);
574 nfc.watch(createNfcWatchOptions(), mockWatchCallback);
575
576 verify(mockWatchCallback).call(mWatchCaptor.capture(), mErrorCaptor.capt ure());
577 assertNull(mErrorCaptor.getValue());
578
579 CancelWatchResponse mockCancelWatchCallback = mock(CancelWatchResponse.c lass);
580 nfc.cancelWatch(mWatchCaptor.getValue().intValue() + 1, mockCancelWatchC allback);
581
582 verify(mockCancelWatchCallback).call(mErrorCaptor.capture());
583 assertEquals(NfcErrorType.NOT_FOUND, mErrorCaptor.getValue().errorType);
584 }
585
586 /**
587 * Test that Nfc.cancelAllWatches() is failing with NOT_FOUND error if there are no active
588 * watch opeartions.
589 */
590 @Test
591 @Feature({"NFCTest"})
592 public void testCancelAllWatchesWithNoWathcers() {
593 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
594 mDelegate.invokeCallback();
595 CancelAllWatchesResponse mockCallback = mock(CancelAllWatchesResponse.cl ass);
596 nfc.cancelAllWatches(mockCallback);
597
598 verify(mockCallback).call(mErrorCaptor.capture());
599 assertEquals(NfcErrorType.NOT_FOUND, mErrorCaptor.getValue().errorType);
600 }
601
602 /**
603 * Test that when tag is disconnected during read operation, IllegalStateExc eption is handled.
604 */
605 @Test
606 @Feature({"NFCTest"})
607 public void testTagDisconnectedDuringRead() throws IOException, FormatExcept ion {
608 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
609 mDelegate.invokeCallback();
610 nfc.setClient(mNfcClient);
611 WatchResponse mockWatchCallback = mock(WatchResponse.class);
612 nfc.watch(createNfcWatchOptions(), mockWatchCallback);
613
614 // Force read operation to fail
615 doThrow(IllegalStateException.class).when(mNfcTagHandler).read();
616
617 // Mocks 'NFC tag found' event.
618 nfc.processPendingOperationsForTesting(mNfcTagHandler);
619
620 // Check that client was not notified.
621 verify(mNfcClient, times(0))
622 .onWatch(mOnWatchCallbackCaptor.capture(), any(NfcMessage.class) );
623 }
624
625 /**
626 * Test that when tag is disconnected during write operation, IllegalStateEx ception is handled.
627 */
628 @Test
629 @Feature({"NFCTest"})
630 public void testTagDisconnectedDuringWrite() throws IOException, FormatExcep tion {
631 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
632 mDelegate.invokeCallback();
633 PushResponse mockCallback = mock(PushResponse.class);
634
635 // Force write operation to fail
636 doThrow(IllegalStateException.class).when(mNfcTagHandler).write(any(Ndef Message.class));
637 nfc.push(createNfcMessage(), createNfcPushOptions(), mockCallback);
638 nfc.processPendingOperationsForTesting(mNfcTagHandler);
639 verify(mockCallback).call(mErrorCaptor.capture());
640
641 // Test that correct error is returned.
642 assertNotNull(mErrorCaptor.getValue());
643 assertEquals(NfcErrorType.IO_ERROR, mErrorCaptor.getValue().errorType);
644 }
645
646 /**
647 * Test that push operation completes with TIMER_EXPIRED error when operatio n times-out.
648 */
649 @Test
650 @Feature({"NFCTest"})
651 public void testPushTimeout() {
652 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
653 mDelegate.invokeCallback();
654 PushResponse mockCallback = mock(PushResponse.class);
655
656 // Set 1 millisecond timeout.
657 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockCallback);
658
659 // Wait for timeout.
660 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
661
662 // Test that correct error is returned.
663 verify(mockCallback).call(mErrorCaptor.capture());
664 assertNotNull(mErrorCaptor.getValue());
665 assertEquals(NfcErrorType.TIMER_EXPIRED, mErrorCaptor.getValue().errorTy pe);
666 }
667
668 /**
669 * Test that multiple Nfc.push() invocations do not disable reader mode.
670 */
671 @Test
672 @Feature({"NFCTest"})
673 public void testPushMultipleInvocations() {
674 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
675 mDelegate.invokeCallback();
676
677 PushResponse mockCallback1 = mock(PushResponse.class);
678 PushResponse mockCallback2 = mock(PushResponse.class);
679 nfc.push(createNfcMessage(), createNfcPushOptions(), mockCallback1);
680 nfc.push(createNfcMessage(), createNfcPushOptions(), mockCallback2);
681
682 verify(mNfcAdapter, times(1))
683 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
684 (Bundle) isNull());
685 verify(mNfcAdapter, times(0)).disableReaderMode(mActivity);
686
687 verify(mockCallback1).call(mErrorCaptor.capture());
688 assertNotNull(mErrorCaptor.getValue());
689 assertEquals(NfcErrorType.OPERATION_CANCELLED, mErrorCaptor.getValue().e rrorType);
690 }
691
692 /**
693 * Test that reader mode is disabled after push operation timeout is expired .
694 */
695 @Test
696 @Feature({"NFCTest"})
697 public void testReaderModeIsDisabledAfterTimeout() {
698 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
699 mDelegate.invokeCallback();
700 PushResponse mockCallback = mock(PushResponse.class);
701
702 // Set 1 millisecond timeout.
703 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockCallback);
704
705 verify(mNfcAdapter, times(1))
706 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
707 (Bundle) isNull());
708
709 // Wait for timeout.
710 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
711
712 // Reader mode is disabled
713 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
714
715 // Test that correct error is returned.
716 verify(mockCallback).call(mErrorCaptor.capture());
717 assertNotNull(mErrorCaptor.getValue());
718 assertEquals(NfcErrorType.TIMER_EXPIRED, mErrorCaptor.getValue().errorTy pe);
719 }
720
721 /**
722 * Test that reader mode is disabled and two push operations are cancelled w ith correct
723 * error code.
724 */
725 @Test
726 @Feature({"NFCTest"})
727 public void testTwoPushInvocationsWithCancel() {
728 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
729 mDelegate.invokeCallback();
730
731 PushResponse mockCallback1 = mock(PushResponse.class);
732
733 // First push without timeout, must be completed with OPERATION_CANCELLE D.
734 nfc.push(createNfcMessage(), createNfcPushOptions(), mockCallback1);
735
736 PushResponse mockCallback2 = mock(PushResponse.class);
737
738 // Second push with 1 millisecond timeout, should be cancelled before ti mer expires,
739 // thus, operation must be completed with OPERATION_CANCELLED.
740 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockCallback2);
741
742 verify(mNfcAdapter, times(1))
743 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
744 (Bundle) isNull());
745 verify(mockCallback1).call(mErrorCaptor.capture());
746 assertNotNull(mErrorCaptor.getValue());
747 assertEquals(NfcErrorType.OPERATION_CANCELLED, mErrorCaptor.getValue().e rrorType);
748
749 CancelPushResponse mockCancelPushCallback = mock(CancelPushResponse.clas s);
750 nfc.cancelPush(NfcPushTarget.ANY, mockCancelPushCallback);
751
752 // Reader mode is disabled after cancelPush is invoked.
753 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
754
755 // Wait for delayed tasks to complete.
756 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
757
758 // The disableReaderMode is not called after delayed tasks are processed .
759 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
760
761 // Test that correct error is returned.
762 verify(mockCallback2).call(mErrorCaptor.capture());
763 assertNotNull(mErrorCaptor.getValue());
764 assertEquals(NfcErrorType.OPERATION_CANCELLED, mErrorCaptor.getValue().e rrorType);
765 }
766
767 /**
768 * Test that reader mode is disabled and two push operations with timeout ar e cancelled
769 * with correct error codes.
770 */
771 @Test
772 @Feature({"NFCTest"})
773 public void testTwoPushInvocationsWithTimeout() {
774 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
775 mDelegate.invokeCallback();
776
777 PushResponse mockCallback1 = mock(PushResponse.class);
778
779 // First push without timeout, must be completed with OPERATION_CANCELLE D.
780 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockCallback1);
781
782 PushResponse mockCallback2 = mock(PushResponse.class);
783
784 // Second push with 1 millisecond timeout, should be cancelled with TIME R_EXPIRED.
785 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockCallback2);
786
787 verify(mNfcAdapter, times(1))
788 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
789 (Bundle) isNull());
790
791 // Reader mode enabled for the duration of timeout.
792 verify(mNfcAdapter, times(0)).disableReaderMode(mActivity);
793
794 verify(mockCallback1).call(mErrorCaptor.capture());
795 assertNotNull(mErrorCaptor.getValue());
796 assertEquals(NfcErrorType.OPERATION_CANCELLED, mErrorCaptor.getValue().e rrorType);
797
798 // Wait for delayed tasks to complete.
799 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
800
801 // Reader mode is disabled
802 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
803
804 // Test that correct error is returned for second push.
805 verify(mockCallback2).call(mErrorCaptor.capture());
806 assertNotNull(mErrorCaptor.getValue());
807 assertEquals(NfcErrorType.TIMER_EXPIRED, mErrorCaptor.getValue().errorTy pe);
808 }
809
810 /**
811 * Test that reader mode is not disabled when there is an active watch opera tion and push
812 * operation timer is expired.
813 */
814 @Test
815 @Feature({"NFCTest"})
816 public void testTimeoutDontDisableReaderMode() {
817 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
818 mDelegate.invokeCallback();
819 WatchResponse mockWatchCallback = mock(WatchResponse.class);
820 nfc.watch(createNfcWatchOptions(), mockWatchCallback);
821
822 PushResponse mockPushCallback = mock(PushResponse.class);
823 // Should be cancelled with TIMER_EXPIRED.
824 nfc.push(createNfcMessage(), createNfcPushOptions(1), mockPushCallback);
825
826 verify(mNfcAdapter, times(1))
827 .enableReaderMode(any(Activity.class), any(ReaderCallback.class) , anyInt(),
828 (Bundle) isNull());
829
830 // Wait for delayed tasks to complete.
831 ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
832
833 // Push was cancelled with TIMER_EXPIRED.
834 verify(mockPushCallback).call(mErrorCaptor.capture());
835 assertNotNull(mErrorCaptor.getValue());
836 assertEquals(NfcErrorType.TIMER_EXPIRED, mErrorCaptor.getValue().errorTy pe);
837
838 verify(mNfcAdapter, times(0)).disableReaderMode(mActivity);
839
840 CancelAllWatchesResponse mockCancelCallback = mock(CancelAllWatchesRespo nse.class);
841 nfc.cancelAllWatches(mockCancelCallback);
842
843 // Check that cancel request was successfuly completed.
844 verify(mockCancelCallback).call(mErrorCaptor.capture());
845 assertNull(mErrorCaptor.getValue());
846
847 // Reader mode is disabled when there are no pending push / watch operat ions.
848 verify(mNfcAdapter, times(1)).disableReaderMode(mActivity);
849 }
850
851 /**
852 * Test timeout overflow and negative timeout
853 */
854 @Test
855 @Feature({"NFCTest"})
856 public void testInvalidPushOptions() {
857 TestNfcImpl nfc = new TestNfcImpl(mContext, mDelegate);
858 mDelegate.invokeCallback();
859 PushResponse mockCallback = mock(PushResponse.class);
860
861 // Long overflow
862 nfc.push(createNfcMessage(), createNfcPushOptions(Long.MAX_VALUE + 1), m ockCallback);
863
864 verify(mockCallback).call(mErrorCaptor.capture());
865 assertNotNull(mErrorCaptor.getValue());
866 assertEquals(NfcErrorType.NOT_SUPPORTED, mErrorCaptor.getValue().errorTy pe);
867
868 // Test negative timeout
869 PushResponse mockCallback2 = mock(PushResponse.class);
870 nfc.push(createNfcMessage(), createNfcPushOptions(-1), mockCallback2);
871
872 verify(mockCallback2).call(mErrorCaptor.capture());
873 assertNotNull(mErrorCaptor.getValue());
874 assertEquals(NfcErrorType.NOT_SUPPORTED, mErrorCaptor.getValue().errorTy pe);
875 }
876
877 /**
878 * Creates NfcPushOptions with default values.
879 */
880 private NfcPushOptions createNfcPushOptions() {
881 NfcPushOptions pushOptions = new NfcPushOptions();
882 pushOptions.target = NfcPushTarget.ANY;
883 pushOptions.timeout = Double.POSITIVE_INFINITY;
884 pushOptions.ignoreRead = false;
885 return pushOptions;
886 }
887
888 /**
889 * Creates NfcPushOptions with specified timeout.
890 */
891 private NfcPushOptions createNfcPushOptions(double timeout) {
892 NfcPushOptions pushOptions = new NfcPushOptions();
893 pushOptions.target = NfcPushTarget.ANY;
894 pushOptions.timeout = timeout;
895 pushOptions.ignoreRead = false;
896 return pushOptions;
897 }
898
899 private NfcWatchOptions createNfcWatchOptions() {
900 NfcWatchOptions options = new NfcWatchOptions();
901 options.url = "";
902 options.mediaType = "";
903 options.mode = NfcWatchMode.ANY;
904 options.recordFilter = null;
905 return options;
906 }
907
908 private NfcMessage createNfcMessage() {
909 NfcMessage message = new NfcMessage();
910 message.url = "";
911 message.data = new NfcRecord[1];
912
913 NfcRecord nfcRecord = new NfcRecord();
914 nfcRecord.recordType = NfcRecordType.TEXT;
915 nfcRecord.mediaType = TEXT_MIME;
916 nfcRecord.data = TEST_TEXT.getBytes();
917 message.data[0] = nfcRecord;
918 return message;
919 }
920
921 private NfcMessage createNfcMessage(String url, NfcRecord record) {
922 NfcMessage message = new NfcMessage();
923 message.url = url;
924 message.data = new NfcRecord[1];
925 message.data[0] = record;
926 return message;
927 }
928
929 private NdefMessage createUrlWebNFCNdefMessage() {
930 NfcRecord urlNfcRecord = new NfcRecord();
931 urlNfcRecord.recordType = NfcRecordType.URL;
932 urlNfcRecord.mediaType = TEXT_MIME;
933 urlNfcRecord.data = TEST_URL.getBytes();
934 NfcMessage urlNfcMessage = createNfcMessage(TEST_URL, urlNfcRecord);
935 try {
936 return NfcTypeConverter.toNdefMessage(urlNfcMessage);
937 } catch (InvalidNfcMessageException e) {
938 return null;
939 }
940 }
941 }
OLDNEW
« no previous file with comments | « device/nfc/android/java/src/org/chromium/device/nfc/OWNERS ('k') | device/nfc/nfc.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698