diff options
6 files changed, 56 insertions, 53 deletions
| diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java index 3d6bb52c..888a6f6f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/CensorshipCircumventionFragment.java @@ -5,6 +5,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Kcp;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePortHopping;  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.resetSnowflakeSettings;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUsePortHopping;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseTunnel;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges; @@ -68,12 +69,11 @@ public class CensorshipCircumventionFragment extends Fragment {      private void initDiscovery() { - -        RadioButton noneRadioButton = new RadioButton(binding.getRoot().getContext()); -        noneRadioButton.setText(getText(R.string.automatically_select)); -        noneRadioButton.setId(DISCOVERY_AUTOMATICALLY); -        noneRadioButton.setChecked(!(hasSnowflakePrefs() && getUseSnowflake()) && !ProviderObservable.getInstance().getCurrentProvider().hasIntroducer()); -        binding.discoveryRadioGroup.addView(noneRadioButton); +        RadioButton automaticallyRadioButton = new RadioButton(binding.getRoot().getContext()); +        automaticallyRadioButton.setText(getText(R.string.automatically_select)); +        automaticallyRadioButton.setId(DISCOVERY_AUTOMATICALLY); +        automaticallyRadioButton.setChecked(!(hasSnowflakePrefs() && getUseSnowflake()) && !ProviderObservable.getInstance().getCurrentProvider().hasIntroducer()); +        binding.discoveryRadioGroup.addView(automaticallyRadioButton);          RadioButton snowflakeRadioButton = new RadioButton(binding.getRoot().getContext());          snowflakeRadioButton.setText(getText(R.string.snowflake)); @@ -92,14 +92,12 @@ public class CensorshipCircumventionFragment extends Fragment {          binding.discoveryRadioGroup.setOnCheckedChangeListener((group, checkedId) -> {              useBridges(true);              if (checkedId == DISCOVERY_AUTOMATICALLY) { -                useSnowflake(false); +                resetSnowflakeSettings();              } else if (checkedId == DISCOVERY_SNOWFLAKE) {                  useSnowflake(true);              } else if (checkedId == DISCOVERY_INVITE_PROXY) {                  useSnowflake(false);              } - -            tryReconnectVpn();          });      } 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 1a14995c..4567bf97 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 @@ -16,6 +16,7 @@ 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.preferUDP; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.resetSnowflakeSettings;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setAllowExperimentalTransports;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseObfuscationPinning;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUsePortHopping; @@ -23,7 +24,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.setUseTunnel;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useBridges;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useSnowflake; -import static se.leap.bitmaskclient.base.utils.PreferenceHelper.usesManualBridges; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useManualBridgeSettings;  import static se.leap.bitmaskclient.base.utils.ViewHelper.setActionBarSubtitle;  import android.app.AlertDialog; @@ -37,10 +38,12 @@ import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.EditText; +import android.widget.LinearLayout;  import android.widget.Toast;  import androidx.annotation.NonNull;  import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatTextView;  import androidx.appcompat.widget.SwitchCompat;  import androidx.fragment.app.DialogFragment;  import androidx.fragment.app.Fragment; @@ -94,43 +97,42 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh      private void initAutomaticCircumventionEntry(View rootView) {          IconSwitchEntry automaticCircumvention = rootView.findViewById(R.id.bridge_automatic_switch); -        if (ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports()) { -            automaticCircumvention.setVisibility(VISIBLE); - -            automaticCircumvention.setChecked(getUseBridges() && !usesManualBridges()); -            automaticCircumvention.setOnCheckedChangeListener((buttonView, isChecked) -> { -                if (!buttonView.isPressed()) { -                    return; -                } +        automaticCircumvention.setChecked(getUseBridges() && !useManualBridgeSettings()); +        automaticCircumvention.setOnCheckedChangeListener((buttonView, isChecked) -> { +            if (!buttonView.isPressed()) { +                return; +            } -                if (isChecked) { -                    useSnowflake(false); -                    setUseTunnel(TUNNELING_AUTOMATICALLY); -                    setUsePortHopping(false); -                } +            if (isChecked) { +                resetSnowflakeSettings(); +                setUseTunnel(TUNNELING_AUTOMATICALLY); +                setUsePortHopping(false); +            } else { +                useSnowflake(false); +            } +            if (ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports()) {                  useBridges(isChecked);                  if (VpnStatus.isVPNActive()) {                      EipCommand.startVPN(getContext(), false);                      Toast.makeText(getContext(), R.string.reconnecting, Toast.LENGTH_LONG).show();                  } -            }); +            } +        }); -            //We check the UI state of the useUdpEntry here as well, in order to avoid a situation -            //where both entries are disabled, because both preferences are enabled. -            //bridges can be enabled not only from here but also from error handling -            boolean useUDP = getPreferUDP() && useUdpEntry.isEnabled(); -            automaticCircumvention.setEnabled(!useUDP); -            automaticCircumvention.setSubtitle(getString(useUDP?R.string.disabled_while_udp_on:R.string.automatic_bridge_description)); -        } else { -            automaticCircumvention.setVisibility(GONE); -        } +        //We check the UI state of the useUdpEntry here as well, in order to avoid a situation +        //where both entries are disabled, because both preferences are enabled. +        //bridges can be enabled not only from here but also from error handling +        boolean useUDP = getPreferUDP() && useUdpEntry.isEnabled(); +        automaticCircumvention.setEnabled(!useUDP); +        automaticCircumvention.setSubtitle(getString(useUDP ? R.string.disabled_while_udp_on : R.string.automatic_bridge_description));      }      private void initManualCircumventionEntry(View rootView) { +        LinearLayout manualConfigRoot = rootView.findViewById(R.id.bridge_manual_switch_entry); +        manualConfigRoot.setVisibility(ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports() ? VISIBLE : GONE);          IconTextEntry manualConfiguration = rootView.findViewById(R.id.bridge_manual_switch); -        manualConfiguration.setVisibility(ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports() ? VISIBLE : GONE);          SwitchCompat manualConfigurationSwitch = rootView.findViewById(R.id.bridge_manual_switch_control); -        boolean usesManualBridge = usesManualBridges(); +        boolean usesManualBridge = useManualBridgeSettings();          manualConfigurationSwitch.setChecked(usesManualBridge);          manualConfigurationSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {              if (!buttonView.isPressed()) { @@ -148,7 +150,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh          //bridges can be enabled not only from here but also from error handling          boolean useUDP = getPreferUDP() && useUdpEntry.isEnabled();          manualConfiguration.setEnabled(!useUDP); -        manualConfiguration.setSubtitle(getString(useUDP? R.string.disabled_while_udp_on:R.string.manual_bridge_description)); +        manualConfiguration.setSubtitle(getString(useUDP ? R.string.disabled_while_udp_on : R.string.manual_bridge_description));      }      private void resetManualConfig() { 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 a698630c..0bf5dfb2 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 @@ -65,13 +65,10 @@ import androidx.annotation.WorkerThread;  import androidx.security.crypto.EncryptedSharedPreferences;  import androidx.security.crypto.MasterKey; -import com.google.gson.Gson; -  import org.json.JSONException;  import org.json.JSONObject;  import java.io.IOException; -import java.net.MalformedURLException;  import java.net.URL;  import java.security.GeneralSecurityException;  import java.util.HashMap; @@ -81,9 +78,6 @@ import java.util.Set;  import de.blinkt.openvpn.VpnProfile;  import de.blinkt.openvpn.core.NativeUtils; -import io.swagger.client.JSON; -import mobile.BitmaskMobile; -import mobilemodels.BitmaskMobileCore;  import se.leap.bitmaskclient.BuildConfig;  import se.leap.bitmaskclient.base.models.Introducer;  import se.leap.bitmaskclient.base.models.Provider; @@ -491,6 +485,10 @@ public class PreferenceHelper {          return hasKey(USE_SNOWFLAKE);      } +    public static void resetSnowflakeSettings() { +        removeKey(USE_SNOWFLAKE); +    } +      public static Boolean getUseSnowflake() {          return getBoolean(USE_SNOWFLAKE, true);      } @@ -619,12 +617,8 @@ public class PreferenceHelper {          return getUseTunnel() == TUNNELING_OBFS4_KCP;      } -    public static boolean usesManualBridges(){ -        return getUseSnowflake() || usesSpecificTunnel() || getUsePortHopping(); -    } - -    public static boolean usesSpecificTunnel() { -        return getUseObfs4() || getUseObfs4Kcp(); +    public static boolean useManualBridgeSettings(){ +        return (hasSnowflakePrefs() && getUseSnowflake()) || getUseObfs4() || getUseObfs4Kcp() || getUsePortHopping();      }      public static void setUseTunnel(int tunnel) { @@ -709,6 +703,12 @@ public class PreferenceHelper {          }      } +    public static void removeKey(String key) { +        synchronized (LOCK) { +            preferences.edit().remove(key).apply(); +        } +    } +      public static long getLong(String key, long defValue) {          synchronized (LOCK) {              return preferences.getLong(key, defValue); 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 d7f3b42e..9655013c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -37,7 +37,6 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseBridges;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUseObfs4Kcp;  import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getUsePortHopping; -import static se.leap.bitmaskclient.base.utils.PreferenceHelper.usesSpecificTunnel;  import android.content.Context;  import android.util.Log; @@ -54,10 +53,8 @@ import org.json.JSONObject;  import java.io.IOException;  import java.lang.reflect.Type;  import java.util.ArrayList; -import java.util.Arrays;  import java.util.Collections;  import java.util.HashMap; -import java.util.HashSet;  import java.util.LinkedHashMap;  import java.util.List;  import java.util.Set; diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java index 58fccc65..d7d8516e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java @@ -1,5 +1,6 @@  package se.leap.bitmaskclient.providersetup.fragments; +import static se.leap.bitmaskclient.base.fragments.CensorshipCircumventionFragment.TUNNELING_AUTOMATICALLY;  import static se.leap.bitmaskclient.base.utils.BuildConfigHelper.isDefaultBitmask;  import android.graphics.Typeface; @@ -35,14 +36,17 @@ public class CircumventionSetupFragment extends BaseSetupFragment implements Can              if (binding.rbCircumvention.getId() == checkedId) {                  PreferenceHelper.useBridges(true);                  PreferenceHelper.useSnowflake(true); +                PreferenceHelper.setUseTunnel(TUNNELING_AUTOMATICALLY);                  binding.tvCircumventionDetailDescription.setVisibility(View.VISIBLE);                  binding.rbCircumvention.setTypeface(Typeface.DEFAULT, Typeface.BOLD);                  binding.rbPlainVpn.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);                  return;              } - +            // otherwise don't use obfuscation              PreferenceHelper.useBridges(false); -            PreferenceHelper.useSnowflake(false); +            PreferenceHelper.resetSnowflakeSettings(); +            PreferenceHelper.setUsePortHopping(false); +            PreferenceHelper.setUseTunnel(TUNNELING_AUTOMATICALLY);              binding.tvCircumventionDetailDescription.setVisibility(View.GONE);              binding.rbPlainVpn.setTypeface(Typeface.DEFAULT, Typeface.BOLD);              binding.rbCircumvention.setTypeface(Typeface.DEFAULT, Typeface.NORMAL); diff --git a/app/src/main/res/layout/f_settings.xml b/app/src/main/res/layout/f_settings.xml index e7b4356f..87a97455 100644 --- a/app/src/main/res/layout/f_settings.xml +++ b/app/src/main/res/layout/f_settings.xml @@ -60,9 +60,11 @@              app:text="@string/automatic_bridge"              app:subtitle="@string/automatic_bridge_description"              app:icon="@drawable/bridge_automatic" +            android:visibility="visible"              app:singleLine="false" />          <LinearLayout +            android:id="@+id/bridge_manual_switch_entry"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"> | 
