mirror of
https://github.com/schwabe/ics-openvpn.git
synced 2024-09-20 03:52:27 +02:00
Use JobScheduler as backup to keep an active VPN active
This should restart it in some instances when the app dies or gets killed.
This commit is contained in:
parent
3211fed064
commit
8fe897a3c7
@ -96,6 +96,11 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:name=".core.keepVPNAlive"
|
||||
android:process=":openvpn"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE"/>
|
||||
|
||||
|
||||
<activity
|
||||
android:name=".LaunchVPN"
|
||||
|
@ -14,6 +14,8 @@ import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.UiModeManager;
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -34,12 +36,12 @@ import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.RemoteException;
|
||||
import android.system.OsConstants;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -227,6 +229,10 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
|
||||
}
|
||||
|
||||
private void endVpnService() {
|
||||
if (!isAlwaysOn()) {
|
||||
/* if we should be an always on VPN, keep the timer running */
|
||||
keepVPNAlive.unscheduleKeepVPNAliveJobService(this);
|
||||
}
|
||||
synchronized (mProcessLock) {
|
||||
mProcessThread = null;
|
||||
}
|
||||
@ -573,6 +579,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
|
||||
|
||||
ProfileManager.setConnectedVpnProfile(this, mProfile);
|
||||
VpnStatus.setConnectedVPNProfile(mProfile.getUUIDString());
|
||||
keepVPNAlive.scheduleKeepVPNAliveJobService(this, vp);
|
||||
|
||||
String nativeLibraryDirectory = getApplicationInfo().nativeLibraryDir;
|
||||
String tmpDir;
|
||||
|
106
main/src/main/java/de/blinkt/openvpn/core/keepVPNAlive.java
Normal file
106
main/src/main/java/de/blinkt/openvpn/core/keepVPNAlive.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2023 Arne Schwabe
|
||||
* Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt
|
||||
*/
|
||||
|
||||
package de.blinkt.openvpn.core;
|
||||
|
||||
import android.app.job.JobInfo;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobScheduler;
|
||||
import android.app.job.JobService;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.VpnService;
|
||||
import android.os.PersistableBundle;
|
||||
|
||||
import de.blinkt.openvpn.LaunchVPN;
|
||||
import de.blinkt.openvpn.VpnProfile;
|
||||
|
||||
/**
|
||||
* This is a task that is run periodically to restart the VPN if tit has died for
|
||||
* some reason in the background
|
||||
*/
|
||||
public class keepVPNAlive extends JobService implements VpnStatus.StateListener {
|
||||
private ConnectionStatus mLevel = ConnectionStatus.UNKNOWN_LEVEL;
|
||||
private static final int JOBID_KEEPVPNALIVE = 6231;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
VpnStatus.addStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
VpnStatus.removeStateListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters jobParameters) {
|
||||
if (mLevel == ConnectionStatus.UNKNOWN_LEVEL || mLevel == ConnectionStatus.LEVEL_NOTCONNECTED) {
|
||||
String vpnUUID = jobParameters.getExtras().getString(LaunchVPN.EXTRA_KEY);
|
||||
VpnProfile vp = ProfileManager.get(this, vpnUUID);
|
||||
if (vp == null) {
|
||||
VpnStatus.logError("Keepalive service cannot find VPN");
|
||||
unscheduleKeepVPNAliveJobService(this);
|
||||
return false;
|
||||
}
|
||||
VPNLaunchHelper.startOpenVpn(vp, getApplicationContext(), "VPN keep alive Job");
|
||||
} else {
|
||||
VpnStatus.logDebug("Keepalive service called but VPN still connected.");
|
||||
}
|
||||
|
||||
/* The job has finished */
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters jobParameters) {
|
||||
/* not doing anything */
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(String state, String logmessage,
|
||||
int localizedResId, ConnectionStatus level, Intent Intent) {
|
||||
mLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConnectedVPN(String uuid) {
|
||||
|
||||
}
|
||||
|
||||
public static void scheduleKeepVPNAliveJobService(Context c, VpnProfile vp) {
|
||||
ComponentName keepVPNAliveComponent = new ComponentName(c, keepVPNAlive.class);
|
||||
JobInfo.Builder jib = new JobInfo.Builder(JOBID_KEEPVPNALIVE, keepVPNAliveComponent);
|
||||
|
||||
/* set the VPN that should be restarted if we get killed */
|
||||
PersistableBundle extraBundle = new PersistableBundle();
|
||||
extraBundle.putString(de.blinkt.openvpn.LaunchVPN.EXTRA_KEY, vp.getUUIDString());
|
||||
jib.setExtras(extraBundle);
|
||||
|
||||
/* periodic timing */
|
||||
/* The current limits are 15 minutes and 5 minutes for flex and periodic timer
|
||||
* but we use a minimum of 5 minutes and 2 minutes to avoid problems if there is some
|
||||
* strange Android build that allows lower lmits.
|
||||
*/
|
||||
long initervalMillis = Math.max(JobInfo.getMinPeriodMillis(), 5 * 60 * 1000L);
|
||||
long flexMillis = Math.max(JobInfo.getMinFlexMillis(), 2 * 60 * 1000L);
|
||||
jib.setPeriodic(initervalMillis, flexMillis);
|
||||
jib.setPersisted(true);
|
||||
|
||||
JobScheduler jobScheduler = c.getSystemService(JobScheduler.class);
|
||||
jobScheduler.schedule(jib.build());
|
||||
VpnStatus.logDebug("Scheduling VPN keep alive for VPN " + vp.mName);
|
||||
}
|
||||
|
||||
public static void unscheduleKeepVPNAliveJobService(Context c) {
|
||||
JobScheduler jobScheduler = c.getSystemService(JobScheduler.class);
|
||||
jobScheduler.cancel(JOBID_KEEPVPNALIVE);
|
||||
VpnStatus.logDebug("Unscheduling VPN keep alive");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user