diff options
author | cyberta <cyberta@riseup.net> | 2021-11-25 13:00:01 +0000 |
---|---|---|
committer | cyberta <cyberta@riseup.net> | 2021-11-25 13:00:01 +0000 |
commit | 976843d09cc7455945bf42a3817445649fec7c05 (patch) | |
tree | 4a05965b62cdecae5e0630267adb09d51a13f667 /app/src/main | |
parent | dcee5f2fa1dc67e5b08223db3441da8bd38e8b20 (diff) | |
parent | d939fc28aaa8f9992d296ddf596fa703ffd5ccb0 (diff) |
Merge branch 'UDP_ui' into 'master'
UDP UI
See merge request leap/bitmask_android!147
Diffstat (limited to 'app/src/main')
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java | 23 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/base/models/Constants.java | 2 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java | 8 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java | 3 | ||||
-rw-r--r-- | app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java | 46 | ||||
-rw-r--r-- | app/src/main/res/drawable-hdpi/ic_multiple_stop.png | bin | 0 -> 472 bytes | |||
-rw-r--r-- | app/src/main/res/drawable-ldpi/ic_multiple_stop.png | bin | 0 -> 311 bytes | |||
-rw-r--r-- | app/src/main/res/drawable-mdpi/ic_multiple_stop.png | bin | 0 -> 311 bytes | |||
-rw-r--r-- | app/src/main/res/drawable-xhdpi/ic_multiple_stop.png | bin | 0 -> 455 bytes | |||
-rw-r--r-- | app/src/main/res/drawable-xxhdpi/ic_multiple_stop.png | bin | 0 -> 663 bytes | |||
-rw-r--r-- | app/src/main/res/drawable-xxxhdpi/ic_multiple_stop.png | bin | 0 -> 837 bytes | |||
-rw-r--r-- | app/src/main/res/layout/f_settings.xml | 178 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 3 |
13 files changed, 162 insertions, 101 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java index ed1e8b6d..7157d1cc 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java @@ -34,10 +34,12 @@ 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; import static se.leap.bitmaskclient.base.models.Constants.USE_IPv6_FIREWALL; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferUDP; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getShowAlwaysOnDialog; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseSnowflake; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.hasSnowflakePrefs; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.preferUDP; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useSnowflake; @@ -63,10 +65,11 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh View view = inflater.inflate(R.layout.f_settings, container, false); initAlwaysOnVpnEntry(view); initExcludeAppsEntry(view); - initFirewallEntry(view); - initTetheringEntry(view); + initPreferUDPEntry(view); initUseBridgesEntry(view); initUseSnowflakeEntry(view); + initFirewallEntry(view); + initTetheringEntry(view); return view; } @@ -126,6 +129,22 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh } } + private void initPreferUDPEntry(View rootView) { + IconSwitchEntry useSnowflake = rootView.findViewById(R.id.prefer_udp); + useSnowflake.setVisibility(VISIBLE); + useSnowflake.setChecked(getPreferUDP(getContext())); + useSnowflake.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (!buttonView.isPressed()) { + return; + } + preferUDP(getContext(), isChecked); + if (VpnStatus.isVPNActive()) { + EipCommand.startVPN(getContext(), false); + showVPNFragment(); + } + }); + } + private void initExcludeAppsEntry(View rootView) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { IconTextEntry excludeApps = rootView.findViewById(R.id.exclude_apps); 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 016a8563..468b1b01 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 @@ -42,6 +42,7 @@ public interface Constants { String LAST_UPDATE_CHECK = "last_update_check"; String PREFERRED_CITY = "preferred_city"; String USE_SNOWFLAKE = "use_snowflake"; + String PREFER_UDP = "prefer_UDP"; ////////////////////////////////////////////// @@ -163,6 +164,7 @@ public interface Constants { String REMOTE = "remote"; String PORTS = "ports"; String PROTOCOLS = "protocols"; + String UDP = "udp"; String CAPABILITIES = "capabilities"; String TRANSPORT = "transport"; String TYPE = "type"; diff --git a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java index 515ec282..fe9100cb 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java @@ -29,6 +29,7 @@ import static se.leap.bitmaskclient.base.models.Constants.EXCLUDED_APPS; import static se.leap.bitmaskclient.base.models.Constants.LAST_UPDATE_CHECK; import static se.leap.bitmaskclient.base.models.Constants.LAST_USED_PROFILE; import static se.leap.bitmaskclient.base.models.Constants.PREFERRED_CITY; +import static se.leap.bitmaskclient.base.models.Constants.PREFER_UDP; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_CONFIGURED; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_EIP_DEFINITION; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY; @@ -145,6 +146,13 @@ public class PreferenceHelper { return getBoolean(context, RESTART_ON_UPDATE, false); } + public static boolean getPreferUDP(Context context) { + return getBoolean(context, PREFER_UDP, false); + } + + public static void preferUDP(Context context, boolean prefer) { + putBoolean(context, PREFER_UDP, prefer); + } public static boolean getUseBridges(SharedPreferences preferences) { return preferences.getBoolean(USE_BRIDGES, false); 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 a3d3abbc..60507363 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -174,7 +174,8 @@ public class Gateway { */ private @NonNull HashMap<Connection.TransportType, VpnProfile> createVPNProfiles(Context context) throws ConfigParser.ConfigParseError, IOException, JSONException { - VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway, apiVersion); + boolean preferUDP = PreferenceHelper.getPreferUDP(context); + VpnConfigGenerator vpnConfigurationGenerator = new VpnConfigGenerator(generalConfiguration, secrets, gateway, apiVersion, preferUDP); HashMap<Connection.TransportType, VpnProfile> profiles = vpnConfigurationGenerator.generateVpnProfiles(); addProfileInfos(context, profiles); return profiles; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java index d72f0936..303959d0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -48,6 +48,7 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICA import static se.leap.bitmaskclient.base.models.Constants.REMOTE; import static se.leap.bitmaskclient.base.models.Constants.TRANSPORT; import static se.leap.bitmaskclient.base.models.Constants.TYPE; +import static se.leap.bitmaskclient.base.models.Constants.UDP; import static se.leap.bitmaskclient.pluggableTransports.Dispatcher.DISPATCHER_IP; import static se.leap.bitmaskclient.pluggableTransports.Dispatcher.DISPATCHER_PORT; @@ -57,16 +58,18 @@ public class VpnConfigGenerator { private JSONObject secrets; private JSONObject obfs4Transport; private int apiVersion; + private boolean preferUDP; public final static String TAG = VpnConfigGenerator.class.getSimpleName(); private final String newLine = System.getProperty("line.separator"); // Platform new line - public VpnConfigGenerator(JSONObject generalConfiguration, JSONObject secrets, JSONObject gateway, int apiVersion) throws ConfigParser.ConfigParseError { + public VpnConfigGenerator(JSONObject generalConfiguration, JSONObject secrets, JSONObject gateway, int apiVersion, boolean preferUDP) throws ConfigParser.ConfigParseError { this.generalConfiguration = generalConfiguration; this.gateway = gateway; this.secrets = secrets; this.apiVersion = apiVersion; + this.preferUDP = preferUDP; checkCapabilities(); } @@ -174,7 +177,7 @@ public class VpnConfigGenerator { default: case 1: case 2: - ipAddress = gateway.getString(IP_ADDRESS); + ipAddress = gateway.getString(IP_ADDRESS); gatewayConfigApiv1(stringBuilder, ipAddress, capabilities); break; case 3: @@ -213,9 +216,9 @@ public class VpnConfigGenerator { int port; String protocol; JSONArray ports = capabilities.getJSONArray(PORTS); + JSONArray protocols = capabilities.getJSONArray(PROTOCOLS); for (int i = 0; i < ports.length(); i++) { port = ports.getInt(i); - JSONArray protocols = capabilities.getJSONArray(PROTOCOLS); for (int j = 0; j < protocols.length(); j++) { protocol = protocols.optString(j); String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine; @@ -229,14 +232,35 @@ public class VpnConfigGenerator { String protocol; JSONObject openvpnTransport = getTransport(transports, OPENVPN); JSONArray ports = openvpnTransport.getJSONArray(PORTS); - for (int j = 0; j < ports.length(); j++) { - port = ports.getString(j); - JSONArray protocols = openvpnTransport.getJSONArray(PROTOCOLS); - for (int k = 0; k < protocols.length(); k++) { - protocol = protocols.optString(k); - for (String ipAddress : ipAddresses) { - String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine; - stringBuilder.append(newRemote); + JSONArray protocols = openvpnTransport.getJSONArray(PROTOCOLS); + if (preferUDP) { + StringBuilder udpRemotes = new StringBuilder(); + StringBuilder tcpRemotes = new StringBuilder(); + for (int i = 0; i < protocols.length(); i++) { + protocol = protocols.optString(i); + for (int j = 0; j < ports.length(); j++) { + port = ports.optString(j); + for (String ipAddress : ipAddresses) { + String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine; + if (UDP.equals(protocol)) { + udpRemotes.append(newRemote); + } else { + tcpRemotes.append(newRemote); + } + } + } + } + stringBuilder.append(udpRemotes.toString()); + stringBuilder.append(tcpRemotes.toString()); + } else { + for (int j = 0; j < ports.length(); j++) { + port = ports.getString(j); + for (int k = 0; k < protocols.length(); k++) { + protocol = protocols.optString(k); + for (String ipAddress : ipAddresses) { + String newRemote = REMOTE + " " + ipAddress + " " + port + " " + protocol + newLine; + stringBuilder.append(newRemote); + } } } } diff --git a/app/src/main/res/drawable-hdpi/ic_multiple_stop.png b/app/src/main/res/drawable-hdpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..cd67c160 --- /dev/null +++ b/app/src/main/res/drawable-hdpi/ic_multiple_stop.png diff --git a/app/src/main/res/drawable-ldpi/ic_multiple_stop.png b/app/src/main/res/drawable-ldpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..fc0a47e1 --- /dev/null +++ b/app/src/main/res/drawable-ldpi/ic_multiple_stop.png diff --git a/app/src/main/res/drawable-mdpi/ic_multiple_stop.png b/app/src/main/res/drawable-mdpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..fc0a47e1 --- /dev/null +++ b/app/src/main/res/drawable-mdpi/ic_multiple_stop.png diff --git a/app/src/main/res/drawable-xhdpi/ic_multiple_stop.png b/app/src/main/res/drawable-xhdpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..c16a18c1 --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/ic_multiple_stop.png diff --git a/app/src/main/res/drawable-xxhdpi/ic_multiple_stop.png b/app/src/main/res/drawable-xxhdpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..b6fe22a8 --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/ic_multiple_stop.png diff --git a/app/src/main/res/drawable-xxxhdpi/ic_multiple_stop.png b/app/src/main/res/drawable-xxxhdpi/ic_multiple_stop.png Binary files differnew file mode 100644 index 00000000..6cf3f58b --- /dev/null +++ b/app/src/main/res/drawable-xxxhdpi/ic_multiple_stop.png diff --git a/app/src/main/res/layout/f_settings.xml b/app/src/main/res/layout/f_settings.xml index b625d548..a4d86fa6 100644 --- a/app/src/main/res/layout/f_settings.xml +++ b/app/src/main/res/layout/f_settings.xml @@ -1,105 +1,109 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" - android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="@dimen/stdpadding" > - - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/general_header" + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.AppCompat.Title" - android:text="@string/vpn_settings" - android:paddingTop="@dimen/activity_margin" - /> + android:orientation="vertical"> - <se.leap.bitmaskclient.base.views.IconTextEntry - android:id="@+id/always_on_vpn" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/always_on_vpn" - app:subtitle="@string/subtitle_always_on_vpn" - app:icon="@drawable/ic_always_on_36" - android:visibility="visible" - /> + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/general_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + android:text="@string/vpn_settings" + android:paddingTop="@dimen/activity_margin" + /> - <se.leap.bitmaskclient.base.views.IconTextEntry - android:id="@+id/exclude_apps" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/exclude_apps_fragment_title" - app:icon="@drawable/ic_shield_remove_grey600_36dp" - android:visibility="visible" - /> + <se.leap.bitmaskclient.base.views.IconTextEntry + android:id="@+id/always_on_vpn" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/always_on_vpn" + app:subtitle="@string/subtitle_always_on_vpn" + app:icon="@drawable/ic_always_on_36" + android:visibility="visible" + /> - <!-- <se.leap.bitmaskclient.base.views.IconSwitchEntry - android:id="@+id/prefer_udp" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/prefer_udp" - app:subtitle="@string/prefer_udp_subtitle" - app:icon="@drawable/ic_multiple_stop" - app:singleLine="false" - /> - --> + <se.leap.bitmaskclient.base.views.IconTextEntry + android:id="@+id/exclude_apps" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/exclude_apps_fragment_title" + app:icon="@drawable/ic_shield_remove_grey600_36dp" + android:visibility="visible" + /> - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/circumvention_header" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.AppCompat.Title" - android:text="@string/censorship_circumvention" - android:paddingTop="@dimen/activity_margin" - /> - <se.leap.bitmaskclient.base.views.IconSwitchEntry - android:id="@+id/bridges_switch" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/nav_drawer_obfuscated_connection" - app:subtitle="@string/nav_drawer_subtitle_obfuscated_connection" - app:icon="@drawable/ic_bridge_36" - app:singleLine="false" - /> + <se.leap.bitmaskclient.base.views.IconSwitchEntry + android:id="@+id/prefer_udp" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/prefer_udp" + app:subtitle="@string/prefer_udp_subtitle" + app:icon="@drawable/ic_multiple_stop" + app:singleLine="false" + /> - <se.leap.bitmaskclient.base.views.IconSwitchEntry - android:id="@+id/snowflake_switch" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:icon="@drawable/ic_snowflake" - app:text="@string/use_snowflake" - app:subtitle="@string/snowflake_description" - app:singleLine="false" - /> + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/circumvention_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + android:text="@string/censorship_circumvention" + android:paddingTop="@dimen/activity_margin" + /> + <se.leap.bitmaskclient.base.views.IconSwitchEntry + android:id="@+id/bridges_switch" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/nav_drawer_obfuscated_connection" + app:subtitle="@string/nav_drawer_subtitle_obfuscated_connection" + app:icon="@drawable/ic_bridge_36" + app:singleLine="false" + /> - <androidx.appcompat.widget.AppCompatTextView - android:id="@+id/experimental_header" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.AppCompat.Title" - android:text="@string/experimental_features" - android:paddingTop="@dimen/activity_margin" - /> + <se.leap.bitmaskclient.base.views.IconSwitchEntry + android:id="@+id/snowflake_switch" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:icon="@drawable/ic_snowflake" + app:text="@string/use_snowflake" + app:subtitle="@string/snowflake_description" + app:singleLine="false" + /> + <androidx.appcompat.widget.AppCompatTextView + android:id="@+id/experimental_header" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.AppCompat.Title" + android:text="@string/experimental_features" + android:paddingTop="@dimen/activity_margin" + /> - <se.leap.bitmaskclient.base.views.IconSwitchEntry - android:id="@+id/enableIPv6Firewall" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/ipv6Firewall" - app:subtitle="@string/require_root" - app:icon="@drawable/ic_cancel" - /> - <se.leap.bitmaskclient.base.views.IconTextEntry - android:id="@+id/tethering" - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:text="@string/tethering" - app:subtitle="@string/require_root" - app:icon="@drawable/ic_access_point_36" - /> + <se.leap.bitmaskclient.base.views.IconSwitchEntry + android:id="@+id/enableIPv6Firewall" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/ipv6Firewall" + app:subtitle="@string/require_root" + app:icon="@drawable/ic_cancel" + /> + + <se.leap.bitmaskclient.base.views.IconTextEntry + android:id="@+id/tethering" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:text="@string/tethering" + app:subtitle="@string/require_root" + app:icon="@drawable/ic_access_point_36" + /> -</LinearLayout>
\ No newline at end of file + </LinearLayout> +</ScrollView>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c49a456e..9ef0b9a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -188,5 +188,8 @@ <string name="use_snowflake">Use Snowflake</string> <string name="snowflake_description">Circumvent blocking of the provider\'s configuration server.</string> <string name="vpn_settings">VPN settings</string> + <string name="prefer_udp">Use UDP if available</string> + <string name="prefer_udp_subtitle">UDP can be faster and better for streaming, but does not work for all networks.</string> + </resources> |