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