Remove certificate spinner from edit view
[strongswan.git] / src / frontends / android / src / org / strongswan / android / ui / VpnProfileDetailActivity.java
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 package org.strongswan.android.ui;
19
20 import org.strongswan.android.R;
21 import org.strongswan.android.data.VpnProfile;
22 import org.strongswan.android.data.VpnProfileDataSource;
23 import org.strongswan.android.logic.TrustedCertificateManager;
24
25 import android.app.Activity;
26 import android.app.AlertDialog;
27 import android.content.DialogInterface;
28 import android.content.Intent;
29 import android.os.AsyncTask;
30 import android.os.Bundle;
31 import android.util.Log;
32 import android.view.Menu;
33 import android.view.MenuInflater;
34 import android.view.MenuItem;
35 import android.view.View;
36 import android.view.Window;
37 import android.widget.CheckBox;
38 import android.widget.CompoundButton;
39 import android.widget.CompoundButton.OnCheckedChangeListener;
40 import android.widget.EditText;
41
42 public class VpnProfileDetailActivity extends Activity
43 {
44 private VpnProfileDataSource mDataSource;
45 private Long mId;
46 private VpnProfile mProfile;
47 private boolean mCertsLoaded;
48 private String mCertAlias;
49 private EditText mName;
50 private EditText mGateway;
51 private EditText mUsername;
52 private EditText mPassword;
53 private CheckBox mCheckAuto;
54
55 @Override
56 public void onCreate(Bundle savedInstanceState)
57 {
58 super.onCreate(savedInstanceState);
59 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
60
61 /* the title is set when we load the profile, if any */
62 getActionBar().setDisplayHomeAsUpEnabled(true);
63
64 mDataSource = new VpnProfileDataSource(this);
65 mDataSource.open();
66
67 setContentView(R.layout.profile_detail_view);
68
69 mName = (EditText)findViewById(R.id.name);
70 mPassword = (EditText)findViewById(R.id.password);
71 mGateway = (EditText)findViewById(R.id.gateway);
72 mUsername = (EditText)findViewById(R.id.username);
73
74 mCheckAuto = (CheckBox)findViewById(R.id.ca_auto);
75
76 mCheckAuto.setOnCheckedChangeListener(new OnCheckedChangeListener() {
77 @Override
78 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
79 {
80
81 }
82 });
83
84 mId = savedInstanceState == null ? null : savedInstanceState.getLong(VpnProfileDataSource.KEY_ID);
85 if (mId == null)
86 {
87 Bundle extras = getIntent().getExtras();
88 mId = extras == null ? null : extras.getLong(VpnProfileDataSource.KEY_ID);
89 }
90
91 loadProfileData();
92
93 new CertificateLoadTask().execute();
94 }
95
96 @Override
97 protected void onDestroy()
98 {
99 super.onDestroy();
100 mDataSource.close();
101 }
102
103 @Override
104 protected void onSaveInstanceState(Bundle outState)
105 {
106 super.onSaveInstanceState(outState);
107 outState.putLong(VpnProfileDataSource.KEY_ID, mId);
108 }
109
110 @Override
111 public boolean onCreateOptionsMenu(Menu menu)
112 {
113 MenuInflater inflater = getMenuInflater();
114 inflater.inflate(R.menu.profile_edit, menu);
115 return true;
116 }
117
118 @Override
119 public boolean onOptionsItemSelected(MenuItem item)
120 {
121 switch (item.getItemId())
122 {
123 case android.R.id.home:
124 case R.id.menu_cancel:
125 finish();
126 return true;
127 case R.id.menu_accept:
128 saveProfile();
129 return true;
130 default:
131 return super.onOptionsItemSelected(item);
132 }
133 }
134
135 /**
136 * Show an alert in case the previously selected certificate is not found anymore
137 * or the user did not select a certificate in the spinner.
138 */
139 private void showCertificateAlert()
140 {
141 AlertDialog.Builder adb = new AlertDialog.Builder(VpnProfileDetailActivity.this);
142 adb.setTitle(R.string.alert_text_nocertfound_title);
143 adb.setMessage(R.string.alert_text_nocertfound);
144 adb.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
145 @Override
146 public void onClick(DialogInterface dialog, int id)
147 {
148 dialog.cancel();
149 }
150 });
151 adb.show();
152 }
153
154 /**
155 * Asynchronously executed task which confirms that the certificates are loaded.
156 * They are loaded from the main Activity already but might not be ready yet, or
157 * unloaded again.
158 *
159 * Once loaded the CA certificate spinner and checkboxes are updated
160 * accordingly.
161 */
162 private class CertificateLoadTask extends AsyncTask<Void, Void, TrustedCertificateManager>
163 {
164 @Override
165 protected void onPreExecute()
166 {
167 setProgressBarIndeterminateVisibility(true);
168 }
169
170 @Override
171 protected TrustedCertificateManager doInBackground(Void... params)
172 {
173 return TrustedCertificateManager.getInstance().load();
174 }
175
176 @Override
177 protected void onPostExecute(TrustedCertificateManager result)
178 {
179 setProgressBarIndeterminateVisibility(false);
180 mCertsLoaded = true;
181 }
182 }
183
184 /**
185 * Save or update the profile depending on whether we actually have a
186 * profile object or not (this was created in updateProfileData)
187 */
188 private void saveProfile()
189 {
190 if (verifyInput())
191 {
192 if (mProfile != null)
193 {
194 updateProfileData();
195 mDataSource.updateVpnProfile(mProfile);
196 }
197 else
198 {
199 mProfile = new VpnProfile();
200 updateProfileData();
201 mDataSource.insertProfile(mProfile);
202 }
203 setResult(RESULT_OK, new Intent().putExtra(VpnProfileDataSource.KEY_ID, mProfile.getId()));
204 finish();
205 }
206 }
207
208 /**
209 * Verify the user input and display error messages.
210 * @return true if the input is valid
211 */
212 private boolean verifyInput()
213 {
214 boolean valid = true;
215 if (mGateway.getText().toString().trim().isEmpty())
216 {
217 mGateway.setError(getString(R.string.alert_text_no_input_gateway));
218 valid = false;
219 }
220 if (mUsername.getText().toString().trim().isEmpty())
221 {
222 mUsername.setError(getString(R.string.alert_text_no_input_username));
223 valid = false;
224 }
225 if (!mCheckAuto.isChecked())
226 {
227 showCertificateAlert();
228 valid = false;
229 }
230 return valid;
231 }
232
233 /**
234 * Update the profile object with the data entered by the user
235 */
236 private void updateProfileData()
237 {
238 /* the name is optional, we default to the gateway if none is given */
239 String name = mName.getText().toString().trim();
240 String gateway = mGateway.getText().toString().trim();
241 mProfile.setName(name.isEmpty() ? gateway : name);
242 mProfile.setGateway(gateway);
243 mProfile.setUsername(mUsername.getText().toString().trim());
244 String password = mPassword.getText().toString().trim();
245 password = password.isEmpty() ? null : password;
246 mProfile.setPassword(password);
247 }
248
249 /**
250 * Load an existing profile if we got an ID
251 */
252 private void loadProfileData()
253 {
254 getActionBar().setTitle(R.string.add_profile);
255 if (mId != null)
256 {
257 mProfile = mDataSource.getVpnProfile(mId);
258 if (mProfile != null)
259 {
260 mName.setText(mProfile.getName());
261 mGateway.setText(mProfile.getGateway());
262 mUsername.setText(mProfile.getUsername());
263 mPassword.setText(mProfile.getPassword());
264 mCertAlias = mProfile.getCertificateAlias();
265 getActionBar().setTitle(mProfile.getName());
266 }
267 else
268 {
269 Log.e(VpnProfileDetailActivity.class.getSimpleName(),
270 "VPN profile with id " + mId + " not found");
271 finish();
272 }
273 }
274 mCheckAuto.setChecked(mCertAlias == null);
275 }
276 }