• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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
onResume()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
onTagDiscovered(Tag tag)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
onItemSelected(AdapterView<?> parent, View view, int position, long id)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
onNothingSelected(AdapterView<?> parent)188     public void onNothingSelected(AdapterView<?> parent) {
189     }
190 }
191