diff options
7 files changed, 53 insertions, 19 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 db19b86a..ed1e8b6d 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 @@ -36,7 +36,10 @@ 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.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.useBridges; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useSnowflake; public class SettingsFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -63,6 +66,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh initFirewallEntry(view); initTetheringEntry(view); initUseBridgesEntry(view); + initUseSnowflakeEntry(view); return view; } @@ -94,6 +98,17 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh } } + private void initUseSnowflakeEntry(View rootView) { + IconSwitchEntry useSnowflake = rootView.findViewById(R.id.snowflake_switch); + useSnowflake.setVisibility(VISIBLE); + useSnowflake.setChecked(hasSnowflakePrefs(getContext()) && getUseSnowflake(getContext())); + useSnowflake.setOnCheckedChangeListener((buttonView, isChecked) -> { + if (!buttonView.isPressed()) { + return; + } + useSnowflake(getContext(), isChecked); + }); + } private void initAlwaysOnVpnEntry(View rootView) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 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 d91880c6..016a8563 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 @@ -41,7 +41,7 @@ public interface Constants { String RESTART_ON_UPDATE = "restart_on_update"; String LAST_UPDATE_CHECK = "last_update_check"; String PREFERRED_CITY = "preferred_city"; - String USE_TOR = "use_tor"; + String USE_SNOWFLAKE = "use_snowflake"; ////////////////////////////////////////////// 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 40b7fc05..515ec282 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 @@ -2,6 +2,7 @@ package se.leap.bitmaskclient.base.utils; import android.content.Context; import android.content.SharedPreferences; +import android.preference.Preference; import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; @@ -37,7 +38,7 @@ import static se.leap.bitmaskclient.base.models.Constants.SHARED_PREFERENCES; import static se.leap.bitmaskclient.base.models.Constants.SHOW_EXPERIMENTAL; 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.models.Constants.USE_TOR; +import static se.leap.bitmaskclient.base.models.Constants.USE_SNOWFLAKE; /** * Created by cyberta on 18.03.18. @@ -155,20 +156,29 @@ public class PreferenceHelper { public static void useBridges(Context context, boolean isEnabled) { putBoolean(context, USE_BRIDGES, isEnabled); - putBoolean(context, USE_TOR, isEnabled); + } + + public static Boolean getUseSnowflake(SharedPreferences preferences) { + return preferences.getBoolean(USE_SNOWFLAKE, true); + } + + public static void useSnowflake(Context context, boolean isEnabled) { + putBoolean(context, USE_SNOWFLAKE, isEnabled); if (!isEnabled) { TorStatusObservable.setProxyPort(-1); } } - // in contrast to USE_BRIDGES, USE_TOR in enabled by default - // This way the initial provider setup can rely on tor as fallback circumvention mechanism - public static Boolean getUseTor(SharedPreferences preferences) { - return preferences.getBoolean(USE_TOR, true); + public static boolean hasSnowflakePrefs(SharedPreferences preferences) { + return preferences.contains(USE_SNOWFLAKE); } - public static Boolean getUseTor(Context context) { - return getBoolean(context, USE_TOR, true); + public static boolean hasSnowflakePrefs(Context context) { + return hasKey(context, USE_SNOWFLAKE); + } + + public static Boolean getUseSnowflake(Context context) { + return getBoolean(context, USE_SNOWFLAKE, true); } public static void saveBattery(Context context, boolean isEnabled) { @@ -306,7 +316,7 @@ public class PreferenceHelper { preferences.edit().putString(key, value).apply(); } - public static Boolean getBoolean(Context context, String key, Boolean defValue) { + public static boolean getBoolean(Context context, String key, Boolean defValue) { if (context == null) { return false; } @@ -323,4 +333,13 @@ public class PreferenceHelper { SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); preferences.edit().putBoolean(key, value).apply(); } + + private static Boolean hasKey(Context context, String key) { + if (context == null) { + return false; + } + + SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + return preferences.contains(key); + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 52046e07..808d9e75 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -200,7 +200,7 @@ public abstract class ProviderApiManagerBase { } try { - if (PreferenceHelper.getUseBridges(preferences)) { + if (PreferenceHelper.hasSnowflakePrefs(preferences)) { startTorProxy(); } } catch (InterruptedException | IllegalStateException e) { @@ -313,7 +313,7 @@ public abstract class ProviderApiManagerBase { protected boolean startTorProxy() throws InterruptedException, IllegalStateException, TimeoutException { if (EipStatus.getInstance().isDisconnected() && - PreferenceHelper.getUseTor(preferences) && + PreferenceHelper.getUseSnowflake(preferences) && serviceCallback.startTorService()) { waitForTorCircuits(); if (TorStatusObservable.isCancelled()) { diff --git a/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java b/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java index 461ee356..68988b67 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java @@ -126,7 +126,7 @@ public class TorServiceCommand { private static TorServiceConnection initTorServiceConnection(Context context) throws InterruptedException, IllegalStateException { Log.d(TAG, "initTorServiceConnection"); - if (PreferenceHelper.getUseTor(context)) { + if (PreferenceHelper.getUseSnowflake(context)) { Log.d(TAG, "serviceConnection is still null"); if (!TorService.hasClientTransportPlugin()) { TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); diff --git a/app/src/main/res/layout/f_settings.xml b/app/src/main/res/layout/f_settings.xml index 6e0e2eb2..b625d548 100644 --- a/app/src/main/res/layout/f_settings.xml +++ b/app/src/main/res/layout/f_settings.xml @@ -65,7 +65,7 @@ /> <se.leap.bitmaskclient.base.views.IconSwitchEntry - android:id="@+id/use_snowflake" + android:id="@+id/snowflake_switch" android:layout_width="match_parent" android:layout_height="wrap_content" app:icon="@drawable/ic_snowflake" diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java index 5bed679b..4d3049f4 100644 --- a/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/eip/ProviderApiManagerTest.java @@ -58,7 +58,7 @@ import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.models.Constants.USE_BRIDGES; -import static se.leap.bitmaskclient.base.models.Constants.USE_TOR; +import static se.leap.bitmaskclient.base.models.Constants.USE_SNOWFLAKE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_GEOIP_JSON; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_GEOIP_JSON; @@ -525,7 +525,7 @@ public class ProviderApiManagerTest { Provider provider = getConfiguredProvider(); mockFingerprintForCertificate("a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494"); mockProviderApiConnector(ERROR_GEOIP_SERVICE_IS_DOWN); - mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_TOR, false).commit(); + mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_SNOWFLAKE, false).commit(); providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback()); Bundle expectedResult = mockBundle(); @@ -722,7 +722,7 @@ public class ProviderApiManagerTest { mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494"); mockProviderApiConnector(NO_ERROR_API_V4); - mockPreferences.edit().putBoolean(USE_BRIDGES, true).putBoolean(USE_TOR, true).commit(); + mockPreferences.edit().putBoolean(USE_BRIDGES, true).putBoolean(USE_SNOWFLAKE, true).commit(); providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback()); Intent providerApiCommand = mockIntent(); @@ -743,7 +743,7 @@ public class ProviderApiManagerTest { mockFingerprintForCertificate(" a5244308a1374709a9afce95e3ae47c1b44bc2398c0a70ccbf8b3a8a97f29494"); mockProviderApiConnector(NO_ERROR_API_V4); - mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_TOR, false).commit(); + mockPreferences.edit().putBoolean(USE_BRIDGES, false).putBoolean(USE_SNOWFLAKE, false).commit(); providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback()); Intent providerApiCommand = mockIntent(); @@ -761,7 +761,7 @@ public class ProviderApiManagerTest { public void test_handleIntentSetupProvider_TorBridgesPreferencesEnabledTimeout_TimeoutError() throws IOException, CertificateEncodingException, NoSuchAlgorithmException, TimeoutException, InterruptedException { Provider provider = getConfiguredProviderAPIv4(); - mockPreferences.edit().putBoolean(USE_BRIDGES, true).putBoolean(USE_TOR, true).commit(); + mockPreferences.edit().putBoolean(USE_BRIDGES, true).putBoolean(USE_SNOWFLAKE, true).commit(); providerApiManager = new ProviderApiManager(mockPreferences, mockResources, mockClientGenerator(), new TestProviderApiServiceCallback()); Bundle expectedResult = mockBundle(); |