WIP convert to service (not working)
[YkNeoCR.git] / src / org / average / nfcauthcr / Enroll.java
1 package org.average.nfcauthcr;
2
3 import java.util.Random;
4
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;
20
21 import org.average.nfcauthcr.Check;
22 import org.average.nfcauthcr.CheckConnector;
23
24 public class Enroll extends Activity {
25
26         private final String TAG = getClass().getName();
27
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];
36
37         private ServiceConnection mConnection = new ServiceConnection() {
38                 @Override
39                 public void onServiceConnected(ComponentName className,
40                                                 IBinder service) {
41                         checkConnector = (CheckConnector) service;
42                         checkConnector.setCaller(activity);
43                         mBound = true;
44                 }
45
46                 @Override
47                 public void onServiceDisconnected(ComponentName arg0) {
48                         mBound = false;
49                 }
50         };
51
52         @Override
53         protected void onCreate(Bundle savedInstanceState)
54         {
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);
60         }
61
62         @Override
63         protected void onResume() {
64                 super.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;
69                 switch (slot) {
70                 case 1: btn = (RadioButton)findViewById(R.id.slot_1);
71                         break;
72                 case 2: btn = (RadioButton)findViewById(R.id.slot_2);
73                         break;
74                 }
75                 if (btn != null) btn.setChecked(true);
76         }
77
78         @Override
79         protected void onPause() {
80                 super.onPause();
81                 Log.v(TAG, "Going inactive, try to stop");
82                 if (!waitingForResult) {
83                         finish();
84                 }
85         }
86
87         @Override
88         protected void onStop() {
89                 super.onStop();
90                 Log.v(TAG, "Stop requested");
91                 if (mBound) {
92                         unbindService(mConnection);
93                         mBound = false;
94                 }
95         }
96
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;
103                 }
104                 Editor editor = prefs.edit();
105                 editor.putInt("slot_number", slot);
106                 editor.commit();
107                 Log.v(TAG, "stored slot number " + slot);
108         }
109
110         public void onEnrollClicked(View view) {
111                 Log.v(TAG, "Enroll clicked");
112                 if (slot > 0) {
113                         runEnrollment();
114                 } else {
115                         showEnrollResult(R.string.need_slot);
116                 }
117         }
118
119         public void runCallback(int rc, byte[] response) {
120                 Log.v(TAG, "Got response");
121                 waitingForResult = false;
122                 if(swipeDialog != null) {
123                         swipeDialog.dismiss();
124                         swipeDialog = null;
125                 }
126                 if (rc != 0) {
127                         Log.v(TAG, "Error result code " + rc);
128                         return;
129                 }
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));
135                 editor.commit();
136                 showEnrollResult(R.string.enroll_success);
137                 Log.v(TAG, "stored new challenge and response");
138         }
139
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) {
147                                 dialog.dismiss();
148                                 if (!waitingForResult) { finish(); }
149                         }
150                 });
151                 AlertDialog dialog = builder.create();
152                 dialog.show();
153         }
154
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();
163                 swipeDialog.show();
164         }
165
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");
174                         }
175                 });
176                 return builder.create();
177         }
178
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();
184         }
185 }