diff options
author | cyBerta <cyberta@riseup.net> | 2021-11-23 12:32:07 +0100 |
---|---|---|
committer | cyBerta <cyberta@riseup.net> | 2021-11-23 12:32:07 +0100 |
commit | 9bf787465a3ae22c76249317496c8927b22ffdb4 (patch) | |
tree | fb37e1079a6aa19d027a38e024e0b5519eda7d52 /app/src/main/java/se/leap/bitmaskclient/base | |
parent | ecbf65eeb79a0172b19881beb3805c8f3ebff132 (diff) |
calculate and show gateway load related to transport
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/base')
5 files changed, 100 insertions, 34 deletions
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 f8053f5e..e9300584 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 @@ -56,12 +56,14 @@ import de.blinkt.openvpn.core.ConnectionStatus; 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.BuildConfig; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.MainActivity; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.base.views.LocationButton; import se.leap.bitmaskclient.base.views.MainButton; import se.leap.bitmaskclient.eip.EipCommand; @@ -426,7 +428,8 @@ public class EipFragment extends Fragment implements Observer { } else if (eipStatus.isConnected()) { setMainButtonEnabled(true); mainButton.updateState(true, false, false); - locationButton.setLocationLoad(gatewaysManager.getLoadForLocation(VpnStatus.getLastConnectedVpnName())); + Connection.TransportType transportType = PreferenceHelper.getUseBridges(getContext()) ? Connection.TransportType.OBFS4 : Connection.TransportType.OPENVPN; + locationButton.setLocationLoad(gatewaysManager.getLoadForLocation(VpnStatus.getLastConnectedVpnName(), transportType)); locationButton.setText(VpnStatus.getLastConnectedVpnName()); locationButton.showBridgeIndicator(VpnStatus.isUsingBridges()); locationButton.showRecommendedIndicator(getPreferredCity(getContext())== null); 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 12aedb12..51ebe359 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 @@ -19,6 +19,7 @@ package se.leap.bitmaskclient.base.fragments; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -48,18 +49,21 @@ import se.leap.bitmaskclient.eip.EipCommand; import se.leap.bitmaskclient.eip.EipStatus; import se.leap.bitmaskclient.eip.GatewaysManager; +import static android.content.Context.MODE_PRIVATE; 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; +import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; +import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; interface LocationListSelectionListener { void onLocationManuallySelected(Location location); } -public class GatewaySelectionFragment extends Fragment implements Observer, LocationListSelectionListener { +public class GatewaySelectionFragment extends Fragment implements Observer, LocationListSelectionListener, SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = GatewaySelectionFragment.class.getSimpleName(); @@ -69,6 +73,8 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca private SelectLocationEntry recommendedLocation; private GatewaysManager gatewaysManager; private EipStatus eipStatus; + private SharedPreferences preferences; + private Connection.TransportType selectedTransport; public GatewaySelectionFragment() { // Required empty public constructor @@ -80,6 +86,9 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca gatewaysManager = new GatewaysManager(getContext()); eipStatus = EipStatus.getInstance(); eipStatus.addObserver(this); + preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + selectedTransport = PreferenceHelper.getUseBridges(preferences) ? OBFS4 : OPENVPN; + preferences.registerOnSharedPreferenceChangeListener(this); } @Override @@ -100,6 +109,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca public void onDestroyView() { super.onDestroyView(); eipStatus.deleteObserver(this); + preferences.unregisterOnSharedPreferenceChangeListener(this); } private void initRecyclerView() { @@ -107,7 +117,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca recyclerView.setHasFixedSize(true); LinearLayoutManager layoutManager = new LinearLayoutManager(this.getContext()); recyclerView.setLayoutManager(layoutManager); - locationListAdapter = new LocationListAdapter(gatewaysManager.getGatewayLocations(), this); + locationListAdapter = new LocationListAdapter(gatewaysManager.getGatewayLocations(), this, selectedTransport); recyclerView.setAdapter(locationListAdapter); recyclerView.setVisibility(VISIBLE); } @@ -135,7 +145,10 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca } } location.selected = !isManualSelection; - recommendedLocation.setLocation(location); + if (!isManualSelection) { + locationListAdapter.unselectAll(); + } + recommendedLocation.setLocation(location, selectedTransport); } protected void startEipService(String preferredCity) { @@ -156,11 +169,11 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca @Override public void onLocationManuallySelected(Location location) { recommendedLocation.setSelected(false); - String name = location.name; - Connection.TransportType selectedTransport = PreferenceHelper.getUseBridges(getContext()) ? OBFS4 : OPENVPN; - if (location.supportedTransports.contains(selectedTransport)) { + String name = location.getName(); + if (location.supportsTransport(selectedTransport)) { startEipService(name); } else { + locationListAdapter.unselectAll(); askToChangeTransport(name); } } @@ -186,8 +199,17 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca } } + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(USE_BRIDGES)) { + selectedTransport = PreferenceHelper.getUseBridges(sharedPreferences) ? OBFS4 : OPENVPN; + locationListAdapter.updateTransport(selectedTransport); + } + } + static class LocationListAdapter extends RecyclerView.Adapter<LocationListAdapter.ViewHolder> { private static final String TAG = LocationListAdapter.class.getSimpleName(); + private Connection.TransportType transport; private final List<Location> values; private final WeakReference<LocationListSelectionListener> callback; @@ -210,6 +232,11 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca notifyItemRemoved(position); } + public void updateTransport(Connection.TransportType transportType) { + transport = transportType; + notifyDataSetChanged(); + } + public void unselectAll() { for (Location l : values) { l.selected = false; @@ -217,9 +244,10 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca notifyDataSetChanged(); } - public LocationListAdapter(List<Location> data, LocationListSelectionListener selectionListener) { + public LocationListAdapter(List<Location> data, LocationListSelectionListener selectionListener, Connection.TransportType selectedTransport) { values = data; callback = new WeakReference<>(selectionListener); + transport = selectedTransport; } @NonNull @@ -234,7 +262,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca @Override public void onBindViewHolder(ViewHolder holder, final int position) { final Location location = values.get(position); - holder.entry.setLocation(location); + holder.entry.setLocation(location, transport); holder.entry.setOnClickListener(v -> { Log.d(TAG, "onClick view at position clicked: " + position); LocationListSelectionListener listener = callback.get(); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/models/Location.java b/app/src/main/java/se/leap/bitmaskclient/base/models/Location.java index 599a358a..e0ce9e8b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/models/Location.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/models/Location.java @@ -19,29 +19,62 @@ package se.leap.bitmaskclient.base.models; import androidx.annotation.NonNull; +import java.util.HashMap; import java.util.HashSet; import de.blinkt.openvpn.core.connection.Connection; public class Location implements Cloneable { - @NonNull public String name = ""; - @NonNull public HashSet<Connection.TransportType> supportedTransports = new HashSet<>(); - public double averageLoad; - public int numberOfGateways; + @NonNull private String name = ""; + @NonNull private HashMap<Connection.TransportType, Double> averageLoad = new HashMap<>(); + @NonNull private HashMap<Connection.TransportType, Integer> numberOfGateways = new HashMap<>(); public boolean selected; public Location() {} - public Location(@NonNull String name, double averageLoad, int numberOfGateways, @NonNull HashSet<Connection.TransportType> supportedTransports, boolean selected) { + public Location(@NonNull String name, + @NonNull HashMap<Connection.TransportType, Double> averageLoad, + @NonNull HashMap<Connection.TransportType, Integer> numberOfGateways, + boolean selected) { this.name = name; this.averageLoad = averageLoad; this.numberOfGateways = numberOfGateways; - this.supportedTransports = supportedTransports; this.selected = selected; } public boolean hasLocationInfo() { - return numberOfGateways != 0 && supportedTransports.size() != 0 && !name.isEmpty(); + return !numberOfGateways.isEmpty() && !averageLoad.isEmpty() && !name.isEmpty(); + } + + public boolean supportsTransport(Connection.TransportType transportType) { + return numberOfGateways.containsKey(transportType); + } + + public void setAverageLoad(Connection.TransportType transportType, double load) { + averageLoad.put(transportType, load); + } + + public double getAverageLoad(Connection.TransportType transportType) { + if (averageLoad.containsKey(transportType)) { + return averageLoad.get(transportType); + } + return 0; + } + + public void setNumberOfGateways(Connection.TransportType transportType, int numbers) { + numberOfGateways.put(transportType, numbers); + } + + public int getNumberOfGateways(Connection.TransportType transportType) { + if (numberOfGateways.containsKey(transportType)) { + return numberOfGateways.get(transportType); + } + return 0; + } + + @NonNull + public String getName() { + return name; } @Override @@ -51,21 +84,16 @@ public class Location implements Cloneable { Location location = (Location) o; - if (Double.compare(location.averageLoad, averageLoad) != 0) return false; - if (numberOfGateways != location.numberOfGateways) return false; if (!name.equals(location.name)) return false; - return supportedTransports.equals(location.supportedTransports); + if (!averageLoad.equals(location.averageLoad)) return false; + return numberOfGateways.equals(location.numberOfGateways); } @Override public int hashCode() { - int result; - long temp; - result = name.hashCode(); - result = 31 * result + supportedTransports.hashCode(); - temp = Double.doubleToLongBits(averageLoad); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - result = 31 * result + numberOfGateways; + int result = name.hashCode(); + result = 31 * result + averageLoad.hashCode(); + result = 31 * result + numberOfGateways.hashCode(); return result; } @@ -73,10 +101,8 @@ public class Location implements Cloneable { public Location clone() throws CloneNotSupportedException { Location copy = (Location) super.clone(); copy.name = this.name; - copy.supportedTransports = (HashSet<Connection.TransportType>) this.supportedTransports.clone(); - copy.numberOfGateways = this.numberOfGateways; - copy.averageLoad = this.averageLoad; + copy.numberOfGateways = (HashMap<Connection.TransportType, Integer>) this.numberOfGateways.clone(); + copy.averageLoad = (HashMap<Connection.TransportType, Double>) this.averageLoad.clone(); return copy; } - } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java index 64b51960..92010992 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ConfigHelper.java @@ -197,6 +197,15 @@ public class ConfigHelper { return Calendar.getInstance().get(Calendar.ZONE_OFFSET) / 3600000; } + public static int timezoneDistance(int local_timezone, int remoteTimezone) { + // Distance along the numberline of Prime Meridian centric, assumes UTC-11 through UTC+12 + int dist = Math.abs(local_timezone - remoteTimezone); + // Farther than 12 timezones and it's shorter around the "back" + if (dist > 12) + dist = 12 - (dist - 12); // Well i'll be. Absolute values make equations do funny things. + return dist; + } + public static String getProviderFormattedString(Resources resources, @StringRes int resourceId) { String appName = resources.getString(R.string.app_name); return resources.getString(resourceId, appName); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/SelectLocationEntry.java b/app/src/main/java/se/leap/bitmaskclient/base/views/SelectLocationEntry.java index f85df4ca..bf293a51 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/views/SelectLocationEntry.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/views/SelectLocationEntry.java @@ -64,14 +64,14 @@ public class SelectLocationEntry extends RelativeLayout { title.setText(text); title.setVisibility(text != null ? VISIBLE : GONE); } - public void setLocation(Location location) { + public void setLocation(Location location, Connection.TransportType transportType) { boolean valid = location.hasLocationInfo(); locationText.setVisibility(valid ? VISIBLE : GONE); locationIndicator.setVisibility(valid ? VISIBLE : GONE); bridgesView.setVisibility(valid ? VISIBLE : GONE); - locationText.setText(location.name); - locationIndicator.setLoad(Load.getLoadByValue(location.averageLoad)); - bridgesView.setVisibility(location.supportedTransports.contains(Connection.TransportType.OBFS4) ? VISIBLE : GONE); + locationText.setText(location.getName()); + locationIndicator.setLoad(Load.getLoadByValue(location.getAverageLoad(transportType))); + bridgesView.setVisibility(location.supportsTransport(Connection.TransportType.OBFS4) ? VISIBLE : GONE); selectedView.setChecked(location.selected); } |