f9d6c1725eb44a2c21a741fbd1469f9aa5a83794
[strongswan.git] / src / frontends / android / src / org / strongswan / android / ui / MainActivity.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.CharonVpnService;
24 import org.strongswan.android.logic.TrustedCertificateManager;
25 import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
26
27 import android.app.ActionBar;
28 import android.app.Activity;
29 import android.app.AlertDialog;
30 import android.app.AlertDialog.Builder;
31 import android.app.Dialog;
32 import android.app.DialogFragment;
33 import android.content.Context;
34 import android.content.DialogInterface;
35 import android.content.Intent;
36 import android.net.VpnService;
37 import android.os.AsyncTask;
38 import android.os.Bundle;
39 import android.view.LayoutInflater;
40 import android.view.Menu;
41 import android.view.MenuItem;
42 import android.view.View;
43 import android.view.Window;
44 import android.widget.EditText;
45
46 public class MainActivity extends Activity implements OnVpnProfileSelectedListener
47 {
48 private static final int PREPARE_VPN_SERVICE = 0;
49 private VpnProfile activeProfile;
50
51 @Override
52 public void onCreate(Bundle savedInstanceState)
53 {
54 super.onCreate(savedInstanceState);
55 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
56 setContentView(R.layout.main);
57
58 ActionBar bar = getActionBar();
59 bar.setDisplayShowTitleEnabled(false);
60
61 /* load CA certificates in a background task */
62 new CertificateLoadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, false);
63 }
64
65 @Override
66 public boolean onCreateOptionsMenu(Menu menu)
67 {
68 getMenuInflater().inflate(R.menu.main, menu);
69 return true;
70 }
71
72 @Override
73 public boolean onOptionsItemSelected(MenuItem item)
74 {
75 switch (item.getItemId())
76 {
77 case R.id.menu_reload_certs:
78 new CertificateLoadTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, true);
79 return true;
80 case R.id.menu_show_log:
81 Intent logIntent = new Intent(this, LogActivity.class);
82 startActivity(logIntent);
83 return true;
84 default:
85 return super.onOptionsItemSelected(item);
86 }
87 }
88
89 /**
90 * Prepare the VpnService. If this succeeds the current VPN profile is
91 * started.
92 */
93 protected void prepareVpnService()
94 {
95 Intent intent = VpnService.prepare(this);
96 if (intent != null)
97 {
98 startActivityForResult(intent, PREPARE_VPN_SERVICE);
99 }
100 else
101 {
102 onActivityResult(PREPARE_VPN_SERVICE, RESULT_OK, null);
103 }
104 }
105
106 @Override
107 protected void onActivityResult(int requestCode, int resultCode, Intent data)
108 {
109 switch (requestCode)
110 {
111 case PREPARE_VPN_SERVICE:
112 if (resultCode == RESULT_OK && activeProfile != null)
113 {
114 Intent intent = new Intent(this, CharonVpnService.class);
115 intent.putExtra(VpnProfileDataSource.KEY_ID, activeProfile.getId());
116 /* submit the password as the profile might not store one */
117 intent.putExtra(VpnProfileDataSource.KEY_PASSWORD, activeProfile.getPassword());
118 this.startService(intent);
119 }
120 break;
121 default:
122 super.onActivityResult(requestCode, resultCode, data);
123 }
124 }
125
126 @Override
127 public void onVpnProfileSelected(VpnProfile profile)
128 {
129 activeProfile = profile;
130 if (activeProfile.getPassword() == null)
131 {
132 new LoginDialog().show(getFragmentManager(), "LoginDialog");
133 }
134 else
135 {
136 prepareVpnService();
137 }
138 }
139
140 /**
141 * Class that loads or reloads the cached CA certificates.
142 */
143 private class CertificateLoadTask extends AsyncTask<Boolean, Void, TrustedCertificateManager>
144 {
145 @Override
146 protected void onPreExecute()
147 {
148 setProgressBarIndeterminateVisibility(true);
149 }
150 @Override
151 protected TrustedCertificateManager doInBackground(Boolean... params)
152 {
153 if (params.length > 0 && params[0])
154 { /* force a reload of the certificates */
155 return TrustedCertificateManager.getInstance().reload();
156 }
157 return TrustedCertificateManager.getInstance().load();
158 }
159 @Override
160 protected void onPostExecute(TrustedCertificateManager result)
161 {
162 setProgressBarIndeterminateVisibility(false);
163 }
164 }
165
166 private class LoginDialog extends DialogFragment
167 {
168 @Override
169 public Dialog onCreateDialog(Bundle savedInstanceState)
170 {
171 LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
172 View view = inflater.inflate(R.layout.login_dialog, null);
173 EditText username = (EditText)view.findViewById(R.id.username);
174 username.setText(activeProfile.getUsername());
175 final EditText password = (EditText)view.findViewById(R.id.password);
176
177 Builder adb = new AlertDialog.Builder(MainActivity.this);
178 adb.setView(view);
179 adb.setTitle(getString(R.string.login_title));
180 adb.setPositiveButton(R.string.login_confirm, new DialogInterface.OnClickListener() {
181 @Override
182 public void onClick(DialogInterface dialog, int whichButton)
183 {
184 /* let's work on a clone of the profile when updating the password */
185 activeProfile = activeProfile.clone();
186 activeProfile.setPassword(password.getText().toString().trim());
187 prepareVpnService();
188 }
189 });
190 adb.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
191 @Override
192 public void onClick(DialogInterface dialog, int which)
193 {
194 dismiss();
195 }
196 });
197 return adb.create();
198 }
199 }
200 }