Merge branch 'android-14'
Updates target SDK to Android 14 (34) and fixes compatibility issues.
This commit is contained in:
@@ -7,10 +7,10 @@ android {
|
||||
applicationId "org.strongswan.android"
|
||||
compileSdk 34
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 33
|
||||
targetSdkVersion 34
|
||||
|
||||
versionCode 82
|
||||
versionName "2.5.1"
|
||||
versionCode 84
|
||||
versionName "2.5.2"
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
@@ -45,10 +45,10 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.8.3'
|
||||
implementation 'androidx.preference:preference:1.2.1'
|
||||
implementation 'com.google.android.material:material:1.10.0'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.assertj:assertj-core:3.24.2'
|
||||
testImplementation 'org.mockito:mockito-core:5.8.0'
|
||||
|
||||
@@ -22,9 +22,11 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<!-- necessary to allow users to select ex-/included apps and EAP-TNC -->
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
@@ -176,10 +178,14 @@
|
||||
<service
|
||||
android:name=".logic.CharonVpnService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="specialUse"
|
||||
android:permission="android.permission.BIND_VPN_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.VpnService" />
|
||||
</intent-filter>
|
||||
<property
|
||||
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="VpnService instance"/>
|
||||
</service>
|
||||
<service
|
||||
android:name=".ui.VpnTileService"
|
||||
|
||||
+10
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.strongswan.android.logic;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -37,6 +38,7 @@ public class Scheduler extends BroadcastReceiver
|
||||
private final AlarmManager mManager;
|
||||
private final PriorityQueue<ScheduledJob> mJobs;
|
||||
|
||||
@SuppressLint("UnspecifiedRegisterReceiverFlag")
|
||||
public Scheduler(Context context)
|
||||
{
|
||||
mContext = context;
|
||||
@@ -45,7 +47,14 @@ public class Scheduler extends BroadcastReceiver
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(EXECUTE_JOB);
|
||||
mContext.registerReceiver(this, filter);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
|
||||
{
|
||||
mContext.registerReceiver(this, filter, Context.RECEIVER_NOT_EXPORTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
mContext.registerReceiver(this, filter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+34
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2015 Tobias Brunner
|
||||
* Copyright (C) 2012-2024 Tobias Brunner
|
||||
* Copyright (C) 2012 Giuliano Grassi
|
||||
* Copyright (C) 2012 Ralf Sager
|
||||
*
|
||||
@@ -20,6 +20,8 @@ package org.strongswan.android.logic;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.cert.Certificate;
|
||||
@@ -27,10 +29,9 @@ import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
public class TrustedCertificateManager extends Observable
|
||||
public class TrustedCertificateManager
|
||||
{
|
||||
private static final String TAG = TrustedCertificateManager.class.getSimpleName();
|
||||
private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
|
||||
@@ -38,6 +39,7 @@ public class TrustedCertificateManager extends Observable
|
||||
private volatile boolean mReload;
|
||||
private boolean mLoaded;
|
||||
private final ArrayList<KeyStore> mKeyStores = new ArrayList<KeyStore>();
|
||||
private PropertyChangeSupport mObservers = new PropertyChangeSupport(this);
|
||||
|
||||
public enum TrustedCertificateSource
|
||||
{
|
||||
@@ -98,6 +100,35 @@ public class TrustedCertificateManager extends Observable
|
||||
return Singleton.mInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an observer for changes to the trusted certificate store. There will
|
||||
* be a "storeChanged" property "change" when anything in the store changed.
|
||||
*
|
||||
* @param observer observer to add
|
||||
*/
|
||||
public void addObserver(PropertyChangeListener observer)
|
||||
{
|
||||
mObservers.addPropertyChangeListener(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an observer for changes to the trusted certificate store.
|
||||
*
|
||||
* @param observer observer to remove
|
||||
*/
|
||||
public void deleteObserver(PropertyChangeListener observer)
|
||||
{
|
||||
mObservers.removePropertyChangeListener(observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a fake property with a forced change to notify observers.
|
||||
*/
|
||||
private void notifyObservers()
|
||||
{
|
||||
mObservers.firePropertyChange("storeChanged", false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the current load state so that the next call to load()
|
||||
* will force a reload of the cached CA certificates.
|
||||
@@ -110,7 +141,6 @@ public class TrustedCertificateManager extends Observable
|
||||
{
|
||||
Log.d(TAG, "Force reload of cached CA certificates on next load");
|
||||
this.mReload = true;
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
return this;
|
||||
}
|
||||
@@ -152,7 +182,6 @@ public class TrustedCertificateManager extends Observable
|
||||
this.mCACerts = certs;
|
||||
if (!this.mLoaded)
|
||||
{
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
this.mLoaded = true;
|
||||
}
|
||||
|
||||
+4
-4
@@ -33,14 +33,14 @@ import org.strongswan.android.logic.TrustedCertificateManager.TrustedCertificate
|
||||
import org.strongswan.android.security.TrustedCertificateEntry;
|
||||
import org.strongswan.android.ui.adapter.TrustedCertificateAdapter;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
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 java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -249,12 +249,12 @@ public class TrustedCertificateListFragment extends ListFragment implements Load
|
||||
}
|
||||
}
|
||||
|
||||
private class TrustedCertificateManagerObserver implements Observer
|
||||
private class TrustedCertificateManagerObserver implements PropertyChangeListener
|
||||
{
|
||||
private ForceLoadContentObserver mContentObserver = new ForceLoadContentObserver();
|
||||
|
||||
@Override
|
||||
public void update(Observable observable, Object data)
|
||||
public void propertyChange(PropertyChangeEvent evt)
|
||||
{
|
||||
mContentObserver.onChange(false);
|
||||
}
|
||||
|
||||
+1
-1
@@ -380,7 +380,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity
|
||||
{
|
||||
Intent intent = new Intent(VpnProfileDetailActivity.this, SelectedApplicationsActivity.class);
|
||||
intent.putExtra(VpnProfileDataSource.KEY_SELECTED_APPS_LIST, new ArrayList<>(mSelectedApps));
|
||||
intent.putExtra(VpnProfileDataSource.KEY_READ_ONLY, mProfile.isReadOnly());
|
||||
intent.putExtra(VpnProfileDataSource.KEY_READ_ONLY, mProfile != null && mProfile.isReadOnly());
|
||||
mSelectApplications.launch(intent);
|
||||
}
|
||||
});
|
||||
|
||||
+29
-2
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.strongswan.android.ui;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@@ -26,6 +28,7 @@ import android.content.SharedPreferences;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
|
||||
@@ -127,6 +130,7 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
||||
return mDataSource != null ? mDataSource.getVpnProfile(uuid) : null;
|
||||
}
|
||||
|
||||
@SuppressLint("StartActivityAndCollapseDeprecated")
|
||||
@Override
|
||||
public void onClick()
|
||||
{
|
||||
@@ -177,10 +181,26 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
||||
if (profile.getVpnType().has(VpnType.VpnTypeFeature.USER_PASS) &&
|
||||
profile.getPassword() == null)
|
||||
{ /* the user will have to enter the password, so collapse the drawer */
|
||||
startActivityAndCollapse(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
{
|
||||
startActivityAndCollapse(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE));
|
||||
}
|
||||
else
|
||||
{
|
||||
startActivityAndCollapse(intent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* a bug in Android 14+ requires us to request this permission in
|
||||
* order to start the activity from this "background" service */
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && !Settings.canDrawOverlays(this))
|
||||
{
|
||||
Intent permIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||
permIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityAndCollapse(PendingIntent.getActivity(this, 0, permIntent, PendingIntent.FLAG_IMMUTABLE));
|
||||
return;
|
||||
}
|
||||
startActivity(intent);
|
||||
}
|
||||
return;
|
||||
@@ -188,7 +208,14 @@ public class VpnTileService extends TileService implements VpnStateService.VpnSt
|
||||
}
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityAndCollapse(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
{
|
||||
startActivityAndCollapse(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE));
|
||||
}
|
||||
else
|
||||
{
|
||||
startActivityAndCollapse(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+12
-12
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.strongswan.android.ui.widget;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.text.Editable;
|
||||
@@ -33,8 +35,6 @@ import com.google.android.material.textfield.TextInputLayout;
|
||||
import org.strongswan.android.R;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.ViewPropertyAnimatorListenerAdapter;
|
||||
|
||||
/**
|
||||
* Layout that extends {@link TextInputLayout} with a helper text
|
||||
@@ -113,8 +113,8 @@ public class TextInputLayoutHelper extends TextInputLayout
|
||||
showHelper(hasFocus);
|
||||
}
|
||||
});
|
||||
ViewCompat.setPaddingRelative(mHelperContainer, ViewCompat.getPaddingStart(text),
|
||||
0, ViewCompat.getPaddingEnd(text), text.getPaddingBottom());
|
||||
mHelperContainer.setPaddingRelative(text.getPaddingStart(), 0,
|
||||
text.getPaddingEnd(), text.getPaddingBottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,27 +158,27 @@ public class TextInputLayoutHelper extends TextInputLayout
|
||||
}
|
||||
if (show)
|
||||
{
|
||||
ViewCompat.animate(mHelperContainer)
|
||||
mHelperContainer.animate()
|
||||
.alpha(1f)
|
||||
.setDuration(200)
|
||||
.setListener(new ViewPropertyAnimatorListenerAdapter() {
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(View view)
|
||||
public void onAnimationStart(Animator animation)
|
||||
{
|
||||
view.setVisibility(View.VISIBLE);
|
||||
mHelperContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewCompat.animate(mHelperContainer)
|
||||
mHelperContainer.animate()
|
||||
.alpha(0f)
|
||||
.setDuration(200)
|
||||
.setListener(new ViewPropertyAnimatorListenerAdapter() {
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(View view)
|
||||
public void onAnimationEnd(Animator animation)
|
||||
{
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
mHelperContainer.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
# 2.5.2 #
|
||||
|
||||
- Ziel-SDK auf Android 14 erhöht
|
||||
- Wegen eines Bugs in Android 14 ist eine zusätzliche Permission ist nötig, um von der Status-Kachel eine Verbindung im Hintergrund zu starten
|
||||
- Fixt einen Crash beim Öffnen der Liste installierter Apps in neuen Profilen
|
||||
|
||||
# 2.5.1 #
|
||||
|
||||
- Fix für existierende Verknüpfungen und Automatisierung via Intents
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
# 2.5.2 #
|
||||
|
||||
- Increased target SDK to Android 14
|
||||
- Due to a bug in Android 14, a new permission is necessary to start a profile in the background from the status tile
|
||||
- Fix crash when listing installed apps for new profiles
|
||||
|
||||
# 2.5.1 #
|
||||
|
||||
- Fix for existing shortcuts and automation via Intents
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<!-- Managed configuration, VPN profile -->
|
||||
<string name="managed_config_uuid_title">Unique identifier</string>
|
||||
<string name="managed_config_uuid_description">Unique identifier of the VPN profile. Version 4 UUIDs (random-generated) are recommended</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label</string>
|
||||
<string name="managed_config_name_title">@string/profile_name_label_simple</string>
|
||||
<string name="managed_config_name_description">@string/profile_name_hint</string>
|
||||
<string name="managed_config_vpn_type_title">@string/profile_vpn_type_label</string>
|
||||
<string name="managed_config_vpn_type_description">The type of client authentication used by the VPN profile</string>
|
||||
|
||||
@@ -4,7 +4,7 @@ buildscript {
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.2.0'
|
||||
classpath 'com.android.tools.build:gradle:8.5.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
|
||||
|
||||
Reference in New Issue
Block a user