Home | History | Annotate | Download | only in tech
      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 com.android.cts.verifier.nfc.tech;
     18 
     19 import com.android.cts.verifier.R;
     20 
     21 import android.content.Context;
     22 import android.nfc.FormatException;
     23 import android.nfc.NdefMessage;
     24 import android.nfc.NdefRecord;
     25 import android.nfc.Tag;
     26 import android.nfc.tech.Ndef;
     27 import android.util.Log;
     28 
     29 import java.io.IOException;
     30 import java.nio.charset.Charset;
     31 import java.util.Random;
     32 
     33 /**
     34  * {@link TagTester} for NDEF tags. It writes a semi-random NDEF tag with a random id but
     35  * constant mime type and payload.
     36  */
     37 public class NdefTagTester implements TagTester {
     38 
     39     private static final String TAG = NdefTagTester.class.getSimpleName();
     40 
     41     private static final String MIME_TYPE = "application/com.android.cts.verifier.nfc";
     42 
     43     private static final String PAYLOAD = "CTS Verifier NDEF Tag";
     44 
     45     private final Context mContext;
     46 
     47     public NdefTagTester(Context context) {
     48         this.mContext = context;
     49     }
     50 
     51     @Override
     52     public boolean isTestableTag(Tag tag) {
     53         if (tag != null) {
     54             for (String tech : tag.getTechList()) {
     55                 if (tech.equals(Ndef.class.getName())) {
     56                     Ndef ndef = Ndef.get(tag);
     57                     return ndef != null && ndef.isWritable();
     58                 }
     59             }
     60         }
     61         return false;
     62     }
     63 
     64     @Override
     65     public TagVerifier writeTag(Tag tag) throws IOException, FormatException {
     66         Random random = new Random();
     67         NdefRecord mimeRecord = createRandomMimeRecord(random);
     68         NdefRecord[] expectedRecords = new NdefRecord[] {mimeRecord};
     69 
     70         final NdefMessage expectedMessage = new NdefMessage(expectedRecords);
     71         writeMessage(tag, expectedMessage);
     72 
     73         final String expectedContent = mContext.getString(R.string.nfc_ndef_content,
     74                 NfcUtils.displayByteArray(mimeRecord.getId()), MIME_TYPE, PAYLOAD);
     75 
     76         return new TagVerifier() {
     77             @Override
     78             public Result verifyTag(Tag tag) throws IOException, FormatException {
     79                 String actualContent;
     80                 NdefMessage message = readMessage(tag);
     81                 NdefRecord[] records = message.getRecords();
     82 
     83                 if (records.length > 0) {
     84                     NdefRecord record = records[0];
     85                     actualContent = mContext.getString(R.string.nfc_ndef_content,
     86                             NfcUtils.displayByteArray(record.getId()),
     87                             new String(record.getType(), Charset.forName("US-ASCII")),
     88                             new String(record.getPayload(), Charset.forName("US-ASCII")));
     89                 } else {
     90                     actualContent = null;
     91                 }
     92 
     93                 return new Result(expectedContent, actualContent,
     94                         NfcUtils.areMessagesEqual(message, expectedMessage));
     95             }
     96         };
     97     }
     98 
     99     private NdefRecord createRandomMimeRecord(Random random) {
    100         byte[] mimeBytes = MIME_TYPE.getBytes(Charset.forName("US-ASCII"));
    101         byte[] id = new byte[4];
    102         random.nextBytes(id);
    103         byte[] payload = PAYLOAD.getBytes(Charset.forName("US-ASCII"));
    104         return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, id, payload);
    105     }
    106 
    107     private void writeMessage(Tag tag, NdefMessage message) throws IOException, FormatException {
    108         Ndef ndef = null;
    109         try {
    110             ndef = Ndef.get(tag);
    111             ndef.connect();
    112             ndef.writeNdefMessage(message);
    113         } finally {
    114             if (ndef != null) {
    115                 try {
    116                     ndef.close();
    117                 } catch (IOException e) {
    118                     Log.e(TAG, "IOException while closing NDEF...", e);
    119                 }
    120             }
    121         }
    122     }
    123 
    124     private NdefMessage readMessage(Tag tag) throws IOException, FormatException {
    125         Ndef ndef = null;
    126         try {
    127             ndef = Ndef.get(tag);
    128             if (ndef != null) {
    129                 ndef.connect();
    130                 return ndef.getNdefMessage();
    131             }
    132         } finally {
    133             if (ndef != null) {
    134                 try {
    135                     ndef.close();
    136                 } catch (IOException e) {
    137                     Log.e(TAG, "Error closing Ndef...", e);
    138                 }
    139             }
    140         }
    141         return null;
    142     }
    143 }