fix: don't close client sockets too early
[saartuer.git] / AndTuer / src / de / hacksaar / andtuer / DoorActivity.java
1 package de.hacksaar.andtuer;
2
3 import android.app.Activity;
4 import android.app.AlertDialog;
5 import android.app.Dialog;
6 import android.content.DialogInterface;
7 import android.content.Intent;
8 import android.content.SharedPreferences;
9 import android.os.Bundle;
10 import android.preference.PreferenceManager;
11 import android.text.InputType;
12 import android.util.Log;
13 import android.view.Menu;
14 import android.view.MenuItem;
15 import android.view.View;
16 import android.widget.EditText;
17 import android.widget.TextView;
18
19 public class DoorActivity extends Activity implements View.OnClickListener {
20
21         private static final String TAG = "DoorActivity";
22         private static final int DIALOG_BOOLEAN = 7;
23         private static final int DIALOG_STRING = 14;
24         private static final int TEXT_ID = 42;
25         private final AsyncTyshell.Prompter prompter = new DialogPrompter();
26         private TextView logText;
27         private AsyncTyshell task;
28         private String pendingMessage;
29
30         private Dialog askBooleanDialog() {
31                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
32                 builder.setTitle(null);
33                 builder.setMessage(pendingMessage);
34
35                 builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
36                         @Override
37                         public void onClick(DialogInterface dialog, int whichButton) {
38                                 assert task != null;
39                                 task.promptResult(true);
40                         }
41                 });
42
43                 builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
44                         @Override
45                         public void onClick(DialogInterface dialog, int which) {
46                                 assert task != null;
47                                 task.promptResult(false);
48                         }
49                 });
50
51                 return builder.create();
52         }
53
54         private Dialog askStringDialog() {
55                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
56                 builder.setTitle(null);
57                 builder.setMessage(pendingMessage);
58
59                 final EditText input = new EditText(this);
60                 input.setId(TEXT_ID);
61                 input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
62                 builder.setView(input);
63
64                 builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
65                         @Override
66                         public void onClick(DialogInterface dialog, int whichButton) {
67                                 assert task != null;
68                                 String value = input.getText().toString();
69                                 task.promptResult(value);
70                         }
71                 });
72
73                 builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
74                         @Override
75                         public void onClick(DialogInterface dialog, int whichButton) {
76                                 assert task != null;
77                                 task.promptResult(null);
78                         }
79                 });
80
81                 return builder.create();
82         }
83
84         private void onBuzzClick() {
85                 if (task != null) {
86                         task.sendCommand("buzz");
87                 }
88         }
89
90         @Override
91         public void onClick(View view) {
92                 switch (view.getId()) {
93                         case R.id.connect_button:
94                                 onConnectClick();
95                                 break;
96                         case R.id.buzz_button:
97                                 onBuzzClick();
98                                 break;
99                         case R.id.unlock_button:
100                                 onUnlockClick();
101                                 break;
102                         case R.id.disconnect_button:
103                                 onDisconnectClick();
104                                 break;
105                 }
106         }
107
108         private void onCloseClick() {
109                 if (task != null) {
110                         task.sendCommand("close");
111                 }
112         }
113
114         private void onConnectClick() {
115                 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
116                 task = new AsyncTyshell(preferences.getString(DoorSettings.PREF_SERVER_HOSTNAME, DoorSettings.DEFAULT_HOST),
117                                                                 preferences.getInt(DoorSettings.PREF_SERVER_PORT, DoorSettings.DEFAULT_PORT),
118                                                                 preferences.getString(DoorSettings.PREF_USER_USERNAME, null),
119                                                                 preferences.getString(DoorSettings.PREF_USER_KEYFILE, DoorSettings.DEFAULT_KEYFILE),
120                                                                 prompter);
121                 task.execute();
122                 findViewById(R.id.connect_button).setEnabled(false);
123         }
124
125         @Override
126         public void onCreate(Bundle savedInstanceState) {
127                 super.onCreate(savedInstanceState);
128                 setContentView(R.layout.door);
129                 for (int view : new int[]{R.id.unlock_button, R.id.buzz_button, R.id.disconnect_button, R.id.connect_button}) {
130                         findViewById(view).setOnClickListener(this);
131                 }
132                 logText = (TextView) findViewById(R.id.logout);
133                 try {
134                         logText.setText("Welcome to Hacksaar AndTuer, Version " +
135                                                         getPackageManager().getPackageInfo(getPackageName(), 0).versionName);
136                 } catch (Exception e) {
137                         logText.setText("Welcome to Hacksaar AndTuer, [unknown version]");
138                 }
139         }
140
141         @Override
142         protected Dialog onCreateDialog(int id) {
143                 switch (id) {
144                         case DIALOG_BOOLEAN:
145                                 return askBooleanDialog();
146                         case DIALOG_STRING:
147                                 return askStringDialog();
148                         default:
149                                 return super.onCreateDialog(id);
150                 }
151         }
152
153         @Override
154         public boolean onCreateOptionsMenu(Menu menu) {
155                 getMenuInflater().inflate(R.menu.main, menu);
156                 return super.onCreateOptionsMenu(menu);
157         }
158
159         private void onDisconnectClick() {
160                 if (task != null) {
161                         task.sendCommand("exit");
162                         task.disconnect();
163                 }
164                 findViewById(R.id.unlock_button).setEnabled(false);
165                 findViewById(R.id.buzz_button).setEnabled(false);
166                 findViewById(R.id.disconnect_button).setEnabled(false);
167                 findViewById(R.id.connect_button).setEnabled(true);
168         }
169
170         @Override
171         public boolean onMenuItemSelected(int featureId, MenuItem item) {
172                 switch (item.getItemId()) {
173                         case R.id.menu_settings:
174                                 startActivity(new Intent(this, DoorSettings.class));
175                                 return true;
176                         default:
177                                 return super.onMenuItemSelected(featureId, item);
178                 }
179         }
180
181         @Override
182         protected void onPrepareDialog(int id, Dialog dialog) {
183                 switch (id) {
184                         case DIALOG_STRING:
185                                 ((TextView) dialog.findViewById(TEXT_ID)).setText("");
186                         case DIALOG_BOOLEAN:
187                                 ((AlertDialog) dialog).setMessage(pendingMessage);
188                                 break;
189                         default:
190                                 super.onPrepareDialog(id, dialog);
191                 }
192
193         }
194
195         private void onUnlockClick() {
196                 if (task != null) {
197                         task.sendCommand("unlock");
198                 }
199         }
200
201         private void writeLog(String msg) {
202                 Log.d(TAG, "Log: " + msg);
203                 logText.setText(logText.getText() + "\n" + msg);
204
205                 findViewById(R.id.unlock_button).setEnabled(true);
206                 findViewById(R.id.buzz_button).setEnabled(true);
207                 findViewById(R.id.disconnect_button).setEnabled(true);
208         }
209
210         private class DialogPrompter implements AsyncTyshell.Prompter {
211                 DialogPrompter() {
212                 }
213
214                 @Override
215                 public void promptBoolean(String message) {
216                         pendingMessage = message;
217                         runOnUiThread(new Runnable() {
218                                 @Override
219                                 public void run() {
220                                         showDialog(DIALOG_BOOLEAN);
221                                 }
222                         });
223                 }
224
225                 @Override
226                 public void promptString(String message) {
227                         pendingMessage = message;
228                         runOnUiThread(new Runnable() {
229                                 @Override
230                                 public void run() {
231                                         showDialog(DIALOG_STRING);
232                                 }
233                         });
234                 }
235
236                 @Override
237                 public void sendMessage(final String message) {
238                         runOnUiThread(new Runnable() {
239                                 @Override
240                                 public void run() {
241                                         writeLog(message);
242                                 }
243                         });
244                 }
245         }
246 }