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