summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2019-10-25 17:10:13 +0200
committercyBerta <cyberta@riseup.net>2019-10-25 17:10:13 +0200
commit761b604e14b14a86a357816b266e77d458137c83 (patch)
treef3dfefaeee6b71738fd1ae1d670d6392c38a8f2b
parent6b4f3597733ced8d312ed263d53b9669d6274d65 (diff)
implement error handling for edge case when Android
throws an nullpointer exception while it tries to prepare the VpnService
-rw-r--r--app/src/main/java/de/blinkt/openvpn/LaunchVPN.java13
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Constants.java1
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivity.java34
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java49
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EIP.java67
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipResultBroadcast.java77
-rw-r--r--app/src/main/res/values/strings.xml1
8 files changed, 165 insertions, 85 deletions
diff --git a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
index 60e4abb6..70f8e445 100644
--- a/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
+++ b/app/src/main/java/de/blinkt/openvpn/LaunchVPN.java
@@ -26,7 +26,9 @@ import de.blinkt.openvpn.core.VpnStatus;
import se.leap.bitmaskclient.MainActivity;
import se.leap.bitmaskclient.R;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE;
+import static se.leap.bitmaskclient.eip.EipResultBroadcast.tellToReceiverOrBroadcast;
/**
* This Activity actually handles two stages of a launcher shortcut's life cycle.
@@ -62,6 +64,7 @@ public class LaunchVPN extends Activity {
private static final int START_VPN_PROFILE = 70;
+ private static final String TAG = LaunchVPN.class.getName();
private VpnProfile mSelectedProfile;
@@ -180,7 +183,15 @@ public class LaunchVPN extends Activity {
return;
}
- Intent intent = VpnService.prepare(this);
+ Intent intent = null;
+ try {
+ intent = VpnService.prepare(this.getApplicationContext());
+ } catch (NullPointerException npe) {
+ tellToReceiverOrBroadcast(this.getApplicationContext(), EIP_ACTION_PREPARE_VPN, RESULT_CANCELED);
+ finish();
+ return;
+ }
+
// Check if we want to fix /dev/tun
SharedPreferences prefs = Preferences.getDefaultSharedPreferences(this);
boolean usecm9fix = prefs.getBoolean("useCM9Fix", false);
diff --git a/app/src/main/java/se/leap/bitmaskclient/Constants.java b/app/src/main/java/se/leap/bitmaskclient/Constants.java
index 720cd1c4..d3c09f08 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Constants.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Constants.java
@@ -51,6 +51,7 @@ public interface Constants {
String EIP_ACTION_START_ALWAYS_ON_VPN = "se.leap.bitmaskclient.START_ALWAYS_ON_VPN";
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_RECEIVER = "EIP.RECEIVER";
String EIP_REQUEST = "EIP.REQUEST";
diff --git a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
index 7ded9069..53bd9002 100644
--- a/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/EipSetupObserver.java
@@ -34,6 +34,7 @@ import static se.leap.bitmaskclient.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_E
import static se.leap.bitmaskclient.Constants.BROADCAST_PROVIDER_API_EVENT;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START_ALWAYS_ON_VPN;
import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
@@ -176,6 +177,13 @@ class EipSetupObserver extends BroadcastReceiver implements VpnStatus.StateListe
EipStatus.refresh();
}
break;
+ case EIP_ACTION_PREPARE_VPN:
+ if (resultCode == RESULT_CANCELED) {
+ VpnStatus.logError("Error preparing VpnService.");
+ finishGatewaySetup(false);
+ EipStatus.refresh();
+ }
+ break;
default:
break;
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
index ad7c8ae3..39c4a8f1 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivity.java
@@ -35,6 +35,7 @@ import java.util.Observable;
import java.util.Observer;
import se.leap.bitmaskclient.drawer.NavigationDrawerFragment;
+import se.leap.bitmaskclient.eip.EIP;
import se.leap.bitmaskclient.eip.EipCommand;
import se.leap.bitmaskclient.fragments.ExcludeAppsFragment;
import se.leap.bitmaskclient.fragments.LogFragment;
@@ -43,6 +44,7 @@ import se.leap.bitmaskclient.utils.PreferenceHelper;
import static se.leap.bitmaskclient.Constants.ASK_TO_CANCEL_VPN;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.EIP_ACTION_PREPARE_VPN;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_START;
import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
import static se.leap.bitmaskclient.Constants.PROVIDER_KEY;
@@ -58,6 +60,7 @@ import static se.leap.bitmaskclient.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.utils.PreferenceHelper.storeProviderInPreferences;
@@ -88,18 +91,13 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
preferences = getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
provider = ProviderObservable.getInstance().getCurrentProvider();
+ EipSetupObserver.addListener(this);
// Set up the drawer.
navigationDrawerFragment.setUp(R.id.navigation_drawer, findViewById(R.id.drawer_layout));
handleIntentAction(getIntent());
}
@Override
- protected void onResume() {
- super.onResume();
- EipSetupObserver.addListener(this);
- }
-
- @Override
public void onBackPressed() {
FragmentManagerEnhanced fragmentManagerEnhanced = new FragmentManagerEnhanced(getSupportFragmentManager());
Fragment fragment = fragmentManagerEnhanced.findFragmentByTag(MainActivity.TAG);
@@ -214,8 +212,8 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
}
@Override
- protected void onPause() {
- super.onPause();
+ protected void onDestroy() {
+ super.onDestroy();
EipSetupObserver.removeListener(this);
}
@@ -247,6 +245,11 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
}
}
break;
+ case EIP_ACTION_PREPARE_VPN:
+ if (resultCode == RESULT_CANCELED) {
+ showMainActivityErrorDialog(getString(R.string.vpn_error_establish), ERROR_VPN_PREPARE);
+ }
+ break;
}
}
@@ -297,7 +300,22 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener,
e.printStackTrace();
Log.w(TAG, "error dialog leaked!");
}
+ }
+ /**
+ * Shows an error dialog
+ */
+ public void showMainActivityErrorDialog(String reasonToFail, EIP.EIPErrors error) {
+ try {
+ FragmentTransaction fragmentTransaction = new FragmentManagerEnhanced(
+ this.getSupportFragmentManager()).removePreviousFragment(
+ MainActivityErrorDialog.TAG);
+ DialogFragment newFragment = MainActivityErrorDialog.newInstance(provider, reasonToFail, error);
+ newFragment.show(fragmentTransaction, MainActivityErrorDialog.TAG);
+ } catch (IllegalStateException | NullPointerException e) {
+ e.printStackTrace();
+ Log.w(TAG, "error dialog leaked!");
+ }
}
/**
diff --git a/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java b/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
index 6ce21918..5e3d8f73 100644
--- a/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
+++ b/app/src/main/java/se/leap/bitmaskclient/MainActivityErrorDialog.java
@@ -32,6 +32,7 @@ import se.leap.bitmaskclient.eip.EipCommand;
import static se.leap.bitmaskclient.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.R.string.warning_option_try_ovpn;
import static se.leap.bitmaskclient.R.string.warning_option_try_pt;
+import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.UNKNOWN;
import static se.leap.bitmaskclient.eip.EIP.EIPErrors.valueOf;
import static se.leap.bitmaskclient.eip.EIP.ERRORS;
@@ -59,9 +60,17 @@ public class MainActivityErrorDialog extends DialogFragment {
* @return a new instance of this DialogFragment.
*/
public static DialogFragment newInstance(Provider provider, String reasonToFail) {
+ return newInstance(provider, reasonToFail, UNKNOWN);
+ }
+
+ /**
+ * @return a new instance of this DialogFragment.
+ */
+ public static DialogFragment newInstance(Provider provider, String reasonToFail, EIP.EIPErrors error) {
MainActivityErrorDialog dialogFragment = new MainActivityErrorDialog();
dialogFragment.reasonToFail = reasonToFail;
dialogFragment.provider = provider;
+ dialogFragment.downloadError = error;
return dialogFragment;
}
@@ -99,6 +108,7 @@ public class MainActivityErrorDialog extends DialogFragment {
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ Context applicationContext = getContext().getApplicationContext();
builder.setMessage(reasonToFail)
.setNegativeButton(R.string.cancel, (dialog, id) -> {
});
@@ -108,28 +118,29 @@ public class MainActivityErrorDialog extends DialogFragment {
ProviderAPICommand.execute(getContext(), UPDATE_INVALID_VPN_CERTIFICATE, provider));
break;
case NO_MORE_GATEWAYS:
- Context context = getContext();
- if (context != null) {
- Context applicationContext = context.getApplicationContext();
- if (provider.supportsPluggableTransports()) {
- if (getUsePluggableTransports(applicationContext)) {
- builder.setPositiveButton(warning_option_try_ovpn, ((dialog, which) -> {
- usePluggableTransports(applicationContext, false);
- EipCommand.startVPN(applicationContext.getApplicationContext(), false);
- }));
- } else {
- builder.setPositiveButton(warning_option_try_pt, ((dialog, which) -> {
- usePluggableTransports(applicationContext, true);
- EipCommand.startVPN(applicationContext.getApplicationContext(), false);
- }));
- }
+ if (provider.supportsPluggableTransports()) {
+ if (getUsePluggableTransports(applicationContext)) {
+ builder.setPositiveButton(warning_option_try_ovpn, ((dialog, which) -> {
+ usePluggableTransports(applicationContext, false);
+ EipCommand.startVPN(applicationContext, false);
+ }));
} else {
- builder.setPositiveButton(R.string.retry,(dialog, which) -> {
- EipCommand.startVPN(applicationContext.getApplicationContext(), false);
- });
+ builder.setPositiveButton(warning_option_try_pt, ((dialog, which) -> {
+ usePluggableTransports(applicationContext, true);
+ EipCommand.startVPN(applicationContext, false);
+ }));
}
+ } else {
+ builder.setPositiveButton(R.string.retry, (dialog, which) -> {
+ EipCommand.startVPN(applicationContext, false);
+ });
}
-
+ break;
+ case ERROR_VPN_PREPARE:
+ builder.setPositiveButton(R.string.retry, (dialog, which) -> {
+ EipCommand.startVPN(applicationContext, false);
+ });
+ break;
default:
break;
}
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 5ce8b6e2..e37305f2 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java
@@ -52,17 +52,13 @@ import de.blinkt.openvpn.core.connection.Connection;
import se.leap.bitmaskclient.OnBootReceiver;
import se.leap.bitmaskclient.ProviderObservable;
import se.leap.bitmaskclient.R;
-import se.leap.bitmaskclient.utils.ConfigHelper;
import se.leap.bitmaskclient.utils.PreferenceHelper;
import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;
-import static android.content.Intent.CATEGORY_DEFAULT;
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.Constants.BROADCAST_EIP_EVENT;
import static se.leap.bitmaskclient.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT;
-import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_CHECK_CERT_VALIDITY;
import static se.leap.bitmaskclient.Constants.EIP_ACTION_IS_RUNNING;
@@ -73,7 +69,6 @@ import static se.leap.bitmaskclient.Constants.EIP_ACTION_STOP_BLOCKING_VPN;
import static se.leap.bitmaskclient.Constants.EIP_EARLY_ROUTES;
import static se.leap.bitmaskclient.Constants.EIP_N_CLOSEST_GATEWAY;
import static se.leap.bitmaskclient.Constants.EIP_RECEIVER;
-import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
import static se.leap.bitmaskclient.Constants.EIP_RESTART_ON_BOOT;
import static se.leap.bitmaskclient.Constants.PROVIDER_PROFILE;
import static se.leap.bitmaskclient.Constants.PROVIDER_VPN_CERTIFICATE;
@@ -82,6 +77,7 @@ 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.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.utils.ConfigHelper.ensureNotOnMainThread;
import static se.leap.bitmaskclient.utils.PreferenceHelper.getUsePluggableTransports;
@@ -117,7 +113,8 @@ public final class EIP extends JobIntentService implements Observer {
public enum EIPErrors {
UNKNOWN,
ERROR_INVALID_VPN_CERTIFICATE,
- NO_MORE_GATEWAYS
+ NO_MORE_GATEWAYS,
+ ERROR_VPN_PREPARE
}
/**
@@ -212,24 +209,24 @@ public final class EIP extends JobIntentService implements Observer {
if (!isVPNCertificateValid()) {
setErrorResult(result, vpn_certificate_is_invalid, ERROR_INVALID_VPN_CERTIFICATE.toString());
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_CANCELED, result);
return;
}
GatewaysManager gatewaysManager = gatewaysFromPreferences();
if (gatewaysManager.isEmpty()) {
setErrorResult(result, warning_client_parsing_error_gateways, null);
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_CANCELED, result);
return;
}
Gateway gateway = gatewaysManager.select(nClosestGateway);
if (launchActiveGateway(gateway, nClosestGateway)) {
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_OK);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_OK);
} else {
setErrorResult(result, NO_MORE_GATEWAYS.toString(), getStringResourceForNoMoreGateways(), getString(R.string.app_name));
- tellToReceiverOrBroadcast(EIP_ACTION_START, RESULT_CANCELED, result);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_START, RESULT_CANCELED, result);
}
}
@@ -284,7 +281,7 @@ public final class EIP extends JobIntentService implements Observer {
private void stopEIP() {
VpnStatus.updateStateString("STOPPING", "STOPPING VPN", R.string.state_exiting, ConnectionStatus.LEVEL_STOPPING);
int resultCode = stop() ? RESULT_OK : RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_STOP, resultCode);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_STOP, resultCode);
}
/**
@@ -296,7 +293,7 @@ public final class EIP extends JobIntentService implements Observer {
int resultCode = (eipStatus.isConnected()) ?
RESULT_OK :
RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_IS_RUNNING, resultCode);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_IS_RUNNING, resultCode);
}
/**
@@ -316,7 +313,7 @@ public final class EIP extends JobIntentService implements Observer {
int resultCode = isVPNCertificateValid() ?
RESULT_OK :
RESULT_CANCELED;
- tellToReceiverOrBroadcast(EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
+ tellToReceiverOrBroadcast(this, EIP_ACTION_CHECK_CERT_VALIDITY, resultCode);
}
/**
@@ -330,50 +327,6 @@ public final class EIP extends JobIntentService implements Observer {
}
/**
- * send resultCode and resultData to receiver or
- * broadcast the result if no receiver is defined
- *
- * @param action the action that has been performed
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- * @param resultData other data to broadcast or return to receiver
- */
- private void tellToReceiverOrBroadcast(String action, int resultCode, Bundle resultData) {
- resultData.putString(EIP_REQUEST, action);
- if (mResultRef.get() != null) {
- mResultRef.get().send(resultCode, resultData);
- } else {
- broadcastEvent(resultCode, resultData);
- }
- }
-
- /**
- * send resultCode and resultData to receiver or
- * broadcast the result if no receiver is defined
- *
- * @param action the action that has been performed
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- */
- private void tellToReceiverOrBroadcast(String action, int resultCode) {
- tellToReceiverOrBroadcast(action, resultCode, new Bundle());
- }
-
- /**
- * broadcast result
- *
- * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
- * @param resultData other data to broadcast or return to receiver
- */
- private void broadcastEvent(int resultCode, Bundle resultData) {
- Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT);
- intentUpdate.addCategory(CATEGORY_DEFAULT);
- intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
- intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
- Log.d(TAG, "sending broadcast");
- LocalBroadcastManager.getInstance(this).sendBroadcast(intentUpdate);
- }
-
-
- /**
* helper function to add error to result bundle
*
* @param result - result of an action
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipResultBroadcast.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipResultBroadcast.java
new file mode 100644
index 00000000..e1efb375
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipResultBroadcast.java
@@ -0,0 +1,77 @@
+package se.leap.bitmaskclient.eip;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+
+import static android.content.Intent.CATEGORY_DEFAULT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_EIP_EVENT;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_CODE;
+import static se.leap.bitmaskclient.Constants.BROADCAST_RESULT_KEY;
+import static se.leap.bitmaskclient.Constants.EIP_REQUEST;
+
+public class EipResultBroadcast {
+ private static final String TAG = EipResultBroadcast.class.getSimpleName();
+
+
+ /**
+ * send resultCode and resultData to receiver or
+ * broadcast the result if no receiver is defined
+ *
+ * @param action the action that has been performed
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ */
+ public static void tellToReceiverOrBroadcast(Context context, String action, int resultCode) {
+ tellToReceiverOrBroadcast(context, action, resultCode, null, new Bundle());
+ }
+
+ /**
+ * send resultCode and resultData to receiver or
+ * broadcast the result if no receiver is defined
+ *
+ * @param action the action that has been performed
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ * @param resultData other data to broadcast or return to receiver
+ */
+ public static void tellToReceiverOrBroadcast(Context context, String action, int resultCode, ResultReceiver receiver, Bundle resultData) {
+ resultData.putString(EIP_REQUEST, action);
+ if (receiver != null) {
+ receiver.send(resultCode, resultData);
+ } else {
+ broadcastEvent(context, resultCode, resultData);
+ }
+ }
+
+ /**
+ * send resultCode and resultData to receiver or
+ * broadcast the result if no receiver is defined
+ *
+ * @param action the action that has been performed
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ * @param resultData other data to broadcast or return to receiver
+ */
+ public static void tellToReceiverOrBroadcast(Context context, String action, int resultCode, Bundle resultData) {
+ resultData.putString(EIP_REQUEST, action);
+ broadcastEvent(context, resultCode, resultData);
+ }
+
+
+
+ /**
+ * broadcast result
+ *
+ * @param resultCode RESULT_OK if action was successful RESULT_CANCELED otherwise
+ * @param resultData other data to broadcast or return to receiver
+ */
+ public static void broadcastEvent(Context context, int resultCode, Bundle resultData) {
+ Intent intentUpdate = new Intent(BROADCAST_EIP_EVENT);
+ intentUpdate.addCategory(CATEGORY_DEFAULT);
+ intentUpdate.putExtra(BROADCAST_RESULT_CODE, resultCode);
+ intentUpdate.putExtra(BROADCAST_RESULT_KEY, resultData);
+ Log.d(TAG, "sending broadcast");
+ LocalBroadcastManager.getInstance(context).sendBroadcast(intentUpdate);
+ }
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 06aeeacf..6c2f0236 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -127,4 +127,5 @@
<string name="warning_no_more_gateways_use_ovpn">%s could not connect using obfuscated vpn connections. Do you want to try to connect using a standard vpn?</string>
<string name="warning_option_try_pt">Try obfuscated connection</string>
<string name="warning_option_try_ovpn">Try standard connection</string>
+ <string name="vpn_error_establish">Android failed to establish the VPN service.</string>
</resources>