summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2021-02-24 23:23:47 +0100
committercyBerta <cyberta@riseup.net>2021-02-26 10:03:31 +0100
commit49b1539722063a53573fb859f543967ebff5ce14 (patch)
tree2cc2d13e3250faf91b977acc2c18676af80c6425
parentcf6e6f355cc71e43c69f20716a7aa6fd0d6990ce (diff)
implement service binding in order to fix remote service exception during foreground service start
-rw-r--r--app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl2
-rw-r--r--app/src/main/java/de/blinkt/openvpn/LaunchVPN.java3
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java25
-rw-r--r--app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java17
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java40
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java52
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java20
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/VpnNotificationManager.java71
12 files changed, 154 insertions, 98 deletions
diff --git a/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl b/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
index 293c2b6d..98cc3e42 100644
--- a/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
+++ b/app/src/main/aidl/de/blinkt/openvpn/core/IOpenVPNServiceInternal.aidl
@@ -23,4 +23,6 @@ interface IOpenVPNServiceInternal {
boolean isVpnRunning();
+ void startWithForegroundNotification();
+
}
diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
index b148d04d..3f45f391 100644
--- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
+++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
@@ -25,6 +25,7 @@ import de.blinkt.openvpn.core.VPNLaunchHelper;
import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.base.MainActivity;
import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.eip.EipCommand;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
@@ -119,7 +120,7 @@ public class LaunchVPN extends Activity {
if(!mhideLog && showLogWindow)
showLogWindow();
- VPNLaunchHelper.startOpenVpn(mSelectedProfile, getBaseContext());
+ EipCommand.launchVPNProfile(getApplicationContext(), mSelectedProfile);
finish();
} else if (resultCode == Activity.RESULT_CANCELED) {
diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
index 1670c0be..6be8db25 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java
@@ -46,6 +46,7 @@ import de.blinkt.openvpn.core.VpnStatus.StateListener;
import de.blinkt.openvpn.core.connection.Connection;
import de.blinkt.openvpn.core.connection.Obfs4Connection;
import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.eip.VpnNotificationManager;
import se.leap.bitmaskclient.firewall.FirewallManager;
import se.leap.bitmaskclient.pluggableTransports.Shapeshifter;
@@ -92,11 +93,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
private Shapeshifter shapeshifter;
private FirewallManager firewallManager;
- private static final int PRIORITY_MIN = -2;
- private static final int PRIORITY_DEFAULT = 0;
- private static final int PRIORITY_MAX = 2;
-
-
private final IBinder mBinder = new IOpenVPNServiceInternal.Stub() {
@Override
@@ -118,6 +114,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public boolean isVpnRunning() throws RemoteException {
return OpenVPNService.this.isVpnRunning();
}
+
+ @Override
+ public void startWithForegroundNotification() throws RemoteException {
+ OpenVPNService.this.startWithForegroundNotification();
+ }
};
// From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
@@ -280,18 +281,11 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
}
+ @Override
public void startWithForegroundNotification() {
// Always show notification here to avoid problem with startForeground timeout
notificationManager.createOpenVpnNotificationChannel();
- notificationManager.buildOpenVpnNotification(
- mProfile != null ? mProfile.mName : "",
- mProfile != null && mProfile.mUsePluggableTransports,
- VpnStatus.getLastCleanLogMessage(this),
- VpnStatus.getLastCleanLogMessage(this),
- ConnectionStatus.LEVEL_START,
- 0,
- NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- this::onNotificationBuild);
+ notificationManager.buildForegroundServiceNotification(EipStatus.getInstance().getLevel(), this::onNotificationBuild);
}
@Override
@@ -539,7 +533,6 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
public void onCreate() {
super.onCreate();
notificationManager = new VpnNotificationManager(this);
- startWithForegroundNotification();
firewallManager = new FirewallManager(this, true);
}
@@ -558,7 +551,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac
VpnStatus.removeStateListener(this);
VpnStatus.flushLog();
firewallManager.onDestroy();
- notificationManager.cancelAllNotifications();
+ notificationManager.deleteOpenvpnNotificationChannel();
}
private String getTunConfigString() {
diff --git a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
index 7c742746..540ca043 100644
--- a/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
+++ b/app/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java
@@ -7,7 +7,6 @@ package de.blinkt.openvpn.core;
import android.annotation.TargetApi;
import android.content.Context;
-import android.content.Intent;
import android.os.Build;
import java.io.File;
@@ -18,7 +17,6 @@ import java.util.Arrays;
import java.util.Vector;
import se.leap.bitmaskclient.R;
-import de.blinkt.openvpn.VpnProfile;
public class VPNLaunchHelper {
private static final String MININONPIEVPN = "nopie_openvpn";
@@ -120,7 +118,6 @@ public class VPNLaunchHelper {
return false;
}
-
return true;
} catch (IOException e) {
VpnStatus.logException(e);
@@ -129,20 +126,6 @@ public class VPNLaunchHelper {
}
-
- public static void startOpenVpn(VpnProfile startprofile, Context context) {
- Intent startVPN = startprofile.prepareStartService(context);
- if (startVPN != null) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
- //noinspection NewApi
- context.startForegroundService(startVPN);
- else
- context.startService(startVPN);
-
- }
- }
-
-
public static String getConfigFilePath(Context context) {
return context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
index 676e6c82..a7a14ed0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java
@@ -20,13 +20,14 @@ package se.leap.bitmaskclient.base;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
+import android.util.Log;
+
import androidx.annotation.StringRes;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
-import androidx.appcompat.app.ActionBar;
-import androidx.appcompat.app.AppCompatActivity;
-import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
@@ -35,24 +36,27 @@ import java.util.Observable;
import java.util.Observer;
import se.leap.bitmaskclient.R;
-import se.leap.bitmaskclient.base.fragments.NavigationDrawerFragment;
-import se.leap.bitmaskclient.eip.EIP;
-import se.leap.bitmaskclient.eip.EipCommand;
-import se.leap.bitmaskclient.eip.EipSetupListener;
-import se.leap.bitmaskclient.eip.EipSetupObserver;
import se.leap.bitmaskclient.base.fragments.EipFragment;
import se.leap.bitmaskclient.base.fragments.ExcludeAppsFragment;
import se.leap.bitmaskclient.base.fragments.LogFragment;
+import se.leap.bitmaskclient.base.fragments.MainActivityErrorDialog;
+import se.leap.bitmaskclient.base.fragments.NavigationDrawerFragment;
import se.leap.bitmaskclient.base.models.Provider;
import se.leap.bitmaskclient.base.models.ProviderObservable;
-import se.leap.bitmaskclient.providersetup.models.LeapSRPSession;
-import se.leap.bitmaskclient.providersetup.activities.LoginActivity;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
-import se.leap.bitmaskclient.base.fragments.MainActivityErrorDialog;
+import se.leap.bitmaskclient.eip.EIP;
+import se.leap.bitmaskclient.eip.EipCommand;
+import se.leap.bitmaskclient.eip.EipSetupListener;
+import se.leap.bitmaskclient.eip.EipSetupObserver;
+import se.leap.bitmaskclient.providersetup.activities.LoginActivity;
+import se.leap.bitmaskclient.providersetup.models.LeapSRPSession;
+import static se.leap.bitmaskclient.R.string.downloading_vpn_certificate_failed;
+import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message;
import static se.leap.bitmaskclient.base.models.Constants.ASK_TO_CANCEL_VPN;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_CODE;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_LAUNCH_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.EIP_REQUEST;
@@ -61,16 +65,14 @@ import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN;
import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER;
import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences;
+import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE;
+import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORID;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_EIP_SERVICE;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE;
-import static se.leap.bitmaskclient.R.string.downloading_vpn_certificate_failed;
-import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message;
-import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE;
-import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences;
public class MainActivity extends AppCompatActivity implements EipSetupListener, Observer, ExcludeAppsFragment.ExcludedAppsCallback {
@@ -259,6 +261,12 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
showMainActivityErrorDialog(getString(R.string.vpn_error_establish), ERROR_VPN_PREPARE);
}
break;
+ case EIP_ACTION_LAUNCH_VPN:
+ if (resultCode == RESULT_CANCELED) {
+ String error = resultData.getString(ERRORS);
+ showMainActivityErrorDialog(error);
+ }
+ break;
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
index 4ff80ea6..5d88d864 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java
@@ -52,6 +52,7 @@ import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
+import de.blinkt.openvpn.core.ConnectionStatus;
import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.VpnStatus;
@@ -319,10 +320,11 @@ public class EipFragment extends Fragment implements Observer {
} else {
EipCommand.startVPN(context.getApplicationContext(), false);
}
- vpnStateImage.showProgress();
+ EipStatus.getInstance().updateState("RECONNECTING", "", 0, ConnectionStatus.LEVEL_START);
+ /* vpnStateImage.showProgress();
routedText.setVisibility(GONE);
vpnRoute.setVisibility(GONE);
- colorBackgroundALittle();
+ colorBackgroundALittle();*/
}
protected void stopEipIfPossible() {
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
index e60019fc..8adf7744 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java
@@ -80,7 +80,7 @@ public interface Constants {
String EIP_ACTION_START_BLOCKING_VPN = "se.leap.bitmaskclient.EIP_ACTION_START_BLOCKING_VPN";
String EIP_ACTION_STOP_BLOCKING_VPN = "se.leap.bitmaskclient.EIP_ACTION_STOP_BLOCKING_VPN";
String EIP_ACTION_PREPARE_VPN = "se.leap.bitmaskclient.EIP_ACTION_PREPARE_VPN";
- String EIP_ACTION_CONFIGURE_TETHERING = "se.leap.bitmaskclient.EIP_ACTION_CONFIGURE_TETHERING";
+ String EIP_ACTION_LAUNCH_VPN = "se.leap.bitmaskclient.EIP_ACTION_LAUNCH_VPN";
String EIP_RECEIVER = "EIP.RECEIVER";
String EIP_REQUEST = "EIP.REQUEST";
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
index 66b7c6cf..ae6bdf39 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -22,16 +22,18 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import android.util.Log;
+
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.WorkerThread;
import androidx.core.app.JobIntentService;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
@@ -49,20 +51,23 @@ import de.blinkt.openvpn.core.IOpenVPNServiceInternal;
import de.blinkt.openvpn.core.OpenVPNService;
import de.blinkt.openvpn.core.VpnStatus;
import de.blinkt.openvpn.core.connection.Connection;
+import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.OnBootReceiver;
import se.leap.bitmaskclient.base.models.ProviderObservable;
-import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4;
import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN;
+import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid;
+import static se.leap.bitmaskclient.R.string.warning_client_parsing_error_gateways;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_CONFIGURE_TETHERING;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_IS_RUNNING;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_LAUNCH_VPN;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_BLOCKING_VPN;
@@ -75,13 +80,11 @@ import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES;
-import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid;
-import static se.leap.bitmaskclient.R.string.warning_client_parsing_error_gateways;
+import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread;
+import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePluggableTransports;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.NO_MORE_GATEWAYS;
import static se.leap.bitmaskclient.eip.EipResultBroadcast.tellToReceiverOrBroadcast;
-import static se.leap.bitmaskclient.base.utils.ConfigHelper.ensureNotOnMainThread;
-import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePluggableTransports;
/**
* EIP is the abstract base class for interacting with and managing the Encrypted
@@ -116,7 +119,8 @@ public final class EIP extends JobIntentService implements Observer {
UNKNOWN,
ERROR_INVALID_VPN_CERTIFICATE,
NO_MORE_GATEWAYS,
- ERROR_VPN_PREPARE
+ ERROR_VPN_PREPARE,
+ ERROR_INVALID_PROFILE
}
/**
@@ -195,8 +199,9 @@ public final class EIP extends JobIntentService implements Observer {
disconnect();
earlyRoutes();
break;
- case EIP_ACTION_CONFIGURE_TETHERING:
- Log.d(TAG, "TODO: implement tethering configuration");
+ case EIP_ACTION_LAUNCH_VPN:
+ VpnProfile profile = (VpnProfile) intent.getSerializableExtra(PROVIDER_PROFILE);
+ launchVpn(profile);
break;
}
}
@@ -409,6 +414,33 @@ public final class EIP extends JobIntentService implements Observer {
return false;
}
+ /**
+ * creates an OpenVpnServiceConnection if necessary and starts OpenVPN as foreground service
+ */
+ private void launchVpn(VpnProfile vpnProfile) {
+ Bundle result = new Bundle();
+
+ Intent startVPN = vpnProfile.prepareStartService(getApplicationContext());
+ if (startVPN != null) {
+ try {
+ initOpenVpnServiceConnection();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ //noinspection NewApi
+ getApplicationContext().startForegroundService(startVPN);
+ openVpnServiceConnection.getService().startWithForegroundNotification();
+ } else {
+ getApplicationContext().startService(startVPN);
+ }
+ } catch (InterruptedException | IllegalStateException | RemoteException e) {
+ setErrorResult(result, R.string.vpn_error_establish, null);
+ tellToReceiverOrBroadcast(this.getApplicationContext(), EIP_ACTION_PREPARE_VPN, RESULT_CANCELED);
+ }
+ } else {
+ setErrorResult(result, R.string.vpn_error_establish, null);
+ tellToReceiverOrBroadcast(this.getApplicationContext(), EIP_ACTION_PREPARE_VPN, RESULT_CANCELED);
+ }
+ }
+
private @StringRes int getStringResourceForNoMoreGateways() {
if (ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports()) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
index 0650e8cd..7f330f0d 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipCommand.java
@@ -9,14 +9,17 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import de.blinkt.openvpn.VpnProfile;
+
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
-import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_CONFIGURE_TETHERING;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_LAUNCH_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_BLOCKING_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP;
import static se.leap.bitmaskclient.base.models.Constants.EIP_EARLY_ROUTES;
import static se.leap.bitmaskclient.base.models.Constants.EIP_N_CLOSEST_GATEWAY;
import static se.leap.bitmaskclient.base.models.Constants.EIP_RECEIVER;
+import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PROFILE;
/**
* Use this class to send commands to EIP
@@ -73,6 +76,12 @@ public class EipCommand {
execute(context, EIP_ACTION_STOP);
}
+ public static void launchVPNProfile(@NonNull Context context, VpnProfile vpnProfile) {
+ Intent baseIntent = new Intent();
+ baseIntent.putExtra(PROVIDER_PROFILE, vpnProfile);
+ execute(context, EIP_ACTION_LAUNCH_VPN, null, baseIntent);
+ }
+
@VisibleForTesting
public static void stopVPN(@NonNull Context context, ResultReceiver resultReceiver) {
execute(context, EIP_ACTION_STOP, resultReceiver, null);
@@ -87,13 +96,4 @@ public class EipCommand {
execute(context, EIP_ACTION_CHECK_CERT_VALIDITY, resultReceiver, null);
}
- public static void configureTethering(@NonNull Context context) {
- execute(context, EIP_ACTION_CONFIGURE_TETHERING);
- }
-
- @VisibleForTesting
- public static void configureTethering(@NonNull Context context, ResultReceiver resultReceiver) {
- execute(context, EIP_ACTION_CONFIGURE_TETHERING);
- }
-
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
index f35e5e30..a8e71f64 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
@@ -54,6 +54,7 @@ import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_GATEWAY_SETU
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_PROVIDER_API_EVENT;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_CODE;
import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_LAUNCH_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
@@ -230,6 +231,13 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta
EipStatus.refresh();
}
break;
+ case EIP_ACTION_LAUNCH_VPN:
+ if (resultCode == RESULT_CANCELED) {
+ VpnStatus.logError("Error starting VpnService.");
+ finishGatewaySetup(false);
+ EipStatus.refresh();
+ }
+ break;
default:
break;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
index 0c46f8cd..476dda77 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java
@@ -99,6 +99,12 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat
closeFd();
}
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ notificationManager.deleteVoidVpnNotificationChannel();
+ }
+
private void stop() {
if (thread != null) {
thread.interrupt();
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnNotificationManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnNotificationManager.java
index 6fd33352..b007715b 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnNotificationManager.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnNotificationManager.java
@@ -31,7 +31,6 @@ import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.StyleSpan;
-import android.util.Log;
import android.widget.RemoteViews;
import androidx.annotation.NonNull;
@@ -50,11 +49,11 @@ import static android.os.Build.VERSION_CODES.O;
import static android.text.TextUtils.isEmpty;
import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
import static androidx.core.app.NotificationCompat.PRIORITY_MAX;
-import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_NONETWORK;
import static de.blinkt.openvpn.core.ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT;
import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT;
import static se.leap.bitmaskclient.base.models.Constants.ASK_TO_CANCEL_VPN;
+import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
/**
@@ -96,6 +95,37 @@ public class VpnNotificationManager {
);
}
+
+ public void buildForegroundServiceNotification(ConnectionStatus connectionStatus,
+ VpnServiceCallback callback) {
+ String message = "";
+ // if the app was killed by the system getLastCleanLogMessage returns an empty string
+ // because the state doesn't get persisted. We can use LEVEL_NOTCONNECTED as an indicator for
+ // that case because the openvpn service won't be connected then
+ if (connectionStatus == ConnectionStatus.LEVEL_NOTCONNECTED) {
+ message = context.getString(R.string.eip_state_not_connected);
+ } else {
+ message = VpnStatus.getLastCleanLogMessage(context);
+ }
+
+ NotificationCompat.Action.Builder actionBuilder = new NotificationCompat.Action.Builder(0,
+ context.getString(R.string.vpn_button_turn_on), getStartOpenvpnIntent());
+
+ buildVpnNotification(
+ "",
+ message,
+ null,
+ "",
+ connectionStatus,
+ OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
+ PRIORITY_DEFAULT,
+ 0,
+ getMainActivityIntent(),
+ actionBuilder.build(),
+ callback
+ );
+ }
+
public void buildOpenVpnNotification(String profileName, boolean isObfuscated, String msg,
String tickerText, ConnectionStatus status, long when,
String notificationChannelNewstatusId, VpnServiceCallback vpnServiceCallback) {
@@ -147,15 +177,6 @@ public class VpnNotificationManager {
contentIntent = getUserInputIntent(msg);
else
contentIntent = getMainActivityIntent();
-
- int priority;
- if (OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID.equals(notificationChannelNewstatusId)) {
- priority = PRIORITY_DEFAULT;
- } else {
- // background channel
- priority = PRIORITY_MIN;
- }
-
buildVpnNotification(
title,
msg,
@@ -163,7 +184,7 @@ public class VpnNotificationManager {
tickerText,
status,
notificationChannelNewstatusId,
- priority,
+ PRIORITY_DEFAULT,
when,
contentIntent,
actionBuilder.build(),
@@ -174,11 +195,17 @@ public class VpnNotificationManager {
buildOpenVpnNotification(profileName, isObfuscated, msg, tickerText, status, when, notificationChannelNewstatusId, null);
}
+ public void deleteOpenvpnNotificationChannel() {
+ compatNotificationManager.cancelAll();
+ compatNotificationManager.deleteNotificationChannel(OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
+ }
- public void cancelAllNotifications() {
+ public void deleteVoidVpnNotificationChannel() {
compatNotificationManager.cancelAll();
+ compatNotificationManager.deleteNotificationChannel(VoidVpnService.NOTIFICATION_CHANNEL_NEWSTATUS_ID);
}
+
@TargetApi(O)
public void createVoidVpnNotificationChannel() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
@@ -236,18 +263,6 @@ public class VpnNotificationManager {
return remoteViews;
}
- public void buildOpenVpnForegroundNotification(VpnServiceCallback vpnServiceCallback) {
- buildOpenVpnNotification("",
- false,
- VpnStatus.getLastCleanLogMessage(context.getApplicationContext()),
- VpnStatus.getLastCleanLogMessage(context.getApplicationContext()),
- ConnectionStatus.LEVEL_START,
- 0,
- OpenVPNService.NOTIFICATION_CHANNEL_NEWSTATUS_ID,
- vpnServiceCallback
- );
- }
-
private void buildVpnNotification(String title, String message, CharSequence bigMessage, String tickerText,
ConnectionStatus status, String notificationChannelNewstatusId, int priority,
long when, PendingIntent contentIntent, NotificationCompat.Action notificationAction, VpnServiceCallback vpnServiceCallback) {
@@ -299,6 +314,12 @@ public class VpnNotificationManager {
return PendingIntent.getActivity(context, 0, startActivity, PendingIntent.FLAG_CANCEL_CURRENT);
}
+ private PendingIntent getStartOpenvpnIntent() {
+ Intent startIntent = new Intent(context, EIP.class);
+ startIntent.setAction(EIP_ACTION_START);
+ return PendingIntent.getService(context, 0, startIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
private PendingIntent getStopVoidVpnIntent() {
Intent stopVoidVpnIntent = new Intent (context, VoidVpnService.class);
stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN);