]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Add settings activity and default profile selection
authorTobias Brunner <tobias@strongswan.org>
Fri, 8 Jun 2018 09:57:38 +0000 (11:57 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 3 Jul 2018 09:31:34 +0000 (11:31 +0200)
The default profile can then be used for a Quick Settings tile or the
Always-on VPN feature.

18 files changed:
src/frontends/android/app/build.gradle
src/frontends/android/app/src/main/AndroidManifest.xml
src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java [new file with mode: 0644]
src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsFragment.java [new file with mode: 0644]
src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileControlActivity.java
src/frontends/android/app/src/main/java/org/strongswan/android/utils/Constants.java
src/frontends/android/app/src/main/res/menu/main.xml
src/frontends/android/app/src/main/res/values-de/strings.xml
src/frontends/android/app/src/main/res/values-pl/strings.xml
src/frontends/android/app/src/main/res/values-ru/strings.xml
src/frontends/android/app/src/main/res/values-ua/strings.xml
src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml
src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml
src/frontends/android/app/src/main/res/values/strings.xml
src/frontends/android/app/src/main/res/values/styles.xml
src/frontends/android/app/src/main/res/xml/settings.xml [new file with mode: 0644]

index 41845960255d8a0a6fb6e1a3b69144dbccde176c..737787b5e919ab2882b7a88efa2dd3114fad4501 100644 (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'
 }
index fc0fb4f5784815968232046f797554b6620afbfc..5d827a34def6cfccdefbf4b28fdd9ee0376a57f3 100644 (file)
@@ -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
         <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"
index b9161702e2312a93a426400675b2f6e07487cc90..afd0d4fb1ae8b9c3ea3792a49369e51e60142010 100644 (file)
@@ -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
index 5971e1ad499231d9b9950a7b408ad9a746745da4..bfef8e98caf21f216ee68e9532c81aa61229ca59 100644 (file)
@@ -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);
                }
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsActivity.java
new file mode 100644 (file)
index 0000000..ad28529
--- /dev/null
@@ -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);
+               }
+       }
+}
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsFragment.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/SettingsFragment.java
new file mode 100644 (file)
index 0000000..b710c82
--- /dev/null
@@ -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();
+       }
+}
index b8e74475c0dab24aa1f2cf3a57cecc9c4b13472e..9bc0cf0320d35d4aac229ce2c25d12105d75f953 100644 (file)
@@ -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
                {
index 16fdcdad12da2970593ebda2b764ec13b6320561..2e5de7fc3637fae766eb923757b1645a0124904b 100644 (file)
@@ -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";
 }
index 48a541b3d5a84e30757964ed7b0fd2949c8387bf..7cb0917ec6fb74cd478ff7e77354b85e30bc6d61 100644 (file)
@@ -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>
index 975686e563e70ba77a7e7aeffc49e315e75269a4..97df885f86cab204636fb1f37fad56c2333ca1b6 100644 (file)
     <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>
     <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>
index 835efd531a1f04f555e94514d80e212e6adf5413..e9c52f14a0a256d12b8d9298ee2698dd0dae3d6f 100644 (file)
     <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>
index 53e83757307d669a40911389320cc701bb46a57a..5f16eecc8112a536b6b002f117f195ee061748ac 100644 (file)
     <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>
index 8e41daf91423f527272c14ae1b4ccc7b1daf3629..53bcf7164056f586f9e907eaa32d4899e5214f3d 100644 (file)
     <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>
index 0cb6bd087a7ea3c30d65827a31e89a75aac33c20..72098cc4796f7db5ad676823fd8371923361174c 100644 (file)
     <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>
index 168fdd7dd39347732b88547a61ecb35a6e2c8e88..ba9fdd044a6a9dc485f91161779603aff941bc66 100644 (file)
     <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>
index 13d718733353db3157472c7e3f11869aff083f5e..cb507beae4cde28457da13149ab1d56fd3ac282c 100644 (file)
     <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>
index 83f34b6e182ff8e2237553daec4b0b24631b0413..4b7cc4c5c9816a03153a6416a74a6467d0dd2e62 100644 (file)
@@ -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">
diff --git a/src/frontends/android/app/src/main/res/xml/settings.xml b/src/frontends/android/app/src/main/res/xml/settings.xml
new file mode 100644 (file)
index 0000000..908a888
--- /dev/null
@@ -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>