1 package org.average.nfcauthcr;
3 import java.util.Random;
5 import android.os.Bundle;
6 import android.app.Activity;
7 import android.app.AlertDialog;
8 import android.content.Context;
9 import android.content.ComponentName;
10 import android.content.Intent;
11 import android.content.ServiceConnection;
12 import android.content.SharedPreferences;
13 import android.content.SharedPreferences.Editor;
14 import android.content.DialogInterface;
15 import android.preference.PreferenceManager;
16 import android.util.Log;
17 import android.view.View;
18 import android.widget.TextView;
19 import android.widget.RadioButton;
21 import org.average.nfcauthcr.Check;
22 import org.average.nfcauthcr.CheckConnector;
24 public class Enroll extends Activity {
26 private final String TAG = getClass().getName();
28 private Enroll thisActivity = this;
29 private static boolean waitingForResult = false;
30 private static SharedPreferences prefs;
31 private static int slot;
32 private AlertDialog swipeDialog;
33 private CheckConnector checkConnector;
34 private boolean mBound = false;
35 private byte[] challenge = new byte[63];
37 private ServiceConnection mConnection = new ServiceConnection() {
39 public void onServiceConnected(ComponentName className,
41 checkConnector = (CheckConnector) service;
42 checkConnector.setCaller(activity);
47 public void onServiceDisconnected(ComponentName arg0) {
53 protected void onCreate(Bundle savedInstanceState)
55 super.onCreate(savedInstanceState);
56 Log.v(TAG, "Starting");
57 prefs = PreferenceManager.getDefaultSharedPreferences(this);
58 Intent intent = new Intent(this, Check.class);
59 bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
63 protected void onResume() {
65 setContentView(R.layout.main);
66 slot = prefs.getInt("slot_number", -1);
67 Log.v(TAG, "found saved slot value " + slot);
68 RadioButton btn = null;
70 case 1: btn = (RadioButton)findViewById(R.id.slot_1);
72 case 2: btn = (RadioButton)findViewById(R.id.slot_2);
75 if (btn != null) btn.setChecked(true);
79 protected void onPause() {
81 Log.v(TAG, "Going inactive, try to stop");
82 if (!waitingForResult) {
88 protected void onStop() {
90 Log.v(TAG, "Stop requested");
92 unbindService(mConnection);
97 public void onSlotSelectionClicked(View view) {
98 Log.v(TAG, "Radio Button selected");
99 if (! ((RadioButton) view).isChecked()) return;
100 switch(view.getId()) {
101 case R.id.slot_1: slot=1; break;
102 case R.id.slot_2: slot=2; break;
104 Editor editor = prefs.edit();
105 editor.putInt("slot_number", slot);
107 Log.v(TAG, "stored slot number " + slot);
110 public void onEnrollClicked(View view) {
111 Log.v(TAG, "Enroll clicked");
115 showEnrollResult(R.string.need_slot);
119 public void runCallback(int rc, byte[] response) {
120 Log.v(TAG, "Got response");
121 waitingForResult = false;
122 if(swipeDialog != null) {
123 swipeDialog.dismiss();
127 Log.v(TAG, "Error result code " + rc);
130 Log.v(TAG, "Challenge is \"" + hex(challenge) + "\"");
131 Log.v(TAG, "Response is \"" + hex(response) + "\"");
132 Editor editor = prefs.edit();
133 editor.putString("challenge", hex(challenge));
134 editor.putString("response", hex(response));
136 showEnrollResult(R.string.enroll_success);
137 Log.v(TAG, "stored new challenge and response");
140 private void showEnrollResult(int messageid) {
141 AlertDialog.Builder builder = new AlertDialog.Builder(this);
142 builder.setTitle(R.string.enrollresult);
143 builder.setMessage(messageid);
144 builder.setPositiveButton(android.R.string.ok,
145 new DialogInterface.OnClickListener() {
146 public void onClick(DialogInterface dialog, int which) {
148 if (!waitingForResult) { finish(); }
151 AlertDialog dialog = builder.create();
155 private void runEnrollment() {
156 Random rng = new Random();
157 rng.nextBytes(challenge);
158 Log.v(TAG, "Random challenge: " + hex(challenge));
159 waitingForResult = true;
160 checkConnector.runEnroll(slot, challenge);
161 if (swipeDialog != null) swipeDialog.dismiss();
162 swipeDialog = makeDialog();
166 private AlertDialog makeDialog() {
167 AlertDialog.Builder builder = new AlertDialog.Builder(this);
168 builder.setTitle(R.string.challenging);
169 builder.setMessage(R.string.swipe);
170 builder.setOnCancelListener(
171 new DialogInterface.OnCancelListener() {
172 public void onCancel(DialogInterface dialog) {
173 Log.v(TAG, "unbind service FIXME");
176 return builder.create();
179 private String hex(byte[] a) {
180 StringBuilder sb = new StringBuilder();
181 if (a == null) return "<null>";
182 for (byte b: a) sb.append(String.format("%02x", b&0xff));
183 return sb.toString();