From d8b11c392a492ef05b1a454c298f5244a694553b Mon Sep 17 00:00:00 2001 From: cyBerta Date: Fri, 30 Jul 2021 20:38:23 +0200 Subject: ask user to change location or disable bridges if manually selected location doesn't support bridges --- .../se/leap/bitmaskclient/base/MainActivity.java | 13 +++++++-- .../base/fragments/GatewaySelectionFragment.java | 32 ++++++++++++++++++---- .../base/fragments/MainActivityErrorDialog.java | 25 ++++++++++++++++- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 3 +- .../se/leap/bitmaskclient/eip/GatewaysManager.java | 19 +++++++++++-- 5 files changed, 80 insertions(+), 12 deletions(-) (limited to 'app/src/main/java') 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 18ac8b7c..54977f0a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java @@ -60,6 +60,7 @@ 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; +import static se.leap.bitmaskclient.base.models.Constants.LOCATION; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN; @@ -85,6 +86,7 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment"; public final static String ACTION_SHOW_LOG_FRAGMENT = "action_show_log_fragment"; + public final static String ACTION_SHOW_DIALOG_FRAGMENT = "action_show_dialog_fragment"; /** * Fragment managing the behaviors, interactions and presentation of the navigation drawer. @@ -152,6 +154,13 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, fragment = new LogFragment(); setActionBarTitle(R.string.log_fragment_title); break; + case ACTION_SHOW_DIALOG_FRAGMENT: + if (intent.hasExtra(EIP.ERRORID)) { + String errorId = intent.getStringExtra(EIP.ERRORID); + String error = intent.getStringExtra(EIP.ERRORS); + String args = intent.getStringExtra(LOCATION); + showMainActivityErrorDialog(error, EIP.EIPErrors.valueOf(errorId), args); + } default: break; } @@ -324,12 +333,12 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, /** * Shows an error dialog */ - public void showMainActivityErrorDialog(String reasonToFail, EIP.EIPErrors error) { + public void showMainActivityErrorDialog(String reasonToFail, EIP.EIPErrors error, String... args) { try { FragmentTransaction fragmentTransaction = new FragmentManagerEnhanced( this.getSupportFragmentManager()).removePreviousFragment( MainActivityErrorDialog.TAG); - DialogFragment newFragment = MainActivityErrorDialog.newInstance(provider, reasonToFail, error); + DialogFragment newFragment = MainActivityErrorDialog.newInstance(provider, reasonToFail, error, args); newFragment.show(fragmentTransaction, MainActivityErrorDialog.TAG); } catch (IllegalStateException | NullPointerException e) { e.printStackTrace(); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java index 450cba4d..2dcb0ec9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java @@ -45,16 +45,21 @@ import se.leap.bitmaskclient.base.MainActivity; import se.leap.bitmaskclient.base.models.Location; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.base.views.LocationIndicator; +import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.eip.GatewaysManager; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +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.base.MainActivity.ACTION_SHOW_DIALOG_FRAGMENT; import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT; +import static se.leap.bitmaskclient.base.models.Constants.LOCATION; interface LocationListSelectionListener { - void onLocationSelected(String name); + void onLocationSelected(Location location); } public class GatewaySelectionFragment extends Fragment implements Observer, LocationListSelectionListener { @@ -154,8 +159,24 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca } @Override - public void onLocationSelected(String name) { - startEipService(name); + public void onLocationSelected(Location location) { + String name = location.name; + Connection.TransportType selectedTransport = PreferenceHelper.getUsePluggableTransports(getContext()) ? OBFS4 : OPENVPN; + if (location.supportedTransports.contains(selectedTransport)) { + startEipService(name); + } else { + askToChangeTransport(name); + } + } + + private void askToChangeTransport(String name) { + Intent intent = new Intent(getContext(), MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.setAction(ACTION_SHOW_DIALOG_FRAGMENT); + intent.putExtra(EIP.ERRORID, EIP.EIPErrors.TRANSPORT_NOT_SUPPORTED.toString()); + intent.putExtra(EIP.ERRORS, getString(R.string.warning_bridges_not_supported, name)); + intent.putExtra(LOCATION, name); + startActivity(intent); } @Override @@ -168,7 +189,6 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca } } - static class LocationListAdapter extends RecyclerView.Adapter { private static final String TAG = LocationListAdapter.class.getSimpleName(); private List values; @@ -228,11 +248,11 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca Log.d(TAG, "view at position clicked: " + position); LocationListSelectionListener listener = callback.get(); if (listener != null) { - listener.onLocationSelected(location.name); + listener.onLocationSelected(location); } }); holder.locationIndicator.setLoad(GatewaysManager.Load.getLoadByValue(location.averageLoad)); - holder.bridgeView.setVisibility(location.supportedTransports.contains(Connection.TransportType.OBFS4) ? VISIBLE : View.GONE); + holder.bridgeView.setVisibility(location.supportedTransports.contains(OBFS4) ? VISIBLE : View.GONE); } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java index da48effc..f7805002 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java @@ -18,6 +18,8 @@ package se.leap.bitmaskclient.base.fragments; import android.app.Dialog; import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -27,11 +29,15 @@ import androidx.appcompat.app.AlertDialog; import org.json.JSONObject; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.base.MainActivity; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.providersetup.ProviderAPICommand; +import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_DIALOG_FRAGMENT; +import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferredCity; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setPreferredCity; import static se.leap.bitmaskclient.providersetup.ProviderAPI.UPDATE_INVALID_VPN_CERTIFICATE; @@ -56,6 +62,7 @@ public class MainActivityErrorDialog extends DialogFragment { final private static String KEY_REASON_TO_FAIL = "key reason to fail"; final private static String KEY_PROVIDER = "key provider"; private String reasonToFail; + private String[] args; private EIP.EIPErrors downloadError = UNKNOWN; private Provider provider; @@ -70,11 +77,12 @@ public class MainActivityErrorDialog extends DialogFragment { /** * @return a new instance of this DialogFragment. */ - public static DialogFragment newInstance(Provider provider, String reasonToFail, EIP.EIPErrors error) { + public static DialogFragment newInstance(Provider provider, String reasonToFail, EIP.EIPErrors error, String... args) { MainActivityErrorDialog dialogFragment = new MainActivityErrorDialog(); dialogFragment.reasonToFail = reasonToFail; dialogFragment.provider = provider; dialogFragment.downloadError = error; + dialogFragment.args = args; return dialogFragment; } @@ -150,6 +158,21 @@ public class MainActivityErrorDialog extends DialogFragment { case ERROR_VPN_PREPARE: builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { }); break; + case TRANSPORT_NOT_SUPPORTED: + + builder.setPositiveButton(R.string.option_different_location, (dialog, which) -> { }); + builder.setNegativeButton(R.string.option_disable_bridges, (dialog, which) -> { + PreferenceHelper.useBridges(applicationContext, false); + PreferenceHelper.setPreferredCity(applicationContext, args[0]); + + EipCommand.startVPN(applicationContext, false); + // at this point the gateway selection dialog is shown, let's switch to the main view + Intent intent = new Intent(getContext(), MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.setAction(ACTION_SHOW_VPN_FRAGMENT); + startActivity(intent); + }); + 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 dd9054f1..a7e08bd7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -127,7 +127,8 @@ public final class EIP extends JobIntentService implements Observer { ERROR_INVALID_VPN_CERTIFICATE, NO_MORE_GATEWAYS, ERROR_VPN_PREPARE, - ERROR_INVALID_PROFILE + ERROR_INVALID_PROFILE, + TRANSPORT_NOT_SUPPORTED, } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java index 0b2c2030..dbb2a914 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -96,6 +96,7 @@ public class GatewaysManager { private final LinkedHashMap gateways = new LinkedHashMap<>(); private final Type listType = new TypeToken>() {}.getType(); private final ArrayList presortedList = new ArrayList<>(); + private ArrayList locations = new ArrayList<>(); public GatewaysManager(Context context) { this.context = context; @@ -130,6 +131,10 @@ public class GatewaysManager { } public List getGatewayLocations() { + if (locations.size() > 0) { + return locations; + } + HashMap locationNames = new HashMap<>(); ArrayList locations = new ArrayList<>(); ArrayList gateways = getSortedGateways(); @@ -166,16 +171,26 @@ public class GatewaysManager { } } + this.locations = locations; return locations; } - public Load getLoadForLocation(@Nullable String name) { + @Nullable + public Location getLocation(String name) { List locations = getGatewayLocations(); for (Location location : locations) { if (location.name.equals(name)) { - return Load.getLoadByValue(location.averageLoad); + return location; } } + return null; + } + + public Load getLoadForLocation(@Nullable String name) { + Location location = getLocation(name); + if (location != null) { + return Load.getLoadByValue(location.averageLoad); + } // location not found return Load.UNKNOWN; -- cgit v1.2.3