diff options
Diffstat (limited to 'app/src/main')
6 files changed, 75 insertions, 32 deletions
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 ee4aea74..450cba4d 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 @@ -18,7 +18,6 @@ package se.leap.bitmaskclient.base.fragments; import android.app.Activity; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -28,6 +27,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.AppCompatButton; +import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatTextView; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; @@ -39,6 +39,7 @@ import java.util.Observable; import java.util.Observer; import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.MainActivity; import se.leap.bitmaskclient.base.models.Location; @@ -48,18 +49,15 @@ 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.INVISIBLE; import static android.view.View.VISIBLE; import static se.leap.bitmaskclient.base.MainActivity.ACTION_SHOW_VPN_FRAGMENT; -import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; -import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; interface LocationListSelectionListener { void onLocationSelected(String name); } -public class GatewaySelectionFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener, Observer, LocationListSelectionListener { +public class GatewaySelectionFragment extends Fragment implements Observer, LocationListSelectionListener { private static final String TAG = GatewaySelectionFragment.class.getSimpleName(); @@ -70,7 +68,6 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen private AppCompatTextView currentLocation; private AppCompatButton autoSelectionButton; private GatewaysManager gatewaysManager; - private SharedPreferences preferences; private EipStatus eipStatus; public GatewaySelectionFragment() { @@ -81,7 +78,6 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); gatewaysManager = new GatewaysManager(getContext()); - preferences = getContext().getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); eipStatus = EipStatus.getInstance(); } @@ -98,19 +94,14 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen initRecyclerView(); initAutoSelectionButton(); initCurrentLocationInfoPanel(); - eipStatus.addObserver(this); - preferences.registerOnSharedPreferenceChangeListener(this); } @Override public void onDestroyView() { super.onDestroyView(); - preferences.unregisterOnSharedPreferenceChangeListener(this); eipStatus.deleteObserver(this); } - - private void initRecyclerView() { recyclerView = getActivity().findViewById(R.id.gatewaySelection_list); recyclerView.setHasFixedSize(true); @@ -163,13 +154,6 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen } @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (USE_BRIDGES.equals(key)) { - locationListAdapter.updateData(gatewaysManager.getGatewayLocations()); - } - } - - @Override public void onLocationSelected(String name) { startEipService(name); } @@ -193,6 +177,7 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen static class ViewHolder extends RecyclerView.ViewHolder { public AppCompatTextView locationLabel; public LocationIndicator locationIndicator; + public AppCompatImageView bridgeView; public View layout; public ViewHolder(View v) { @@ -200,6 +185,7 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen layout = v; locationLabel = v.findViewById(R.id.location); locationIndicator = v.findViewById(R.id.quality); + bridgeView = v.findViewById(R.id.bridge_image); } } @@ -246,6 +232,7 @@ public class GatewaySelectionFragment extends Fragment implements SharedPreferen } }); holder.locationIndicator.setLoad(GatewaysManager.Load.getLoadByValue(location.averageLoad)); + holder.bridgeView.setVisibility(location.supportedTransports.contains(Connection.TransportType.OBFS4) ? VISIBLE : View.GONE); } 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 8e032d18..3ec7d38c 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 @@ -1,16 +1,37 @@ +/** + * Copyright (c) 2021 LEAP Encryption Access Project and contributers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + package se.leap.bitmaskclient.base.models; import androidx.annotation.NonNull; +import java.util.HashSet; +import de.blinkt.openvpn.core.connection.Connection; public class Location { @NonNull public String name; + @NonNull public HashSet<Connection.TransportType> supportedTransports; public double averageLoad; public int numberOfGateways; - public Location(@NonNull String name, double averageLoad, int numberOfGateways) { + public Location(@NonNull String name, double averageLoad, int numberOfGateways, @NonNull HashSet<Connection.TransportType> supportedTransports) { this.name = name; this.averageLoad = averageLoad; this.numberOfGateways = numberOfGateways; + this.supportedTransports = supportedTransports; } @Override @@ -22,7 +43,8 @@ public class Location { if (Double.compare(location.averageLoad, averageLoad) != 0) return false; if (numberOfGateways != location.numberOfGateways) return false; - return name.equals(location.name); + if (!name.equals(location.name)) return false; + return supportedTransports.equals(location.supportedTransports); } @Override @@ -30,6 +52,7 @@ public class Location { 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; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java index 78b33355..8a48684f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -195,6 +195,10 @@ public class Gateway { return vpnProfiles.get(transportType) != null; } + public HashSet<Connection.TransportType> getSupportedTransports() { + return new HashSet<>(vpnProfiles.keySet()); + } + public int getTimezone() { return timezone; } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java index 33fd3c21..a48cc6d5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaySelector.java @@ -2,6 +2,8 @@ package se.leap.bitmaskclient.eip; import android.util.Log; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -18,7 +20,15 @@ public class GatewaySelector { public GatewaySelector(List<Gateway> gateways) { this.gateways = gateways; this.offsets = calculateOffsets(); + } + public ArrayList<Gateway> getGatewaysSortedByDistance() { + ArrayList<Gateway> list = new ArrayList<>(); + int i = 0; + for (Collection<Gateway> gatewayCollection : offsets.values()) { + list.addAll(gatewayCollection); + } + return list; } public Gateway select() { 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 0819e9b6..0b2c2030 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -43,7 +43,6 @@ import de.blinkt.openvpn.core.connection.Connection; import se.leap.bitmaskclient.base.models.Location; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.models.ProviderObservable; -import se.leap.bitmaskclient.base.utils.PreferenceHelper; import static de.blinkt.openvpn.core.connection.Connection.TransportType.OBFS4; import static de.blinkt.openvpn.core.connection.Connection.TransportType.OPENVPN; @@ -121,13 +120,20 @@ public class GatewaysManager { return getGatewayFromTimezoneCalculation(nClosest, transportType, city); } + public ArrayList<Gateway> getSortedGateways() { + if (presortedList.size() > 0) { + return presortedList; + } else { + GatewaySelector gatewaySelector = new GatewaySelector(new ArrayList<>(gateways.values())); + return gatewaySelector.getGatewaysSortedByDistance(); + } + } + public List<Location> getGatewayLocations() { - String selectedCity = PreferenceHelper.getPreferredCity(context); HashMap<String, Integer> locationNames = new HashMap<>(); ArrayList<Location> locations = new ArrayList<>(); - int n = 0; - Gateway gateway; - while ((gateway = select(n, null)) != null) { + ArrayList<Gateway> gateways = getSortedGateways(); + for (Gateway gateway : gateways) { String name = gateway.getName(); if (name == null) { Log.e(TAG, "Gateway without location name found. This should never happen. Provider misconfigured?"); @@ -139,23 +145,25 @@ public class GatewaysManager { // fake values for now Random rand = new Random(); double averageLoad = rand.nextDouble(); //location.averageLoad; - Log.d(TAG, "getGatewayLocations - new averageLoad (" + gateway.getName() + "): " + averageLoad); + Log.d(TAG, "getGatewayLocations - new averageLoad (" + gateway.getName() + " - " + gateway.getHost()+ "): " + averageLoad); Location location = new Location( gateway.getName(), averageLoad /*gateway.getFullness()*/, - 1); + 1, + gateway.getSupportedTransports() + ); locations.add(location); } else { int index = locationNames.get(gateway.getName()); Location location = locations.get(index); location.averageLoad = (location.numberOfGateways * location.averageLoad + gateway.getFullness()) / (location.numberOfGateways + 1); - Log.d(TAG, "getGatewayLocations - updated averageLoad: (" + gateway.getName() + "): " + location.averageLoad); + Log.d(TAG, "getGatewayLocations - updated averageLoad: (" + gateway.getName() + " - " + gateway.getHost()+ "): " + location.averageLoad); location.numberOfGateways += 1; + location.supportedTransports.addAll(gateway.getSupportedTransports()); locations.set(index, location); } - n++; } return locations; diff --git a/app/src/main/res/layout/v_select_text_list_item.xml b/app/src/main/res/layout/v_select_text_list_item.xml index 1d7054a4..373de14f 100644 --- a/app/src/main/res/layout/v_select_text_list_item.xml +++ b/app/src/main/res/layout/v_select_text_list_item.xml @@ -16,14 +16,25 @@ tools:visibility="visible" /> + <androidx.appcompat.widget.AppCompatImageView + android:id="@+id/bridge_image" + android:layout_width="56dp" + android:layout_height="match_parent" + android:layout_toStartOf="@id/quality" + android:layout_toLeftOf="@id/quality" + android:src="@drawable/ic_bridge_36" + tools:visibility="visible" + android:visibility="gone" + /> + <androidx.appcompat.widget.AppCompatTextView android:id="@+id/location" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" - android:layout_toStartOf="@id/quality" - android:layout_toLeftOf="@id/quality" + android:layout_toStartOf="@id/bridge_image" + android:layout_toLeftOf="@id/bridge_image" android:ellipsize="end" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeightLarge" |