android: Add settings activity and default profile selection

The default profile can then be used for a Quick Settings tile or the
Always-on VPN feature.
This commit is contained in:
Tobias Brunner
2018-07-03 11:31:34 +02:00
parent 6e73a939a9
commit acdac14818
18 changed files with 293 additions and 15 deletions
+1
View File
@@ -45,6 +45,7 @@ android {
dependencies {
implementation 'com.android.support:appcompat-v7:26.0.2'
implementation 'com.android.support:design:26.0.2'
implementation 'com.android.support:preference-v7:26.0.2'
implementation 'com.android.support:support-v4:26.0.2'
testImplementation 'junit:junit:4.12'
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012-2015 Tobias Brunner
Copyright (C) 2012-2018 Tobias Brunner
Copyright (C) 2012 Giuliano Grassi
Copyright (C) 2012 Ralf Sager
HSR Hochschule fuer Technik Rapperswil
@@ -66,6 +66,10 @@
<activity
android:name=".ui.LogActivity"
android:label="@string/log_title" >
</activity>
<activity
android:name=".ui.SettingsActivity"
android:label="@string/pref_title">
</activity>
<activity
android:name=".ui.RemediationInstructionsActivity"
@@ -381,6 +381,28 @@ public class VpnProfileDataSource
return profile;
}
/**
* Get a single VPN profile from the database by its UUID as String.
* @param uuid the UUID of the VPN profile as String
* @return the profile or null, if not found
*/
public VpnProfile getVpnProfile(String uuid)
{
try
{
if (uuid != null)
{
return getVpnProfile(UUID.fromString(uuid));
}
return null;
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
return null;
}
}
/**
* Get a list of all VPN profiles stored in the database.
* @return list of VPN profiles
@@ -108,6 +108,10 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec
Intent logIntent = new Intent(this, LogActivity.class);
startActivity(logIntent);
return true;
case R.id.menu_settings:
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
package org.strongswan.android.ui;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
public class SettingsActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
@@ -0,0 +1,133 @@
/*
* Copyright (C) 2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
package org.strongswan.android.ui;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceManager;
import org.strongswan.android.R;
import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.data.VpnProfileDataSource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE;
import static org.strongswan.android.utils.Constants.PREF_DEFAULT_VPN_PROFILE_MRU;
public class SettingsFragment extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener
{
private ListPreference mDefaultVPNProfile;
@Override
public void onCreatePreferences(Bundle bundle, String s)
{
setPreferencesFromResource(R.xml.settings, s);
mDefaultVPNProfile = (ListPreference)findPreference(PREF_DEFAULT_VPN_PROFILE);
mDefaultVPNProfile.setOnPreferenceChangeListener(this);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
{
mDefaultVPNProfile.setEnabled(false);
}
}
@Override
public void onResume()
{
super.onResume();
VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
profiles.open();
List<VpnProfile> all = profiles.getAllVpnProfiles();
Collections.sort(all, new Comparator<VpnProfile>() {
@Override
public int compare(VpnProfile lhs, VpnProfile rhs)
{
return lhs.getName().compareToIgnoreCase(rhs.getName());
}
});
ArrayList<CharSequence> entries = new ArrayList<>();
ArrayList<CharSequence> entryvalues = new ArrayList<>();
entries.add(getString(R.string.pref_default_vpn_profile_mru));
entryvalues.add(PREF_DEFAULT_VPN_PROFILE_MRU);
for (VpnProfile profile : all)
{
entries.add(profile.getName());
entryvalues.add(profile.getUUID().toString());
}
profiles.close();
if (entries.size() <= 1)
{
mDefaultVPNProfile.setEnabled(false);
}
else
{
mDefaultVPNProfile.setEnabled(true);
mDefaultVPNProfile.setEntries(entries.toArray(new CharSequence[0]));
mDefaultVPNProfile.setEntryValues(entryvalues.toArray(new CharSequence[0]));
}
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity());
setCurrentProfileName(pref.getString(PREF_DEFAULT_VPN_PROFILE, PREF_DEFAULT_VPN_PROFILE_MRU));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue)
{
if (preference == mDefaultVPNProfile)
{
setCurrentProfileName((String)newValue);
}
return true;
}
private void setCurrentProfileName(String uuid)
{
VpnProfileDataSource profiles = new VpnProfileDataSource(getActivity());
profiles.open();
if (!uuid.equals(PREF_DEFAULT_VPN_PROFILE_MRU))
{
VpnProfile current = profiles.getVpnProfile(uuid);
if (current != null)
{
mDefaultVPNProfile.setSummary(current.getName());
}
else
{
mDefaultVPNProfile.setSummary(R.string.profile_not_found);
}
}
else
{
mDefaultVPNProfile.setSummary(R.string.pref_default_vpn_profile_mru);
}
profiles.close();
}
}
@@ -44,8 +44,6 @@ import org.strongswan.android.logic.CharonVpnService;
import org.strongswan.android.logic.VpnStateService;
import org.strongswan.android.logic.VpnStateService.State;
import java.util.UUID;
public class VpnProfileControlActivity extends AppCompatActivity
{
public static final String START_PROFILE = "org.strongswan.android.action.START_PROFILE";
@@ -254,14 +252,7 @@ public class VpnProfileControlActivity extends AppCompatActivity
String profileUUID = intent.getStringExtra(EXTRA_VPN_PROFILE_ID);
if (profileUUID != null)
{
try
{
profile = dataSource.getVpnProfile(UUID.fromString(profileUUID));
}
catch (Exception e)
{ /* invalid UUID */
e.printStackTrace();
}
profile = dataSource.getVpnProfile(profileUUID);
}
else
{
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Tobias Brunner
* Copyright (C) 2016-2018 Tobias Brunner
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -43,4 +43,14 @@ public final class Constants
*/
public static final int NAT_KEEPALIVE_MAX = 120;
public static final int NAT_KEEPALIVE_MIN = 10;
/**
* Preference key for default VPN profile
*/
public static final String PREF_DEFAULT_VPN_PROFILE = "pref_default_vpn_profile";
/**
* Value used to signify that the most recently used profile should be used as default
*/
public static final String PREF_DEFAULT_VPN_PROFILE_MRU = "pref_default_vpn_profile_mru";
}
@@ -36,4 +36,9 @@
android:title="@string/show_log"
app:showAsAction="withText" />
<item
android:id="@+id/menu_settings"
android:title="@string/pref_title"
app:showAsAction="withText" />
</menu>
@@ -32,6 +32,11 @@
<string name="permanent_notification_name">VPN Verbindungsstatus</string>
<string name="permanent_notification_description">Zeigt Informationen zum Verbindungsstatus der VPN Verbindung und dient als permanente Notification dazu, den VPN Dienst im Hintergrund am Laufen zu halten.</string>
<!-- Settings -->
<string name="pref_title">Einstellungen</string>
<string name="pref_default_vpn_profile">Voreingestelltes VPN Profil</string>
<string name="pref_default_vpn_profile_mru">Verbinden mit zuletzt verwendetem Profil</string>
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Logdatei senden</string>
@@ -76,8 +81,8 @@
<string name="profile_advanced_label">Erweiterte Einstellungen</string>
<string name="profile_show_advanced_label">Erweiterte Einstellungen anzeigen</string>
<string name="profile_remote_id_label">Server-Identität</string>
<string name="profile_remote_id_hint">Standardwert ist der konfigurierte Server. Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen</string>
<string name="profile_remote_id_hint_gateway">Standardwert ist \"%1$s\". Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen</string>
<string name="profile_remote_id_hint">Standardwert ist der konfigurierte Server. Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen</string>
<string name="profile_remote_id_hint_gateway">Standardwert ist \"%1$s\". Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen</string>
<string name="profile_mtu_label">MTU des VPN Tunnel-Device</string>
<string name="profile_mtu_hint">Falls der Standardwert in einem bestimmten Netzwerk nicht geeignet ist</string>
<string name="profile_port_label">Server Port</string>
@@ -105,7 +110,7 @@
<string name="profile_proposals_ike_hint">Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus, eine pseudozufällige Funktion (PRF, optional, ansonsten wird eine auf dem Integritätsalgorithmus basierende verwendet) und eine Diffie-Hellman Gruppe benötigt (z.B. aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen aber eine PRF wird benötigt (z.B. aes256gcm16-prfsha256-ecp256).</string>
<string name="profile_proposals_esp_label">IPsec/ESP Algorithmen</string>
<string name="profile_proposals_esp_hint">Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus benötigt, eine Diffie-Hellman Gruppe ist optional (z.B. aes256-sha256 oder aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen (z.B. aes256gcm16 oder aes256gcm16-ecp256). Falls eine DH Gruppe angegeben wird, kommt während dem IPsec SA Rekeying ein DH Schlüsselaustausch zur Anwendung. Beim initialen Verbindungsaufbau hat eine DH Gruppe hier keinen Einfluss, weil die Schlüssel dort von der IKE SA abgeleitet werden. Deshalb wird eine Fehlkonfiguration mit dem Server erst später während dem Rekeying zu einem Fehler führen.</string>
<string name="profile_import">VPN Profile importieren</string>
<string name="profile_import">VPN Profil importieren</string>
<string name="profile_import_failed">VPN Profil-Import fehlgeschlagen</string>
<string name="profile_import_failed_detail">VPN Profil-Import fehlgeschlagen: %1$s</string>
<string name="profile_import_failed_not_found">Datei nicht gefunden</string>
@@ -32,6 +32,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Prześlij log</string>
@@ -29,6 +29,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">Журнал</string>
<string name="send_log">Отправить журнал</string>
@@ -30,6 +30,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">Журнал</string>
<string name="send_log">Відправити файл журналу</string>
@@ -29,6 +29,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">日志</string>
<string name="send_log">发送日志文件</string>
@@ -29,6 +29,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">日誌</string>
<string name="send_log">發送日誌檔</string>
@@ -32,6 +32,11 @@
<string name="permanent_notification_name">VPN connection state</string>
<string name="permanent_notification_description">Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background.</string>
<!-- Settings -->
<string name="pref_title">Settings</string>
<string name="pref_default_vpn_profile">Default VPN profile</string>
<string name="pref_default_vpn_profile_mru">Connect to most recently used profile</string>
<!-- Log view -->
<string name="log_title">Log</string>
<string name="send_log">Send log file</string>
@@ -20,6 +20,7 @@
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
<style name="AlertDialogTheme.Base" parent="Theme.AppCompat.Dialog.Alert">
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 Tobias Brunner
HSR Hochschule fuer Technik Rapperswil
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="pref_default_vpn_profile"
android:title="@string/pref_default_vpn_profile"
android:summary="@string/pref_default_vpn_profile_mru" />
</PreferenceScreen>