Home | History | Annotate | Download | only in hce
      1 package com.android.cts.verifier.nfc.hce;
      2 
      3 import android.annotation.TargetApi;
      4 import android.app.AlertDialog;
      5 import android.content.Intent;
      6 import android.content.SharedPreferences;
      7 import android.nfc.NfcAdapter;
      8 import android.nfc.NfcAdapter.ReaderCallback;
      9 import android.nfc.tech.IsoDep;
     10 import android.nfc.Tag;
     11 import android.os.Bundle;
     12 import android.os.Parcelable;
     13 import android.util.Log;
     14 import android.view.View;
     15 import android.widget.AdapterView;
     16 import android.widget.AdapterView.OnItemSelectedListener;
     17 import android.widget.ArrayAdapter;
     18 import android.widget.Spinner;
     19 import android.widget.TextView;
     20 
     21 import com.android.cts.verifier.PassFailButtons;
     22 import com.android.cts.verifier.R;
     23 
     24 import java.io.IOException;
     25 import java.util.Arrays;
     26 
     27 @TargetApi(19)
     28 public class SimpleReaderActivity extends PassFailButtons.Activity implements ReaderCallback,
     29         OnItemSelectedListener {
     30     public static final String PREFS_NAME = "HceTypePrefs";
     31 
     32     public static final String TAG = "SimpleReaderActivity";
     33     public static final String EXTRA_APDUS = "apdus";
     34     public static final String EXTRA_RESPONSES = "responses";
     35     public static final String EXTRA_LABEL = "label";
     36 
     37     NfcAdapter mAdapter;
     38     CommandApdu[] mApdus;
     39     String[] mResponses;
     40     String mLabel;
     41 
     42     TextView mTextView;
     43     Spinner mSpinner;
     44     SharedPreferences mPrefs;
     45 
     46     @Override
     47     protected void onCreate(Bundle savedInstanceState) {
     48         super.onCreate(savedInstanceState);
     49         setContentView(R.layout.nfc_hce_reader);
     50         setPassFailButtonClickListeners();
     51         getPassButton().setEnabled(false);
     52 
     53         mLabel = getIntent().getStringExtra(EXTRA_LABEL);
     54         setTitle(mLabel);
     55 
     56         mAdapter = NfcAdapter.getDefaultAdapter(this);
     57         mTextView = (TextView) findViewById(R.id.text);
     58         mTextView.setTextSize(12.0f);
     59         mTextView.setText(R.string.nfc_hce_type_selection);
     60 
     61         Spinner spinner = (Spinner) findViewById(R.id.type_ab_selection);
     62         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
     63                 R.array.nfc_types_array, android.R.layout.simple_spinner_item);
     64         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     65         spinner.setAdapter(adapter);
     66         spinner.setOnItemSelectedListener(this);
     67 
     68         mPrefs = getSharedPreferences(PREFS_NAME, 0);
     69         boolean isTypeB = mPrefs.getBoolean("typeB", false);
     70         if (isTypeB) {
     71             spinner.setSelection(1);
     72         }
     73     }
     74 
     75     @Override
     76     protected void onResume() {
     77         super.onResume();
     78         mAdapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A |
     79                 NfcAdapter.FLAG_READER_NFC_BARCODE | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
     80         Intent intent = getIntent();
     81         Parcelable[] apdus = intent.getParcelableArrayExtra(EXTRA_APDUS);
     82         if (apdus != null) {
     83 	        mApdus = new CommandApdu[apdus.length];
     84 	        for (int i = 0; i < apdus.length; i++) {
     85 	            mApdus[i] = (CommandApdu) apdus[i];
     86 	        }
     87         } else {
     88             mApdus = null;
     89         }
     90         mResponses = intent.getStringArrayExtra(EXTRA_RESPONSES);
     91     }
     92 
     93     @Override
     94     public void onTagDiscovered(Tag tag) {
     95         final StringBuilder sb = new StringBuilder();
     96         IsoDep isoDep = IsoDep.get(tag);
     97         if (isoDep == null) {
     98             // TODO dialog box
     99             return;
    100         }
    101 
    102         try {
    103             isoDep.connect();
    104             isoDep.setTimeout(5000);
    105             int count = 0;
    106             boolean success = true;
    107             long startTime = System.currentTimeMillis();
    108             for (CommandApdu apdu: mApdus) {
    109                 sb.append("Request APDU:\n");
    110                 sb.append(apdu.getApdu() + "\n\n");
    111                 long apduStartTime = System.currentTimeMillis();
    112                 byte[] response = isoDep.transceive(HceUtils.hexStringToBytes(apdu.getApdu()));
    113                 long apduEndTime = System.currentTimeMillis();
    114                 sb.append("Response APDU (in " + Long.toString(apduEndTime - apduStartTime) +
    115                         " ms):\n");
    116                 sb.append(HceUtils.getHexBytes(null, response));
    117 
    118                 sb.append("\n\n\n");
    119                 boolean wildCard = "*".equals(mResponses[count]);
    120                 byte[] expectedResponse = HceUtils.hexStringToBytes(mResponses[count]);
    121                 Log.d(TAG, HceUtils.getHexBytes("APDU response: ", response));
    122                 if (!wildCard && !Arrays.equals(response, expectedResponse)) {
    123                     Log.d(TAG, "Unexpected APDU response: " + HceUtils.getHexBytes("", response));
    124                     success = false;
    125                     break;
    126                 }
    127                 count++;
    128             }
    129             if (success) {
    130                 sb.insert(0, "Total APDU exchange time: " +
    131                         Long.toString(System.currentTimeMillis() - startTime) + " ms.\n\n");
    132                 runOnUiThread(new Runnable() {
    133                     @Override
    134                     public void run() {
    135                         mTextView.setText(sb.toString());
    136                         getPassButton().setEnabled(true);
    137                     }
    138                 });
    139             } else {
    140                 sb.insert(0, "FAIL. Total APDU exchange time: " +
    141                         Long.toString(System.currentTimeMillis() - startTime) + " ms.\n\n");
    142                 runOnUiThread(new Runnable() {
    143                     @Override
    144                     public void run() {
    145                         mTextView.setText(sb.toString());
    146                         AlertDialog.Builder builder = new AlertDialog.Builder(SimpleReaderActivity.this);
    147                         builder.setTitle("Test failed");
    148                         builder.setMessage("An unexpected response APDU was received, or no APDUs were received at all.");
    149                         builder.setPositiveButton("OK", null);
    150                         builder.show();
    151                     }
    152                 });
    153             }
    154         } catch (IOException e) {
    155             sb.insert(0, "Test failed. IOException (did you keep the devices in range?)\n\n.");
    156             runOnUiThread(new Runnable() {
    157                 @Override
    158                 public void run() {
    159                     mTextView.setText(sb.toString());
    160                 }
    161             });
    162         } finally {
    163         }
    164     }
    165 
    166     @Override
    167     public void onItemSelected(AdapterView<?> parent, View view, int position,
    168             long id) {
    169         if (position == 0) {
    170             // Type-A
    171             mAdapter.disableReaderMode(this);
    172             mAdapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_A |
    173                 NfcAdapter.FLAG_READER_NFC_BARCODE | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
    174             SharedPreferences.Editor editor = mPrefs.edit();
    175             editor.putBoolean("typeB", false);
    176             editor.commit();
    177         } else {
    178             // Type-B
    179             mAdapter.disableReaderMode(this);
    180             mAdapter.enableReaderMode(this, this, NfcAdapter.FLAG_READER_NFC_B |
    181                     NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
    182             SharedPreferences.Editor editor = mPrefs.edit();
    183             editor.putBoolean("typeB", true);
    184             editor.commit();
    185         }
    186     }
    187 
    188     @Override
    189     public void onNothingSelected(AdapterView<?> parent) {
    190     }
    191 
    192     @Override
    193     public String getTestId() {
    194         return mLabel;
    195     }
    196 }
    197