From 9ab746cb0f82d4a96d8912b761b99dcc1fbe68d2 Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Tue, 12 Apr 2016 17:10:11 +0200
Subject: [PATCH 01/15] android: Update Android Gradle plugin and wrapper
---
src/frontends/android/build.gradle | 2 +-
.../android/gradle/wrapper/gradle-wrapper.properties | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/frontends/android/build.gradle b/src/frontends/android/build.gradle
index 9b18c6e90..81d32a87b 100644
--- a/src/frontends/android/build.gradle
+++ b/src/frontends/android/build.gradle
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.3.0'
+ classpath 'com.android.tools.build:gradle:2.1.0'
}
}
diff --git a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties
index 0c71e760d..33892269f 100644
--- a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties
+++ b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Wed Apr 13 11:22:32 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
From 10d0de0c9add735cf47821a0991bdc9d777e9b70 Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Wed, 25 Nov 2015 16:07:55 +0100
Subject: [PATCH 02/15] android: Update platform tools and pull in support libs
We'll have to change some stuff that Google deprecated (e.g. the tabs in
the ActionBar) and that requires changing the theme at least in activities.
Since that would look a bit inconsistent we'll change it globally and
use parts of the support library.
---
src/frontends/android/app/build.gradle | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/frontends/android/app/build.gradle b/src/frontends/android/app/build.gradle
index 46927ea27..d27ba1edd 100644
--- a/src/frontends/android/app/build.gradle
+++ b/src/frontends/android/app/build.gradle
@@ -1,8 +1,8 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 21
- buildToolsVersion "22.0.1"
+ compileSdkVersion 23
+ buildToolsVersion "23.0.3"
defaultConfig {
applicationId "org.strongswan.android"
@@ -42,5 +42,7 @@ android {
}
dependencies {
+ compile 'com.android.support:appcompat-v7:23.3.0'
+ compile 'com.android.support:design:23.3.0'
testCompile 'junit:junit:4.12'
}
From 9dd6d1e6dba737c142abc5124677e26158080a4e Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Fri, 15 Apr 2016 17:43:58 +0200
Subject: [PATCH 03/15] android: Ignore build/ in project directory
---
src/frontends/android/.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/frontends/android/.gitignore b/src/frontends/android/.gitignore
index 7e4bcfd4e..aeb7cd7ab 100644
--- a/src/frontends/android/.gitignore
+++ b/src/frontends/android/.gitignore
@@ -1,5 +1,6 @@
.gradle/
.idea/
+build/
app/build/
app/src/main/libs
app/src/main/obj
From 6b31828269b554a67e9188f4e7878bf9494972a7 Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Wed, 25 Nov 2015 17:05:56 +0100
Subject: [PATCH 04/15] android: Switch to AppCompat/Material theme and use
custom Toolbar as AppBar
Also includes some whitespace/formatting changes due to the switch to
Android Studio.
---
.../android/app/src/main/AndroidManifest.xml | 2 +-
.../strongswan/android/ui/LogActivity.java | 22 +++---
.../strongswan/android/ui/MainActivity.java | 69 +++++++++++-------
.../ui/RemediationInstructionsActivity.java | 16 ++---
.../ui/TrustedCertificateImportActivity.java | 42 ++++++-----
.../ui/TrustedCertificateListFragment.java | 41 +++++------
.../ui/TrustedCertificatesActivity.java | 70 +++++++++----------
.../android/ui/VpnProfileDetailActivity.java | 30 ++++----
.../android/ui/VpnProfileSelectActivity.java | 10 +--
.../app/src/main/res/menu/certificates.xml | 7 +-
.../android/app/src/main/res/menu/log.xml | 5 +-
.../android/app/src/main/res/menu/main.xml | 9 +--
.../app/src/main/res/menu/profile_edit.xml | 7 +-
.../app/src/main/res/menu/profile_list.xml | 5 +-
.../main/res/menu/profile_list_context.xml | 6 +-
.../app/src/main/res/values/styles.xml | 2 +-
16 files changed, 185 insertions(+), 158 deletions(-)
diff --git a/src/frontends/android/app/src/main/AndroidManifest.xml b/src/frontends/android/app/src/main/AndroidManifest.xml
index 2ab833cdb..41f1037fd 100644
--- a/src/frontends/android/app/src/main/AndroidManifest.xml
+++ b/src/frontends/android/app/src/main/AndroidManifest.xml
@@ -66,7 +66,7 @@
+ android:theme="@style/Theme.AppCompat.Dialog" >
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/LogActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/LogActivity.java
index a5efecc09..4ad2ebb57 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/LogActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/LogActivity.java
@@ -15,21 +15,21 @@
package org.strongswan.android.ui;
-import java.io.File;
+import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
import org.strongswan.android.R;
import org.strongswan.android.data.LogContentProvider;
import org.strongswan.android.logic.CharonVpnService;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.Toast;
+import java.io.File;
-public class LogActivity extends Activity
+public class LogActivity extends AppCompatActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
@@ -37,7 +37,7 @@ public class LogActivity extends Activity
super.onCreate(savedInstanceState);
setContentView(R.layout.log_activity);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
@@ -74,7 +74,7 @@ public class LogActivity extends Activity
}
Intent intent = new Intent(Intent.ACTION_SEND);
- intent.putExtra(Intent.EXTRA_EMAIL, new String[] { MainActivity.CONTACT_EMAIL });
+ intent.putExtra(Intent.EXTRA_EMAIL, new String[]{MainActivity.CONTACT_EMAIL});
intent.putExtra(Intent.EXTRA_SUBJECT, String.format(getString(R.string.log_mail_subject), version));
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_STREAM, LogContentProvider.createContentUri());
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java
index e1b3e0783..31ce5b9ff 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java
@@ -17,19 +17,7 @@
package org.strongswan.android.ui;
-import org.strongswan.android.R;
-import org.strongswan.android.data.VpnProfile;
-import org.strongswan.android.data.VpnProfileDataSource;
-import org.strongswan.android.data.VpnType.VpnTypeFeature;
-import org.strongswan.android.logic.CharonVpnService;
-import org.strongswan.android.logic.TrustedCertificateManager;
-import org.strongswan.android.logic.VpnStateService;
-import org.strongswan.android.logic.VpnStateService.State;
-import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
-
-import android.app.ActionBar;
import android.app.Activity;
-import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -46,6 +34,8 @@ import android.net.VpnService;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
@@ -54,12 +44,24 @@ import android.view.Window;
import android.widget.EditText;
import android.widget.Toast;
-public class MainActivity extends Activity implements OnVpnProfileSelectedListener
+import org.strongswan.android.R;
+import org.strongswan.android.data.VpnProfile;
+import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnType.VpnTypeFeature;
+import org.strongswan.android.logic.CharonVpnService;
+import org.strongswan.android.logic.TrustedCertificateManager;
+import org.strongswan.android.logic.VpnStateService;
+import org.strongswan.android.logic.VpnStateService.State;
+import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
+
+public class MainActivity extends AppCompatActivity implements OnVpnProfileSelectedListener
{
public static final String CONTACT_EMAIL = "android@strongswan.org";
public static final String START_PROFILE = "org.strongswan.android.action.START_PROFILE";
public static final String EXTRA_VPN_PROFILE_ID = "org.strongswan.android.VPN_PROFILE_ID";
- /** Use "bring your own device" (BYOD) features */
+ /**
+ * Use "bring your own device" (BYOD) features
+ */
public static final boolean USE_BYOD = true;
private static final int PREPARE_VPN_SERVICE = 0;
private static final String PROFILE_NAME = "org.strongswan.android.MainActivity.PROFILE_NAME";
@@ -69,7 +71,8 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
private Bundle mProfileInfo;
private VpnStateService mService;
- private final ServiceConnection mServiceConnection = new ServiceConnection() {
+ private final ServiceConnection mServiceConnection = new ServiceConnection()
+ {
@Override
public void onServiceDisconnected(ComponentName name)
{
@@ -91,16 +94,18 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
@Override
public void onCreate(Bundle savedInstanceState)
{
- super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ super.onCreate(savedInstanceState);
setContentView(R.layout.main);
+ ActionBar bar = getSupportActionBar();
+ bar.setDisplayShowHomeEnabled(true);
+ bar.setDisplayShowTitleEnabled(false);
+ bar.setIcon(R.drawable.ic_launcher);
+
this.bindService(new Intent(this, VpnStateService.class),
mServiceConnection, Service.BIND_AUTO_CREATE);
- ActionBar bar = getActionBar();
- bar.setDisplayShowTitleEnabled(false);
-
/* load CA certificates in a background task */
new LoadCertificatesTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -157,6 +162,7 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
/**
* Prepare the VpnService. If this succeeds the current VPN profile is
* started.
+ *
* @param profileInfo a bundle containing the information about the profile to be started
*/
protected void prepareVpnService(Bundle profileInfo)
@@ -239,6 +245,7 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
/**
* Start the given VPN profile asking the user for a password if required.
+ *
* @param profileInfo data about the profile
*/
private void startVpnProfile(Bundle profileInfo)
@@ -257,6 +264,7 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
/**
* Start the VPN profile referred to by the given intent. Displays an error
* if the profile doesn't exist.
+ *
* @param intent Intent that caused us to start this
*/
private void startVpnProfile(Intent intent)
@@ -291,11 +299,13 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
{
setProgressBarIndeterminateVisibility(true);
}
+
@Override
protected TrustedCertificateManager doInBackground(Void... params)
{
return TrustedCertificateManager.getInstance().load();
}
+
@Override
protected void onPostExecute(TrustedCertificateManager result)
{
@@ -341,11 +351,12 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
button = R.string.reconnect;
}
- return new AlertDialog.Builder(getActivity())
+ return new Builder(getActivity())
.setIcon(icon)
.setTitle(String.format(getString(title), profileInfo.getString(PROFILE_NAME)))
.setMessage(message)
- .setPositiveButton(button, new DialogInterface.OnClickListener() {
+ .setPositiveButton(button, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int whichButton)
{
@@ -353,7 +364,8 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
activity.startVpnProfile(profileInfo);
}
})
- .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int which)
{
@@ -379,10 +391,11 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
username.setText(profileInfo.getString(VpnProfileDataSource.KEY_USERNAME));
final EditText password = (EditText)view.findViewById(R.id.password);
- Builder adb = new AlertDialog.Builder(getActivity());
+ Builder adb = new Builder(getActivity());
adb.setView(view);
adb.setTitle(getString(R.string.login_title));
- adb.setPositiveButton(R.string.login_confirm, new DialogInterface.OnClickListener() {
+ adb.setPositiveButton(R.string.login_confirm, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int whichButton)
{
@@ -391,7 +404,8 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
activity.prepareVpnService(profileInfo);
}
});
- adb.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ adb.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int which)
{
@@ -424,11 +438,12 @@ public class MainActivity extends Activity implements OnVpnProfileSelectedListen
{
final Bundle arguments = getArguments();
final int messageId = arguments.getInt(ERROR_MESSAGE_ID);
- return new AlertDialog.Builder(getActivity())
+ return new Builder(getActivity())
.setTitle(R.string.vpn_not_supported_title)
.setMessage(messageId)
.setCancelable(false)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int id)
{
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/RemediationInstructionsActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/RemediationInstructionsActivity.java
index 66d0de261..7e7e870be 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/RemediationInstructionsActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/RemediationInstructionsActivity.java
@@ -15,24 +15,24 @@
package org.strongswan.android.ui;
-import java.util.ArrayList;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
import org.strongswan.android.R;
import org.strongswan.android.logic.imc.RemediationInstruction;
import org.strongswan.android.ui.RemediationInstructionsFragment.OnRemediationInstructionSelectedListener;
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.MenuItem;
+import java.util.ArrayList;
-public class RemediationInstructionsActivity extends Activity implements OnRemediationInstructionSelectedListener
+public class RemediationInstructionsActivity extends AppCompatActivity implements OnRemediationInstructionSelectedListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.remediation_instructions);
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState != null)
{ /* only update if we're not restoring */
@@ -64,7 +64,7 @@ public class RemediationInstructionsActivity extends Activity implements OnRemed
{
finish();
}
- getActionBar().setTitle(getTitle());
+ getSupportActionBar().setTitle(getTitle());
return true;
default:
return super.onOptionsItemSelected(item);
@@ -88,7 +88,7 @@ public class RemediationInstructionsActivity extends Activity implements OnRemed
frag.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.fragment_container, frag).addToBackStack(null).commit();
- getActionBar().setTitle(instruction.getTitle());
+ getSupportActionBar().setTitle(instruction.getTitle());
}
}
}
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java
index 61bd2c9a2..8e3930788 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateImportActivity.java
@@ -15,17 +15,6 @@
package org.strongswan.android.ui;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.security.KeyStore;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-
-import org.strongswan.android.R;
-import org.strongswan.android.data.VpnProfileDataSource;
-import org.strongswan.android.logic.TrustedCertificateManager;
-
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
@@ -37,19 +26,31 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
-public class TrustedCertificateImportActivity extends Activity
+import org.strongswan.android.R;
+import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.logic.TrustedCertificateManager;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+public class TrustedCertificateImportActivity extends AppCompatActivity
{
private static final int OPEN_DOCUMENT = 0;
private static final String DIALOG_TAG = "Dialog";
/* same as those listed in the manifest */
private static final String[] ACCEPTED_MIME_TYPES = {
- "application/x-x509-ca-cert",
- "application/x-x509-server-cert",
- "application/x-pem-file",
- "application/pkix-cert"
+ "application/x-x509-ca-cert",
+ "application/x-x509-server-cert",
+ "application/x-pem-file",
+ "application/pkix-cert"
};
@TargetApi(Build.VERSION_CODES.KITKAT)
@@ -97,6 +98,7 @@ public class TrustedCertificateImportActivity extends Activity
/**
* Import the file pointed to by the given URI as a certificate.
+ *
* @param uri
*/
private void importCertificate(Uri uri)
@@ -124,6 +126,7 @@ public class TrustedCertificateImportActivity extends Activity
/**
* Load the file from the given URI and try to parse it as X.509 certificate.
+ *
* @param uri
* @return certificate or null
*/
@@ -151,6 +154,7 @@ public class TrustedCertificateImportActivity extends Activity
/**
* Try to store the given certificate in the KeyStore.
+ *
* @param certificate
* @return whether it was successfully stored
*/
@@ -188,7 +192,8 @@ public class TrustedCertificateImportActivity extends Activity
.setIcon(R.drawable.ic_launcher)
.setTitle(R.string.import_certificate)
.setMessage(certificate.getSubjectDN().toString())
- .setPositiveButton(R.string.import_certificate, new DialogInterface.OnClickListener() {
+ .setPositiveButton(R.string.import_certificate, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int whichButton)
{
@@ -205,7 +210,8 @@ public class TrustedCertificateImportActivity extends Activity
getActivity().finish();
}
})
- .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+ .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener()
+ {
@Override
public void onClick(DialogInterface dialog, int which)
{
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateListFragment.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateListFragment.java
index 8bd39c435..12da59622 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateListFragment.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificateListFragment.java
@@ -15,26 +15,13 @@
package org.strongswan.android.ui;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map.Entry;
-
-import org.strongswan.android.R;
-import org.strongswan.android.logic.TrustedCertificateManager;
-import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
-import org.strongswan.android.security.TrustedCertificateEntry;
-import org.strongswan.android.ui.adapter.TrustedCertificateAdapter;
-
import android.app.Activity;
-import android.app.ListFragment;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.AsyncTaskLoader;
import android.content.Context;
-import android.content.Loader;
import android.os.Bundle;
+import android.support.v4.app.ListFragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
@@ -44,7 +31,20 @@ import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
-public class TrustedCertificateListFragment extends ListFragment implements LoaderCallbacks>, OnQueryTextListener
+import org.strongswan.android.R;
+import org.strongswan.android.logic.TrustedCertificateManager;
+import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificateSource;
+import org.strongswan.android.security.TrustedCertificateEntry;
+import org.strongswan.android.ui.adapter.TrustedCertificateAdapter;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map.Entry;
+
+public class TrustedCertificateListFragment extends ListFragment implements LoaderManager.LoaderCallbacks>, OnQueryTextListener
{
public static final String EXTRA_CERTIFICATE_SOURCE = "certificate_source";
private OnTrustedCertificateSelectedListener mListener;
@@ -54,7 +54,8 @@ public class TrustedCertificateListFragment extends ListFragment implements Load
/**
* The activity containing this fragment should implement this interface
*/
- public interface OnTrustedCertificateSelectedListener {
+ public interface OnTrustedCertificateSelectedListener
+ {
public void onTrustedCertificateSelected(TrustedCertificateEntry selected);
}
@@ -186,7 +187,7 @@ public class TrustedCertificateListFragment extends ListFragment implements Load
public List loadInBackground()
{
TrustedCertificateManager certman = TrustedCertificateManager.getInstance().load();
- Hashtable certificates = certman.getCACertificates(mSource);
+ Hashtable certificates = certman.getCACertificates(mSource);
List selected;
selected = new ArrayList();
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java
index 663950c16..5f666250e 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/TrustedCertificatesActivity.java
@@ -15,7 +15,16 @@
package org.strongswan.android.ui;
-import java.security.KeyStore;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.view.Menu;
+import android.view.MenuItem;
import org.strongswan.android.R;
import org.strongswan.android.data.VpnProfileDataSource;
@@ -24,18 +33,9 @@ import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificate
import org.strongswan.android.security.TrustedCertificateEntry;
import org.strongswan.android.ui.CertificateDeleteConfirmationDialog.OnCertificateDeleteListener;
-import android.app.ActionBar;
-import android.app.ActionBar.Tab;
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentTransaction;
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
+import java.security.KeyStore;
-public class TrustedCertificatesActivity extends Activity implements TrustedCertificateListFragment.OnTrustedCertificateSelectedListener, OnCertificateDeleteListener
+public class TrustedCertificatesActivity extends AppCompatActivity implements TrustedCertificateListFragment.OnTrustedCertificateSelectedListener, OnCertificateDeleteListener
{
public static final String SELECT_CERTIFICATE = "org.strongswan.android.action.SELECT_CERTIFICATE";
private static final String DIALOG_TAG = "Dialog";
@@ -48,29 +48,29 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
super.onCreate(savedInstanceState);
setContentView(R.layout.trusted_certificates_activity);
- ActionBar actionBar = getActionBar();
+ ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
TrustedCertificatesTabListener listener;
listener = new TrustedCertificatesTabListener(this, "system", TrustedCertificateSource.SYSTEM);
actionBar.addTab(actionBar
- .newTab()
- .setText(R.string.system_tab)
- .setTag(listener)
- .setTabListener(listener));
+ .newTab()
+ .setText(R.string.system_tab)
+ .setTag(listener)
+ .setTabListener(listener));
listener = new TrustedCertificatesTabListener(this, "user", TrustedCertificateSource.USER);
actionBar.addTab(actionBar
- .newTab()
- .setText(R.string.user_tab)
- .setTag(listener)
- .setTabListener(listener));
+ .newTab()
+ .setText(R.string.user_tab)
+ .setTag(listener)
+ .setTabListener(listener));
listener = new TrustedCertificatesTabListener(this, "local", TrustedCertificateSource.LOCAL);
actionBar.addTab(actionBar
- .newTab()
- .setText(R.string.local_tab)
- .setTag(listener)
- .setTabListener(listener));
+ .newTab()
+ .setText(R.string.local_tab)
+ .setTag(listener)
+ .setTabListener(listener));
if (savedInstanceState != null)
{
@@ -83,7 +83,7 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
- outState.putInt("tab", getActionBar().getSelectedNavigationIndex());
+ outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
}
@Override
@@ -151,7 +151,7 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
else
{
TrustedCertificatesTabListener listener;
- listener = (TrustedCertificatesTabListener)getActionBar().getSelectedTab().getTag();
+ listener = (TrustedCertificatesTabListener)getSupportActionBar().getSelectedTab().getTag();
if (listener.mTag == "local")
{
Bundle args = new Bundle();
@@ -182,9 +182,9 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
private void reloadCertificates()
{
TrustedCertificateManager.getInstance().reset();
- for (int i = 0; i < getActionBar().getTabCount(); i++)
+ for (int i = 0; i < getSupportActionBar().getTabCount(); i++)
{
- Tab tab = getActionBar().getTabAt(i);
+ ActionBar.Tab tab = getSupportActionBar().getTabAt(i);
TrustedCertificatesTabListener listener = (TrustedCertificatesTabListener)tab.getTag();
listener.reset();
}
@@ -196,24 +196,24 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
private final TrustedCertificateSource mSource;
private Fragment mFragment;
- public TrustedCertificatesTabListener(Activity activity, String tag, TrustedCertificateSource source)
+ public TrustedCertificatesTabListener(AppCompatActivity activity, String tag, TrustedCertificateSource source)
{
mTag = tag;
mSource = source;
/* check to see if we already have a fragment for this tab, probably
* from a previously saved state. if so, deactivate it, because the
* initial state is that no tab is shown */
- mFragment = activity.getFragmentManager().findFragmentByTag(mTag);
+ mFragment = activity.getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached())
{
- FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
+ FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
}
}
@Override
- public void onTabSelected(Tab tab, FragmentTransaction ft)
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft)
{
if (mFragment == null)
{
@@ -230,7 +230,7 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
}
@Override
- public void onTabUnselected(Tab tab, FragmentTransaction ft)
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft)
{
if (mFragment != null)
{
@@ -239,7 +239,7 @@ public class TrustedCertificatesActivity extends Activity implements TrustedCert
}
@Override
- public void onTabReselected(Tab tab, FragmentTransaction ft)
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft)
{
/* nothing to be done */
}
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java
index a8b3daa06..24690de76 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java
@@ -17,17 +17,6 @@
package org.strongswan.android.ui;
-import java.security.cert.X509Certificate;
-
-import org.strongswan.android.R;
-import org.strongswan.android.data.VpnProfile;
-import org.strongswan.android.data.VpnProfileDataSource;
-import org.strongswan.android.data.VpnType;
-import org.strongswan.android.data.VpnType.VpnTypeFeature;
-import org.strongswan.android.logic.TrustedCertificateManager;
-import org.strongswan.android.security.TrustedCertificateEntry;
-
-import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
@@ -39,6 +28,7 @@ import android.os.Bundle;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
import android.security.KeyChainException;
+import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
@@ -57,7 +47,17 @@ import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
-public class VpnProfileDetailActivity extends Activity
+import org.strongswan.android.R;
+import org.strongswan.android.data.VpnProfile;
+import org.strongswan.android.data.VpnProfileDataSource;
+import org.strongswan.android.data.VpnType;
+import org.strongswan.android.data.VpnType.VpnTypeFeature;
+import org.strongswan.android.logic.TrustedCertificateManager;
+import org.strongswan.android.security.TrustedCertificateEntry;
+
+import java.security.cert.X509Certificate;
+
+public class VpnProfileDetailActivity extends AppCompatActivity
{
private static final int SELECT_TRUSTED_CERTIFICATE = 0;
private static final int MTU_MIN = 1280;
@@ -94,7 +94,7 @@ public class VpnProfileDetailActivity extends Activity
super.onCreate(savedInstanceState);
/* the title is set when we load the profile, if any */
- getActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDataSource = new VpnProfileDataSource(this);
mDataSource.open();
@@ -465,7 +465,7 @@ public class VpnProfileDetailActivity extends Activity
{
String useralias = null, alias = null;
- getActionBar().setTitle(R.string.add_profile);
+ getSupportActionBar().setTitle(R.string.add_profile);
if (mId != null && mId != 0)
{
mProfile = mDataSource.getVpnProfile(mId);
@@ -482,7 +482,7 @@ public class VpnProfileDetailActivity extends Activity
mBlockIPv6.setChecked(mProfile.getSplitTunneling() != null ? (mProfile.getSplitTunneling() & VpnProfile.SPLIT_TUNNELING_BLOCK_IPV6) != 0 : false);
useralias = mProfile.getUserCertificateAlias();
alias = mProfile.getCertificateAlias();
- getActionBar().setTitle(mProfile.getName());
+ getSupportActionBar().setTitle(mProfile.getName());
}
else
{
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileSelectActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileSelectActivity.java
index b4d34f5a5..23b66d323 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileSelectActivity.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileSelectActivity.java
@@ -15,15 +15,15 @@
package org.strongswan.android.ui;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
import org.strongswan.android.R;
import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedListener;
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class VpnProfileSelectActivity extends Activity implements OnVpnProfileSelectedListener
+public class VpnProfileSelectActivity extends AppCompatActivity implements OnVpnProfileSelectedListener
{
@Override
protected void onCreate(Bundle savedInstanceState)
diff --git a/src/frontends/android/app/src/main/res/menu/certificates.xml b/src/frontends/android/app/src/main/res/menu/certificates.xml
index 6066cab60..8ce4f62bd 100644
--- a/src/frontends/android/app/src/main/res/menu/certificates.xml
+++ b/src/frontends/android/app/src/main/res/menu/certificates.xml
@@ -13,16 +13,17 @@
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-->
-
Dazu kann der Betreiber Daten verlangen, wie etwa eine eindeutige Identifikationsnummer, eine Liste der installierten Pakete, Systemeinstellungen oder kryptografische Prüfsummen von Dateien.
Solche Daten werden nur übermittelt nachdem die Identität des Servers geprüft wurde.]]>
CA-Zertifikate
@@ -116,9 +116,9 @@
Passwort eingeben um zu verbinden
Verbinden
Fehler beim Aufsetzen des VPN:
- Gateway-Adresse konnte nicht aufgelöst werden.
- Gateway ist nicht erreichbar.
- Authentifizierung des Gateway ist fehlgeschlagen.
+ Server-Adresse konnte nicht aufgelöst werden.
+ Server ist nicht erreichbar.
+ Authentifizierung des Servers ist fehlgeschlagen.
Benutzerauthentifizierung ist fehlgeschlagen.
Sicherheitsassessment ist fehlgeschlagen.
Unbekannter Fehler während des Verbindens.
diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml
index fb2aba003..26387190b 100644
--- a/src/frontends/android/app/src/main/res/values-pl/strings.xml
+++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml
@@ -50,8 +50,8 @@
Zapisz
Anuluj
Nazwa profilu:
- (użyj adresu bramki)
- Bramka:
+ (użyj adresu serwer)
+ Serwer:
Typ:
Użytkownik:
Hasło:
@@ -71,14 +71,14 @@
Block IPv4 traffic not destined for the VPN
Block IPv6 traffic not destined for the VPN
- Wprowadź adres bramki
+ Wprowadź adres serwer
Wprowadź swoją nazwę użytkownika
Nie wybrano żadnego certyfikatu CA
Wybierz lub uaktywnij jeden Wybierz automatycznie
Please enter a number in the range from %1$d - %2$d
EAP-TNC may affect your privacy
- Device data is sent to the gateway operator
- <p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b>
+ Device data is sent to the server operator
+ <p>Trusted Network Connect (TNC) allows server operators to assess the health of a client device.</p><p>For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the server\'s identity.</b>
Certyfikaty CA
@@ -116,9 +116,9 @@
Wprowadż hasło
Połącz
Nie udało się utworzyć tunelu VPN:
- Nie znaleziono adresu bramki
- Bramka jest nieosiągalna
- Błąd przy weryfikacji bramki
+ Nie znaleziono adresu serwer
+ Serwer jest nieosiągalna
+ Błąd przy weryfikacji serwer
Błąd przy autoryzacji użytkownika
Security assessment failed.
Nieznany błąd w czasie połączenia
diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml
index eabfc084b..ec9d66334 100644
--- a/src/frontends/android/app/src/main/res/values-ru/strings.xml
+++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml
@@ -47,8 +47,8 @@
Сохранить
Отмена
Название профиля:
- (адрес шлюза)
- Шлюз:
+ (адрес cервер)
+ Сервер:
Тип:
Логин:
Пароль:
@@ -68,14 +68,14 @@
Block IPv4 traffic not destined for the VPN
Block IPv6 traffic not destined for the VPN
- Пожалуйста введите адрес шлюза
+ Пожалуйста введите адрес cервер
Пожалуйста введите имя пользователя
Не выбран сертификат CA
Пожалуйста выберите один Выбрать автоматически
Please enter a number in the range from %1$d - %2$d
EAP-TNC may affect your privacy
- Device data is sent to the gateway operator
- <p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b>
+ Device data is sent to the server operator
+ Trusted Network Connect (TNC) allows server operators to assess the health of a client device.For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.
Any data will be sent only after verifying the server\'s identity.]]>
Сертификаты CA
@@ -113,9 +113,9 @@
Введите пароль для соединения
Соединить
Ошибка подключения к VPN:
- Не найден адрес шлюза.
- Шлюз недоступен.
- Ошибка авторизаци при подключении к шлюзу.
+ Не найден адрес сервер.
+ Сервер недоступен.
+ Ошибка авторизаци при подключении к сервер.
Ошибка авторизации пользователя.
Security assessment failed.
Неизвестная ошибка.
diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml
index d7c238370..a5e668b84 100644
--- a/src/frontends/android/app/src/main/res/values-ua/strings.xml
+++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml
@@ -48,8 +48,8 @@
Зберегти
Відміна
Назва профілю:
- (використовувати адресу шлюза)
- Шлюз:
+ (використовувати адресу cервер)
+ Сервер:
Тип:
Логін:
Пароль:
@@ -69,14 +69,14 @@
Block IPv4 traffic not destined for the VPN
Block IPv6 traffic not destined for the VPN
- Введіть адресу шлюза тут
+ Введіть адресу cервер тут
Введіть ім\'я користувача тут
Не вибрано сертифікат CA
Будь ласка виберіть один Вибрати автоматично
Please enter a number in the range from %1$d - %2$d
EAP-TNC may affect your privacy
- Device data is sent to the gateway operator
- <p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b>
+ Device data is sent to the server operator
+ Trusted Network Connect (TNC) allows server operators to assess the health of a client device.For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.
Any data will be sent only after verifying the server\'s identity.]]>
Сертифікати CA
@@ -114,9 +114,9 @@
Введіть пароль для з\'єднання
Підключити
Помилка підлючення VPN:
- Помилка пошуку адреси шлюза.
- Немає зв\'язку зі шлюзом.
- Помилка перевірки данних аутентифікації шлюза.
+ Помилка пошуку адреси сервер.
+ Сервер зв\'язку зі шлюзом.
+ Помилка перевірки данних аутентифікації сервер.
Помилка аутентифікації користувача.
Security assessment failed.
Невідома помилка під час підключення.
diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml
index 5c8ebab57..2b0049f0a 100644
--- a/src/frontends/android/app/src/main/res/values/strings.xml
+++ b/src/frontends/android/app/src/main/res/values/strings.xml
@@ -1,9 +1,9 @@
- Please enter the gateway address here
+ Please enter the server address here
Please enter your username here
No CA certificate selected
Please select one or activate Select automatically
Please enter a number in the range from %1$d - %2$d
EAP-TNC may affect your privacy
- Device data is sent to the gateway operator
- <p>Trusted Network Connect (TNC) allows gateway operators to assess the health of a client device.</p><p>For that purpose the gateway operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.</p><b>Any data will be sent only after verifying the gateway\'s identity.</b>
+ Device data is sent to the server operator
+ Trusted Network Connect (TNC) allows server operators to assess the health of a client device.For that purpose the server operator may request data such as a unique identifier, a list of installed packages, system settings, or cryptographic checksums of files.
Any data will be sent only after verifying the server\'s identity.]]>
CA certificates
@@ -116,9 +116,9 @@
Enter password to connect
Connect
Failed to establish VPN:
- Gateway address lookup failed.
- Gateway is unreachable.
- Verifying gateway authentication failed.
+ Server address lookup failed.
+ Server is unreachable.
+ Verifying server authentication failed.
User authentication failed.
Security assessment failed.
Unspecified failure while connecting.
From 2a68938b2ed06e6cbe3b356875d8baef334275ce Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Fri, 15 Apr 2016 13:21:22 +0200
Subject: [PATCH 14/15] android: Use Activity as context for VpnProfileAdapter
to fix theme
When using the application context theme customizations wouldn't get
applied for some reason.
---
.../org/strongswan/android/ui/VpnProfileListFragment.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java
index fb684b53d..a23df054b 100644
--- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java
+++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileListFragment.java
@@ -109,15 +109,13 @@ public class VpnProfileListFragment extends Fragment
setHasOptionsMenu(true);
}
- Context context = getActivity().getApplicationContext();
-
mDataSource = new VpnProfileDataSource(this.getActivity());
mDataSource.open();
/* cached list of profiles used as backend for the ListView */
mVpnProfiles = mDataSource.getAllVpnProfiles();
- mListAdapter = new VpnProfileAdapter(context, R.layout.profile_list_item, mVpnProfiles);
+ mListAdapter = new VpnProfileAdapter(getActivity(), R.layout.profile_list_item, mVpnProfiles);
}
@Override
From 90172b66c48372b93125b06ff0353c0d791ffb32 Mon Sep 17 00:00:00 2001
From: Tobias Brunner
Date: Tue, 26 Apr 2016 16:29:35 +0200
Subject: [PATCH 15/15] android: Fix color of lists and buttons on older
platforms
This adds a workaround for an issue on older platforms where the list is
not properly styled with colorAccent. Similarly applies to borderless buttons.
---
.../res/drawable/activated_background.xml | 29 +++++++++++++++++++
.../app/src/main/res/values-v15/styles.xml | 2 ++
.../app/src/main/res/values/colors.xml | 3 ++
3 files changed, 34 insertions(+)
create mode 100644 src/frontends/android/app/src/main/res/drawable/activated_background.xml
diff --git a/src/frontends/android/app/src/main/res/drawable/activated_background.xml b/src/frontends/android/app/src/main/res/drawable/activated_background.xml
new file mode 100644
index 000000000..04cf6effb
--- /dev/null
+++ b/src/frontends/android/app/src/main/res/drawable/activated_background.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/frontends/android/app/src/main/res/values-v15/styles.xml b/src/frontends/android/app/src/main/res/values-v15/styles.xml
index 90c58a7bb..bf40c3f26 100644
--- a/src/frontends/android/app/src/main/res/values-v15/styles.xml
+++ b/src/frontends/android/app/src/main/res/values-v15/styles.xml
@@ -16,6 +16,8 @@