From 64449816223cb9abb6e75310c03dcc9353a42ee4 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Wed, 2 Aug 2023 22:45:26 +0200 Subject: use single instance of shared prefernces across the app, this reduces the laggyness of the UI noticably --- .../blinkt/openvpn/core/DeviceStateReceiver.java | 15 +- .../de/blinkt/openvpn/core/OpenVPNService.java | 4 +- .../java/de/blinkt/openvpn/core/VpnStatus.java | 11 +- .../se/leap/bitmaskclient/base/BitmaskApp.java | 8 +- .../se/leap/bitmaskclient/base/MainActivity.java | 8 +- .../se/leap/bitmaskclient/base/OnBootReceiver.java | 9 +- .../se/leap/bitmaskclient/base/StartActivity.java | 31 +- .../base/fragments/AlwaysOnDialog.java | 2 +- .../base/fragments/DonationReminderDialog.java | 12 +- .../bitmaskclient/base/fragments/EipFragment.java | 26 +- .../base/fragments/ExcludeAppsFragment.java | 4 +- .../base/fragments/GatewaySelectionFragment.java | 20 +- .../bitmaskclient/base/fragments/LogFragment.java | 8 +- .../base/fragments/MainActivityErrorDialog.java | 10 +- .../base/fragments/NavigationDrawerFragment.java | 21 +- .../base/fragments/ObfuscationProxyDialog.java | 23 +- .../base/fragments/SettingsFragment.java | 50 +- .../base/fragments/TetheringDialog.java | 12 +- .../bitmaskclient/base/utils/PreferenceHelper.java | 725 ++++++++++++--------- .../main/java/se/leap/bitmaskclient/eip/EIP.java | 25 +- .../leap/bitmaskclient/eip/EipSetupObserver.java | 17 +- .../java/se/leap/bitmaskclient/eip/Gateway.java | 32 +- .../se/leap/bitmaskclient/eip/GatewaysManager.java | 26 +- .../se/leap/bitmaskclient/eip/VoidVpnService.java | 8 +- .../leap/bitmaskclient/eip/VpnConfigGenerator.java | 1 - .../bitmaskclient/firewall/FirewallManager.java | 12 +- .../bitmaskclient/providersetup/ProviderAPI.java | 2 +- .../providersetup/ProviderApiManagerBase.java | 39 +- .../providersetup/ProviderSetupFailedDialog.java | 4 +- .../activities/ConfigWizardBaseActivity.java | 4 - .../fragments/CircumventionSetupFragment.java | 8 +- .../fragments/ConfigureProviderFragment.java | 4 +- .../tethering/TetheringStateManager.java | 6 +- .../leap/bitmaskclient/tor/TorServiceCommand.java | 9 +- .../providersetup/ProviderApiManager.java | 8 +- .../base/utils/PreferenceHelperTest.java | 7 +- .../se/leap/bitmaskclient/eip/EipStatusTest.java | 4 +- .../bitmaskclient/eip/GatewaySelectorTest.java | 4 + .../leap/bitmaskclient/testutils/MockHelper.java | 37 +- .../tethering/TetheringStateManagerTest.java | 2 - 40 files changed, 679 insertions(+), 579 deletions(-) diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index 219c1394..c3083a1f 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -5,6 +5,8 @@ package de.blinkt.openvpn.core; +import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -14,19 +16,14 @@ import android.net.NetworkInfo; import android.net.NetworkInfo.State; import android.os.Handler; import android.os.Looper; -import android.preference.PreferenceManager; -import se.leap.bitmaskclient.R; +import java.util.LinkedList; + import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; +import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.tethering.TetheringObservable; -import java.util.LinkedList; -import java.util.Objects; -import java.util.StringTokenizer; - -import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason; - public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener, OpenVPNManagement.PausedStateCallback { private final Handler mDisconnectHandler; private int lastNetwork = -1; @@ -143,7 +140,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) { networkStateChange(context); } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { - boolean screenOffPause = PreferenceHelper.getSaveBattery(context); + boolean screenOffPause = PreferenceHelper.getSaveBattery(); boolean isTethering = TetheringObservable.getInstance().getTetheringState().isVpnTetheringRunning(); if (screenOffPause && !isTethering) { if (VpnStatus.getLastConnectedVpnProfile() != null && !VpnStatus.getLastConnectedVpnProfile().mPersistTun) diff --git a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java index 6adffda1..575f1f59 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java +++ b/app/src/main/java/de/blinkt/openvpn/core/OpenVPNService.java @@ -335,7 +335,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac Log.d(TAG, "Starting VPN due to isAlwaysOn system settings or app crash."); startWithForegroundNotification(); - mProfile = VpnStatus.getLastConnectedVpnProfile(this); + mProfile = VpnStatus.getLastConnectedVpnProfile(); VpnStatus.logInfo(R.string.service_restarted); if (mProfile != null) { @@ -357,7 +357,7 @@ public class OpenVPNService extends VpnService implements StateListener, Callbac /* start the OpenVPN process itself in a background thread */ new Thread(this::startOpenVPN).start(); - VpnStatus.setLastConnectedVpnProfile(getApplicationContext(), mProfile); + VpnStatus.setLastConnectedVpnProfile(mProfile); return START_STICKY; } diff --git a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java index 8115548f..ecc03a19 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java +++ b/app/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -153,19 +153,14 @@ public class VpnStatus { } public static VpnProfile getLastConnectedVpnProfile() { - return lastConnectedProfile; + return lastConnectedProfile != null ? lastConnectedProfile : PreferenceHelper.getLastConnectedVpnProfile(); } - public static VpnProfile getLastConnectedVpnProfile(Context context) { - return PreferenceHelper.getLastConnectedVpnProfile(context); - } - - /** * Sets the profile that is connected (to connect if the service restarts) */ - public static void setLastConnectedVpnProfile(Context context, VpnProfile connectedProfile) { - PreferenceHelper.setLastUsedVpnProfile(context, connectedProfile); + public static void setLastConnectedVpnProfile(VpnProfile connectedProfile) { + PreferenceHelper.setLastUsedVpnProfile(connectedProfile); lastConnectedProfile = connectedProfile; setConnectedVPNProfile(lastConnectedProfile.getUUIDString()); } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java index 74b789a9..a66f75d7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java @@ -56,6 +56,8 @@ public class BitmaskApp extends MultiDexApplication { private DownloadBroadcastReceiver downloadBroadcastReceiver; private TorStatusObservable torStatusObservable; + private PreferenceHelper preferenceHelper; + @Override public void onCreate() { @@ -63,11 +65,11 @@ public class BitmaskApp extends MultiDexApplication { // Normal app init code...*/ PRNGFixes.apply(); Security.insertProviderAt(Conscrypt.newProvider(), 1); - SharedPreferences preferences = PreferenceHelper.getSharedPreferences(this); + preferenceHelper = new PreferenceHelper(this); providerObservable = ProviderObservable.getInstance(); - providerObservable.updateProvider(getSavedProviderFromSharedPreferences(preferences)); + providerObservable.updateProvider(getSavedProviderFromSharedPreferences()); torStatusObservable = TorStatusObservable.getInstance(); - EipSetupObserver.init(this, preferences); + EipSetupObserver.init(this); AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); if (!isCalyxOSWithTetheringSupport(this)) { TetheringStateManager.getInstance().init(this); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java index 248d96c7..b459f75d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java @@ -33,7 +33,6 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_SWITCH_PROVIDER; -import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInPreferences; import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_INVALID_VPN_CERTIFICATE; import static se.leap.bitmaskclient.eip.EIP.EIPErrors.ERROR_VPN_PREPARE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORID; @@ -47,7 +46,6 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; import android.view.Gravity; @@ -92,7 +90,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, public final static String TAG = MainActivity.class.getSimpleName(); private Provider provider; - private SharedPreferences preferences; private NavigationDrawerFragment navigationDrawerFragment; public final static String ACTION_SHOW_VPN_FRAGMENT = "action_show_vpn_fragment"; @@ -112,7 +109,6 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, navigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer); - preferences = PreferenceHelper.getSharedPreferences(this); provider = ProviderObservable.getInstance().getCurrentProvider(); EipSetupObserver.addListener(this); @@ -253,10 +249,10 @@ public class MainActivity extends AppCompatActivity implements EipSetupListener, return; } - storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); ProviderObservable.getInstance().updateProvider(provider); if (!provider.supportsPluggableTransports()) { - PreferenceHelper.useBridges(this, false); + PreferenceHelper.useBridges(false); } navigationDrawerFragment.refresh(); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java b/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java index a508329c..876f71da 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java @@ -3,12 +3,10 @@ package se.leap.bitmaskclient.base; import static android.content.Intent.ACTION_BOOT_COMPLETED; import static se.leap.bitmaskclient.base.models.Constants.APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE; import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT; -import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Build; import android.util.Log; @@ -17,8 +15,6 @@ import se.leap.bitmaskclient.base.utils.PreferenceHelper; public class OnBootReceiver extends BroadcastReceiver { - SharedPreferences preferences; - // Debug: am broadcast -a android.intent.action.BOOT_COMPLETED @Override public void onReceive(Context context, Intent intent) { @@ -26,9 +22,8 @@ public class OnBootReceiver extends BroadcastReceiver { if (intent == null || !ACTION_BOOT_COMPLETED.equals(intent.getAction())) { return; } - preferences = PreferenceHelper.getSharedPreferences(context); - boolean providerConfigured = !preferences.getString(PROVIDER_VPN_CERTIFICATE, "").isEmpty(); - boolean startOnBoot = preferences.getBoolean(EIP_RESTART_ON_BOOT, false) && Build.VERSION.SDK_INT < Build.VERSION_CODES.O; + boolean providerConfigured = !PreferenceHelper.getProviderVPNCertificate().isEmpty(); + boolean startOnBoot = PreferenceHelper.getRestartOnBoot() && Build.VERSION.SDK_INT < Build.VERSION_CODES.O; boolean isAlwaysOnConfigured = VpnStatus.isAlwaysOn(); Log.d("OpenVPN", "OpenVPN onBoot intent received. Provider configured? " + providerConfigured + " Start on boot? " + startOnBoot + " isAlwaysOn feature configured: " + isAlwaysOnConfigured); if (providerConfigured) { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java index 241fa4b9..715367f5 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java @@ -30,7 +30,6 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.storeProviderInP import android.app.Activity; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; import android.util.Log; @@ -75,12 +74,10 @@ public class StartActivity extends Activity{ private int versionCode; private int previousVersionCode; - private SharedPreferences preferences; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - preferences = PreferenceHelper.getSharedPreferences(this); Log.d(TAG, "Started"); @@ -131,7 +128,7 @@ public class StartActivity extends Activity{ private int checkAppStart() { try { versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode; - previousVersionCode = preferences.getInt(PREFERENCES_APP_VERSION, -1); + previousVersionCode = PreferenceHelper.getAppVersion(); // versions do match -> normal start if (versionCode == previousVersionCode) { @@ -163,10 +160,9 @@ public class StartActivity extends Activity{ */ private void executeUpgrade() { if (hasNewFeature(FeatureVersionCode.RENAMED_EIP_IN_PREFERENCES)) { - String eipJson = preferences.getString(PROVIDER_KEY, null); + String eipJson = PreferenceHelper.getString(PROVIDER_KEY, null); if (eipJson != null) { - preferences.edit().putString(PROVIDER_EIP_DEFINITION, eipJson). - remove(PROVIDER_KEY).apply(); + PreferenceHelper.putString(PROVIDER_EIP_DEFINITION, eipJson); } } @@ -176,7 +172,7 @@ public class StartActivity extends Activity{ // next setup Provider provider = ProviderObservable.getInstance().getCurrentProvider(); if (provider != null && !provider.isDefault()) { - PreferenceHelper.deleteProviderDetailsFromPreferences(preferences, provider.getDomain()); + PreferenceHelper.deleteProviderDetailsFromPreferences(provider.getDomain()); ProviderObservable.getInstance().updateProvider(new Provider()); } } @@ -190,20 +186,19 @@ public class StartActivity extends Activity{ // deletion of current configured provider so that a new provider setup is triggered Provider provider = ProviderObservable.getInstance().getCurrentProvider(); if (provider != null && !provider.isDefault()) { - PreferenceHelper.deleteProviderDetailsFromPreferences(preferences, provider.getDomain()); - PreferenceHelper.deleteCurrentProviderDetailsFromPreferences(preferences); + PreferenceHelper.deleteProviderDetailsFromPreferences(provider.getDomain()); + PreferenceHelper.deleteCurrentProviderDetailsFromPreferences(); ProviderObservable.getInstance().updateProvider(new Provider()); } } if (hasNewFeature(FeatureVersionCode.ENCRYPTED_SHARED_PREFS)) { PreferenceHelper.migrateToEncryptedPrefs(this); - preferences = PreferenceHelper.getSharedPreferences(this); } // always check if manual gateway selection feature switch has been disabled - if (!BuildConfig.allow_manual_gateway_selection && PreferenceHelper.getPreferredCity(this) != null) { - PreferenceHelper.setPreferredCity(this, null); + if (!BuildConfig.allow_manual_gateway_selection && PreferenceHelper.getPreferredCity() != null) { + PreferenceHelper.setPreferredCity(null); } // ensure all upgrades have passed before storing new information @@ -220,7 +215,7 @@ public class StartActivity extends Activity{ } private void storeAppVersion() { - preferences.edit().putInt(PREFERENCES_APP_VERSION, versionCode).apply(); + PreferenceHelper.setAppVersion(versionCode); } private void prepareEIP() { @@ -230,9 +225,9 @@ public class StartActivity extends Activity{ if (getIntent() != null && getIntent().getBooleanExtra(EIP_RESTART_ON_BOOT, false)) { EipCommand.startVPN(this, true); finish(); - } else if (PreferenceHelper.getRestartOnUpdate(this.getApplicationContext())) { + } else if (PreferenceHelper.getRestartOnUpdate()) { // This is relevant for web build flavor apks - PreferenceHelper.restartOnUpdate(this.getApplicationContext(), false); + PreferenceHelper.restartOnUpdate(false); EipCommand.startVPN(this, false); showNextActivity(provider); finish(); @@ -261,7 +256,7 @@ public class StartActivity extends Activity{ if (requestCode == REQUEST_CODE_CONFIGURE_LEAP) { if (resultCode == RESULT_OK && data != null && data.hasExtra(Provider.KEY)) { Provider provider = data.getParcelableExtra(Provider.KEY); - storeProviderInPreferences(preferences, provider); + storeProviderInPreferences( provider); ProviderObservable.getInstance().updateProvider(provider); EipCommand.startVPN(this, false); showNextActivity(provider); @@ -298,7 +293,7 @@ public class StartActivity extends Activity{ lastSeenHashes.add(hash); p.setMotdLastSeenHashes(lastSeenHashes); p.setLastMotdSeen(System.currentTimeMillis()); - PreferenceHelper.persistProviderAsync(this, p); + PreferenceHelper.persistProviderAsync(p); ProviderObservable.getInstance().updateProvider(p); } showMotdFragment(message); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/AlwaysOnDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/AlwaysOnDialog.java index 7d457406..e68ba170 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/AlwaysOnDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/AlwaysOnDialog.java @@ -68,7 +68,7 @@ public class AlwaysOnDialog extends AppCompatDialogFragment { builder.setView(view) .setPositiveButton(android.R.string.ok, (dialog, id) -> { if (doNotShowAgainCheckBox.isChecked()) { - saveShowAlwaysOnDialog(getContext(), false); + saveShowAlwaysOnDialog(false); } Intent intent = new Intent("android.net.vpn.SETTINGS"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/DonationReminderDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/DonationReminderDialog.java index c39386fc..08346791 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/DonationReminderDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/DonationReminderDialog.java @@ -67,13 +67,11 @@ public class DonationReminderDialog extends AppCompatDialogFragment { } catch (ActivityNotFoundException e) { e.printStackTrace(); } - PreferenceHelper.putString(getContext(), LAST_DONATION_REMINDER_DATE, - DateHelper.getCurrentDateString()); + PreferenceHelper.lastDonationReminderDate(DateHelper.getCurrentDateString()); dismiss(); }); btnLater.setOnClickListener(v -> { - PreferenceHelper.putString(getContext(), LAST_DONATION_REMINDER_DATE, - DateHelper.getCurrentDateString()); + PreferenceHelper.lastDonationReminderDate(DateHelper.getCurrentDateString()); dismiss(); }); @@ -100,9 +98,9 @@ public class DonationReminderDialog extends AppCompatDialogFragment { return false; } - String firstTimeUserDate = PreferenceHelper.getString(context, FIRST_TIME_USER_DATE, null); + String firstTimeUserDate = PreferenceHelper.getFirstTimeUserDate(); if (firstTimeUserDate == null) { - PreferenceHelper.putString(context, FIRST_TIME_USER_DATE, DateHelper.getCurrentDateString()); + PreferenceHelper.firstTimeUserDate(DateHelper.getCurrentDateString()); return false; } @@ -114,7 +112,7 @@ public class DonationReminderDialog extends AppCompatDialogFragment { return false; } - String lastDonationReminderDate = PreferenceHelper.getString(context, LAST_DONATION_REMINDER_DATE, null); + String lastDonationReminderDate = PreferenceHelper.getLastDonationReminderDate(); if (lastDonationReminderDate == null) { return true; } 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 a8d11869..f50b69a5 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 @@ -20,7 +20,6 @@ import static se.leap.bitmaskclient.R.string.vpn_certificate_user_message; import static se.leap.bitmaskclient.base.models.Constants.ASK_TO_CANCEL_VPN; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START; import static se.leap.bitmaskclient.base.models.Constants.EIP_EARLY_ROUTES; -import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP; import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_LOG_IN; @@ -36,7 +35,6 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.USER_MESSAGE; import android.app.Activity; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -93,8 +91,6 @@ public class EipFragment extends Fragment implements Observer { public final static String TAG = EipFragment.class.getSimpleName(); - - private SharedPreferences preferences; private Provider provider; AppCompatImageView background; @@ -156,12 +152,6 @@ public class EipFragment extends Fragment implements Observer { eipStatus = EipStatus.getInstance(); providerObservable = ProviderObservable.getInstance(); torStatusObservable = TorStatusObservable.getInstance(); - Activity activity = getActivity(); - if (activity != null) { - preferences = PreferenceHelper.getSharedPreferences(activity); - } else { - Log.e(TAG, "activity is null in onCreate - no preferences set!"); - } gatewaysManager = new GatewaysManager(getContext()); } @@ -274,7 +264,7 @@ public class EipFragment extends Fragment implements Observer { } private void saveStatus(boolean restartOnBoot) { - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, restartOnBoot).apply(); + PreferenceHelper.restartOnBoot(restartOnBoot); } void handleIcon() { @@ -438,7 +428,7 @@ public class EipFragment extends Fragment implements Observer { Log.d(TAG, "eip fragment eipStatus state: " + eipStatus.getState() + " - level: " + eipStatus.getLevel() + " - is reconnecting: " + eipStatus.isReconnecting()); if (eipStatus.isUpdatingVpnCert()) { setMainButtonEnabled(true); - String city = getPreferredCity(getContext()); + String city = getPreferredCity(); String locationName = VpnStatus.getCurrentlyConnectingVpnName() != null ? VpnStatus.getCurrentlyConnectingVpnName() : city == null ? getString(R.string.gateway_selection_recommended_location) : city; @@ -461,7 +451,7 @@ public class EipFragment extends Fragment implements Observer { setActivityBarColor(R.color.bg_connecting_top, R.color.bg_connecting_top_light_transparent); } else if (eipStatus.isConnecting()) { setMainButtonEnabled(true); - String city = getPreferredCity(getContext()); + String city = getPreferredCity(); String locationName = VpnStatus.getCurrentlyConnectingVpnName() != null ? VpnStatus.getCurrentlyConnectingVpnName() : city == null ? getString(R.string.gateway_selection_recommended_location) : city; @@ -478,11 +468,11 @@ public class EipFragment extends Fragment implements Observer { } else if (eipStatus.isConnected()) { setMainButtonEnabled(true); mainButton.updateState(true, false); - Connection.TransportType transportType = PreferenceHelper.getUseBridges(getContext()) ? Connection.TransportType.OBFS4 : Connection.TransportType.OPENVPN; - locationButton.setLocationLoad(PreferenceHelper.useObfuscationPinning(getContext()) ? GatewaysManager.Load.UNKNOWN : gatewaysManager.getLoadForLocation(VpnStatus.getLastConnectedVpnName(), transportType)); + Connection.TransportType transportType = PreferenceHelper.getUseBridges() ? Connection.TransportType.OBFS4 : Connection.TransportType.OPENVPN; + locationButton.setLocationLoad(PreferenceHelper.useObfuscationPinning() ? GatewaysManager.Load.UNKNOWN : gatewaysManager.getLoadForLocation(VpnStatus.getLastConnectedVpnName(), transportType)); locationButton.setText(VpnStatus.getLastConnectedVpnName()); locationButton.showBridgeIndicator(VpnStatus.isUsingBridges()); - locationButton.showRecommendedIndicator(getPreferredCity(getContext()) == null); + locationButton.showRecommendedIndicator(getPreferredCity() == null); mainDescription.setText(R.string.eip_status_secured); subDescription.setText(null); background.setImageResource(R.drawable.bg_connected); @@ -495,7 +485,7 @@ public class EipFragment extends Fragment implements Observer { locationButton.setText(VpnStatus.getCurrentlyConnectingVpnName()); locationButton.showBridgeIndicator(VpnStatus.isUsingBridges()); locationButton.showBridgeIndicator(VpnStatus.isUsingBridges()); - locationButton.showRecommendedIndicator(getPreferredCity(getContext())== null); + locationButton.showRecommendedIndicator(getPreferredCity()== null); mainDescription.setText(R.string.eip_state_connected); subDescription.setText(R.string.eip_state_no_network); background.setImageResource(R.drawable.bg_connecting); @@ -542,7 +532,7 @@ public class EipFragment extends Fragment implements Observer { mainButton.updateState(false, false); locationButton.setLocationLoad(UNKNOWN); locationButton.showBridgeIndicator(false); - String city = getPreferredCity(getContext()); + String city = getPreferredCity(); locationButton.setText(city == null ? getString(R.string.gateway_selection_recommended_location) : city); locationButton.showRecommendedIndicator(false); mainDescription.setText(R.string.eip_status_unsecured); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java index 98c2e438..89b167f3 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java @@ -255,7 +255,7 @@ public class ExcludeAppsFragment extends Fragment implements AdapterView.OnItemC @Override public void onDestroy() { - PreferenceHelper.setExcludedApps(this.getActivity().getApplicationContext(), apps); + PreferenceHelper.setExcludedApps(apps); super.onDestroy(); } @@ -263,7 +263,7 @@ public class ExcludeAppsFragment extends Fragment implements AdapterView.OnItemC public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - apps = PreferenceHelper.getExcludedApps(this.getContext()); + apps = PreferenceHelper.getExcludedApps(); setHasOptionsMenu(true); } 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 793c6407..dc7f64e1 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 @@ -73,7 +73,6 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca private SelectLocationEntry recommendedLocation; private GatewaysManager gatewaysManager; private EipStatus eipStatus; - private SharedPreferences preferences; private Connection.TransportType selectedTransport; private AppCompatTextView bridgesHint; private AppCompatTextView disableBridges; @@ -87,15 +86,14 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca super.onCreate(savedInstanceState); gatewaysManager = new GatewaysManager(getContext()); eipStatus = EipStatus.getInstance(); - preferences = PreferenceHelper.getSharedPreferences(getContext()); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - selectedTransport = getUseBridges(preferences) ? PT : OPENVPN; - preferences.registerOnSharedPreferenceChangeListener(this); + selectedTransport = getUseBridges() ? PT : OPENVPN; + PreferenceHelper.registerOnSharedPreferenceChangeListener(this); eipStatus.addObserver(this); return inflater.inflate(R.layout.f_gateway_selection, container, false); } @@ -113,7 +111,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca public void onDestroyView() { super.onDestroyView(); eipStatus.deleteObserver(this); - preferences.unregisterOnSharedPreferenceChangeListener(this); + PreferenceHelper.unregisterOnSharedPreferenceChangeListener(this); } private void initRecyclerView() { @@ -140,17 +138,17 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca private void initBridgesHint(@NonNull View view) { bridgesHint = view.findViewById(R.id.manual_subtitle); - bridgesHint.setVisibility(getUseBridges(getContext()) ? VISIBLE : GONE); + bridgesHint.setVisibility(getUseBridges() ? VISIBLE : GONE); disableBridges = view.findViewById(R.id.disable_bridges); - disableBridges.setVisibility(getUseBridges(getContext()) ? VISIBLE : GONE); + disableBridges.setVisibility(getUseBridges() ? VISIBLE : GONE); disableBridges.setOnClickListener(v -> { - useBridges(getContext(), false); + useBridges(false); }); } private void updateRecommendedLocation() { Location location = new Location(); - boolean isManualSelection = PreferenceHelper.getPreferredCity(getContext()) != null; + boolean isManualSelection = PreferenceHelper.getPreferredCity() != null; if (!isManualSelection && eipStatus.isConnected()) { try { location = gatewaysManager.getLocation(VpnStatus.getCurrentlyConnectingVpnName()).clone(); @@ -171,7 +169,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca if (context == null) { return; } - PreferenceHelper.setPreferredCity(context, preferredCity); + PreferenceHelper.setPreferredCity(preferredCity); EipCommand.startVPN(context, false); try { Intent intent = new Intent(context, MainActivity.class); @@ -207,7 +205,7 @@ public class GatewaySelectionFragment extends Fragment implements Observer, Loca @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(USE_BRIDGES)) { - boolean showBridges = getUseBridges(sharedPreferences); + boolean showBridges = getUseBridges(); selectedTransport = showBridges ? PT : OPENVPN; gatewaysManager.updateTransport(selectedTransport); locationListAdapter.updateTransport(selectedTransport, gatewaysManager); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java index 8f73595d..c7dd25da 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java @@ -22,7 +22,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; -import android.preference.PreferenceManager; import android.text.SpannableString; import android.text.format.DateFormat; import android.view.LayoutInflater; @@ -56,12 +55,11 @@ import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.LogItem; import de.blinkt.openvpn.core.OpenVPNManagement; import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.Preferences; import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.VpnStatus.LogListener; import de.blinkt.openvpn.core.VpnStatus.StateListener; import se.leap.bitmaskclient.R; -import se.leap.bitmaskclient.base.models.Constants; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { public static final String TAG = LogFragment.class.getSimpleName(); @@ -511,9 +509,9 @@ public class LogFragment extends ListFragment implements StateListener, SeekBar. } mClearLogCheckBox = v.findViewById(R.id.clearlogconnect); - mClearLogCheckBox.setChecked(PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean(Constants.CLEARLOG, true)); + mClearLogCheckBox.setChecked(PreferenceHelper.getClearLog()); mClearLogCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> - Preferences.getDefaultSharedPreferences(getActivity()).edit().putBoolean(Constants.CLEARLOG, isChecked).apply()); + PreferenceHelper.setClearLog(isChecked)); mSpeedView = v.findViewById(R.id.speed); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java index ae25c61c..3dbdbe64 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java @@ -134,22 +134,22 @@ public class MainActivityErrorDialog extends DialogFragment { stopVoidVpnIntent.setAction(EIP_ACTION_STOP_BLOCKING_VPN); getContext().startService(stopVoidVpnIntent); }); - if (getPreferredCity(applicationContext) != null) { + if (getPreferredCity() != null) { builder.setPositiveButton(R.string.warning_option_try_best, (dialog, which) -> { new Thread(() -> { - setPreferredCity(applicationContext, null); + setPreferredCity(null); EipCommand.startVPN(applicationContext, false); }).start(); }); } else if (provider.supportsPluggableTransports()) { - if (getUseBridges(applicationContext)) { + if (getUseBridges()) { builder.setPositiveButton(warning_option_try_ovpn, ((dialog, which) -> { - useBridges(applicationContext, false); + useBridges(false); EipCommand.startVPN(applicationContext, false); })); } else { builder.setPositiveButton(warning_option_try_pt, ((dialog, which) -> { - useBridges(applicationContext, true); + useBridges(true); EipCommand.startVPN(applicationContext, false); })); } diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java index f51fd342..9a8c9d00 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java @@ -17,7 +17,6 @@ package se.leap.bitmaskclient.base.fragments; -import static android.content.Context.MODE_PRIVATE; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static se.leap.bitmaskclient.base.models.Constants.DONATION_URL; @@ -31,6 +30,7 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSaveBattery; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.saveBattery; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; @@ -38,8 +38,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -99,8 +97,6 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen private volatile boolean wasPaused; private volatile boolean shouldCloseOnResume; - private SharedPreferences preferences; - private final static String KEY_SHOW_SAVE_BATTERY_ALERT = "KEY_SHOW_SAVE_BATTERY_ALERT"; private volatile boolean showSaveBattery = false; AlertDialog alertDialog; @@ -108,10 +104,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Reads in the flag indicating whether or not the user has demonstrated awareness of the - // drawer. See PREF_USER_LEARNED_DRAWER for details. - preferences = PreferenceHelper.getSharedPreferences(getContext()); - preferences.registerOnSharedPreferenceChangeListener(this); + PreferenceHelper.registerOnSharedPreferenceChangeListener(this); } @Override @@ -260,7 +253,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen private void initSaveBatteryEntry() { saveBattery = drawerView.findViewById(R.id.battery_switch); saveBattery.showSubtitle(false); - saveBattery.setChecked(getSaveBattery(getContext())); + saveBattery.setChecked(getSaveBattery()); saveBattery.setOnCheckedChangeListener(((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; @@ -268,7 +261,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen if (isChecked) { showSaveBatteryAlert(); } else { - saveBattery(getContext(), false); + saveBattery(false); } })); boolean enableEntry = !TetheringObservable.getInstance().getTetheringState().isVpnTetheringRunning(); @@ -288,7 +281,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen return; } manualGatewaySelection = drawerView.findViewById(R.id.manualGatewaySelection); - String preferredGateway = getPreferredCity(getContext()); + String preferredGateway = getPreferredCity(); String subtitle = preferredGateway != null ? preferredGateway : getString(R.string.gateway_selection_recommended_location); manualGatewaySelection.setSubtitle(subtitle); boolean show = ProviderObservable.getInstance().getCurrentProvider().hasGatewaysInDifferentLocations(); @@ -388,7 +381,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen .setTitle(activity.getString(R.string.save_battery)) .setMessage(activity.getString(R.string.save_battery_message)) .setPositiveButton((android.R.string.yes), (dialog, which) -> { - saveBattery(getContext(), true); + saveBattery(true); }) .setNegativeButton(activity.getString(android.R.string.no), (dialog, which) -> saveBattery.setCheckedQuietly(false)) .setOnDismissListener(dialog -> showSaveBattery = false) @@ -417,7 +410,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen @Override public void onDestroy() { super.onDestroy(); - preferences.unregisterOnSharedPreferenceChangeListener(this); + PreferenceHelper.unregisterOnSharedPreferenceChangeListener(this); } public void refresh() { diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java index 2c0fdd69..948d764f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java @@ -48,23 +48,23 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment { cancelButton = binding.buttonCancel; kcpSwitch = binding.kcpSwitch; - ipField.setText(PreferenceHelper.getObfuscationPinningIP(getContext())); - portField.setText(PreferenceHelper.getObfuscationPinningPort(getContext())); - certificateField.setText(PreferenceHelper.getObfuscationPinningCert(getContext())); - kcpSwitch.setChecked(PreferenceHelper.getObfuscationPinningKCP(getContext())); + ipField.setText(PreferenceHelper.getObfuscationPinningIP()); + portField.setText(PreferenceHelper.getObfuscationPinningPort()); + certificateField.setText(PreferenceHelper.getObfuscationPinningCert()); + kcpSwitch.setChecked(PreferenceHelper.getObfuscationPinningKCP()); GatewaysManager gatewaysManager = new GatewaysManager(getContext()); saveButton.setOnClickListener(v -> { String ip = TextUtils.isEmpty(ipField.getText()) ? null : ipField.getText().toString(); - PreferenceHelper.setObfuscationPinningIP(v.getContext(), ip); + PreferenceHelper.setObfuscationPinningIP(ip); String port = TextUtils.isEmpty(portField.getText()) ? null : portField.getText().toString(); - PreferenceHelper.setObfuscationPinningPort(v.getContext(), port); + PreferenceHelper.setObfuscationPinningPort(port); String cert = TextUtils.isEmpty(certificateField.getText()) ? null : certificateField.getText().toString(); - PreferenceHelper.setObfuscationPinningCert(v.getContext(), cert); - PreferenceHelper.setObfuscationPinningKCP(v.getContext(), kcpSwitch.isChecked()); - PreferenceHelper.setUseObfuscationPinning(v.getContext(), ip != null && port != null && cert != null); - PreferenceHelper.setObfuscationPinningGatewayLocation(v.getContext(), gatewaysManager.getLocationNameForIP(ip, v.getContext())); + PreferenceHelper.setObfuscationPinningCert(cert); + PreferenceHelper.setObfuscationPinningKCP(kcpSwitch.isChecked()); + PreferenceHelper.setUseObfuscationPinning(ip != null && port != null && cert != null); + PreferenceHelper.setObfuscationPinningGatewayLocation(gatewaysManager.getLocationNameForIP(ip, v.getContext())); dismiss(); }); @@ -78,8 +78,7 @@ public class ObfuscationProxyDialog extends AppCompatDialogFragment { cancelButton.setOnClickListener(v -> { boolean allowPinning = !TextUtils.isEmpty(ipField.getText()) && !TextUtils.isEmpty(portField.getText()) && !TextUtils.isEmpty(certificateField.getText()); - PreferenceHelper.setUseObfuscationPinning( - v.getContext(), allowPinning); + PreferenceHelper.setUseObfuscationPinning(allowPinning); dismiss(); }); 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 f36b17ad..c8c994a5 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 @@ -11,6 +11,7 @@ import static se.leap.bitmaskclient.base.models.Constants.USE_OBFUSCATION_PINNIN import static se.leap.bitmaskclient.base.utils.ConfigHelper.ObfsVpnHelper.useObfsVpn; import static se.leap.bitmaskclient.base.utils.ConfigHelper.isCalyxOSWithTetheringSupport; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.allowExperimentalTransports; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getExcludedApps; 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; @@ -60,8 +61,6 @@ import se.leap.bitmaskclient.firewall.FirewallManager; public class SettingsFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener { private FirewallManager firewallManager; - private SharedPreferences preferences; - private IconTextEntry tethering; private IconSwitchEntry firewall; IconSwitchEntry useUdpEntry; @@ -69,8 +68,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - preferences = PreferenceHelper.getSharedPreferences(getContext()); - preferences.registerOnSharedPreferenceChangeListener(this); + PreferenceHelper.registerOnSharedPreferenceChangeListener(this); firewallManager = new FirewallManager(getContext().getApplicationContext(), false); } @@ -94,20 +92,20 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh @Override public void onDestroy() { + PreferenceHelper.unregisterOnSharedPreferenceChangeListener(this); super.onDestroy(); - preferences.unregisterOnSharedPreferenceChangeListener(this); } private void initUseBridgesEntry(View rootView) { IconSwitchEntry useBridges = rootView.findViewById(R.id.bridges_switch); if (ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports()) { useBridges.setVisibility(VISIBLE); - useBridges.setChecked(getUseBridges(getContext())); + useBridges.setChecked(getUseBridges()); useBridges.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } - useBridges(getContext(), isChecked); + useBridges(isChecked); if (VpnStatus.isVPNActive()) { EipCommand.startVPN(getContext(), false); Toast.makeText(getContext(), R.string.reconnecting, Toast.LENGTH_LONG).show(); @@ -116,7 +114,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh //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(getContext()) && useUdpEntry.isEnabled(); + boolean useUDP = getPreferUDP() && useUdpEntry.isEnabled(); useBridges.setEnabled(!useUDP); useBridges.setSubtitle(getString(useUDP ? R.string.disabled_while_udp_on : R.string.nav_drawer_subtitle_obfuscated_connection)); } else { @@ -127,12 +125,12 @@ 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.setChecked(hasSnowflakePrefs() && getUseSnowflake()); useSnowflake.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } - useSnowflake(getContext(), isChecked); + useSnowflake(isChecked); }); } @@ -141,7 +139,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh IconTextEntry alwaysOnVpn = rootView.findViewById(R.id.always_on_vpn); alwaysOnVpn.setVisibility(VISIBLE); alwaysOnVpn.setOnClickListener((buttonView) -> { - if (getShowAlwaysOnDialog(getContext())) { + if (getShowAlwaysOnDialog()) { showAlwaysOnDialog(); } else { Intent intent = new Intent("android.net.vpn.SETTINGS"); @@ -155,18 +153,18 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh private void initPreferUDPEntry(View rootView) { useUdpEntry = rootView.findViewById(R.id.prefer_udp); useUdpEntry.setVisibility(VISIBLE); - useUdpEntry.setChecked(getPreferUDP(getContext())); + useUdpEntry.setChecked(getPreferUDP()); useUdpEntry.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } - preferUDP(getContext(), isChecked); + preferUDP(isChecked); if (VpnStatus.isVPNActive()) { EipCommand.startVPN(getContext(), false); Toast.makeText(getContext(), R.string.reconnecting, Toast.LENGTH_LONG).show(); } }); - boolean bridgesEnabled = getUseBridges(getContext()); + boolean bridgesEnabled = getUseBridges(); useUdpEntry.setEnabled(!bridgesEnabled); useUdpEntry.setSubtitle(getString(bridgesEnabled ? R.string.disabled_while_bridges_on : R.string.prefer_udp_subtitle)); } @@ -174,7 +172,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh private void initExcludeAppsEntry(View rootView) { IconTextEntry excludeApps = rootView.findViewById(R.id.exclude_apps); excludeApps.setVisibility(VISIBLE); - Set apps = PreferenceHelper.getExcludedApps(this.getContext()); + Set apps = getExcludedApps(); if (apps != null) { updateExcludeAppsSubtitle(excludeApps, apps.size()); } @@ -196,12 +194,12 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh private void initFirewallEntry(View rootView) { firewall = rootView.findViewById(R.id.enableIPv6Firewall); - firewall.setChecked(PreferenceHelper.useIpv6Firewall(getContext())); + firewall.setChecked(PreferenceHelper.useIpv6Firewall()); firewall.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } - PreferenceHelper.setUseIPv6Firewall(getContext(), isChecked); + PreferenceHelper.setUseIPv6Firewall(isChecked); if (VpnStatus.isVPNActive()) { if (isChecked) { firewallManager.startIPv6Firewall(); @@ -235,7 +233,7 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh if (context == null) { return; } - String pinnedGateway = PreferenceHelper.getPinnedGateway(rootView.getContext()); + String pinnedGateway = PreferenceHelper.getPinnedGateway(); gatewayPinning.setSubtitle(pinnedGateway != null ? pinnedGateway : "Connect to a specific Gateway for debugging purposes"); gatewayPinning.setOnClickListener(v -> { @@ -249,10 +247,10 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh if (gatewayPinningEditText.getText() != null) { String editTextInput = gatewayPinningEditText.getText().toString(); if (!TextUtils.isEmpty(editTextInput)) { - PreferenceHelper.setPreferredCity(context, null); - PreferenceHelper.pinGateway(context, editTextInput); + PreferenceHelper.setPreferredCity(null); + PreferenceHelper.pinGateway(editTextInput); } else { - PreferenceHelper.pinGateway(context, null); + PreferenceHelper.pinGateway(null); } } }) @@ -268,16 +266,16 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh return; } obfuscationPinning.setVisibility(VISIBLE); - boolean useBridges = getUseBridges(getContext()); + boolean useBridges = getUseBridges(); obfuscationPinning.setEnabled(useBridges); obfuscationPinning.setSubtitle(useBridges ? "Connect to a specific obfuscation proxy for debugging purposes" : "Enable Bridges to use this option"); - obfuscationPinning.setChecked(useObfuscationPinning(getContext())); + obfuscationPinning.setChecked(useObfuscationPinning()); obfuscationPinning.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } if (!isChecked) { - setUseObfuscationPinning(getContext(), false); + setUseObfuscationPinning(false); } else { showObfuscationPinningDialog(); } @@ -306,12 +304,12 @@ public class SettingsFragment extends Fragment implements SharedPreferences.OnSh IconSwitchEntry experimentalTransports = rootView.findViewById(R.id.experimental_transports); if (useObfsVpn() && ProviderObservable.getInstance().getCurrentProvider().supportsExperimentalPluggableTransports()) { experimentalTransports.setVisibility(VISIBLE); - experimentalTransports.setChecked(allowExperimentalTransports(this.getContext())); + experimentalTransports.setChecked(allowExperimentalTransports()); experimentalTransports.setOnCheckedChangeListener((buttonView, isChecked) -> { if (!buttonView.isPressed()) { return; } - setAllowExperimentalTransports(getContext(), isChecked); + setAllowExperimentalTransports(isChecked); }); } else { experimentalTransports.setVisibility(GONE); diff --git a/app/src/main/java/se/leap/bitmaskclient/base/fragments/TetheringDialog.java b/app/src/main/java/se/leap/bitmaskclient/base/fragments/TetheringDialog.java index e747d5b4..eb9d149f 100644 --- a/app/src/main/java/se/leap/bitmaskclient/base/fragments/TetheringDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/base/fragments/TetheringDialog.java @@ -155,9 +155,9 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer builder.setView(view) .setPositiveButton(android.R.string.ok, (dialog, id) -> { - PreferenceHelper.allowWifiTethering(getContext(), dataset[0].checked); - PreferenceHelper.allowUsbTethering(getContext(), dataset[1].checked); - PreferenceHelper.allowBluetoothTethering(getContext(), dataset[2].checked); + PreferenceHelper.allowWifiTethering(dataset[0].checked); + PreferenceHelper.allowUsbTethering(dataset[1].checked); + PreferenceHelper.allowBluetoothTethering(dataset[2].checked); TetheringObservable.allowVpnWifiTethering(dataset[0].checked); TetheringObservable.allowVpnUsbTethering(dataset[1].checked); TetheringObservable.allowVpnBluetoothTethering(dataset[2].checked); @@ -247,15 +247,15 @@ public class TetheringDialog extends AppCompatDialogFragment implements Observer dataset = new DialogListAdapter.ViewModel[] { new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_wifi), getContext().getString(R.string.tethering_wifi), - PreferenceHelper.isWifiTetheringAllowed(getContext()), + PreferenceHelper.isWifiTetheringAllowed(), TetheringObservable.getInstance().isWifiTetheringEnabled()), new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_usb), getContext().getString(R.string.tethering_usb), - PreferenceHelper.isUsbTetheringAllowed(getContext()), + PreferenceHelper.isUsbTetheringAllowed(), TetheringObservable.getInstance().isUsbTetheringEnabled()), new DialogListAdapter.ViewModel(getContext().getResources().getDrawable(R.drawable.ic_bluetooth), getContext().getString(R.string.tethering_bluetooth), - PreferenceHelper.isBluetoothTetheringAllowed(getContext()), + PreferenceHelper.isBluetoothTetheringAllowed(), TetheringObservable.getInstance().isUsbTetheringEnabled()) }; } 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 12196aee..b35a04cd 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 @@ -6,9 +6,14 @@ import static se.leap.bitmaskclient.base.models.Constants.ALLOW_TETHERING_BLUETO import static se.leap.bitmaskclient.base.models.Constants.ALLOW_TETHERING_USB; import static se.leap.bitmaskclient.base.models.Constants.ALLOW_TETHERING_WIFI; import static se.leap.bitmaskclient.base.models.Constants.ALWAYS_ON_SHOW_DIALOG; +import static se.leap.bitmaskclient.base.models.Constants.CLEARLOG; import static se.leap.bitmaskclient.base.models.Constants.DEFAULT_SHARED_PREFS_BATTERY_SAVER; +import static se.leap.bitmaskclient.base.models.Constants.EIP_IS_ALWAYS_ON; +import static se.leap.bitmaskclient.base.models.Constants.EIP_RESTART_ON_BOOT; import static se.leap.bitmaskclient.base.models.Constants.EXCLUDED_APPS; +import static se.leap.bitmaskclient.base.models.Constants.FIRST_TIME_USER_DATE; import static se.leap.bitmaskclient.base.models.Constants.GATEWAY_PINNING; +import static se.leap.bitmaskclient.base.models.Constants.LAST_DONATION_REMINDER_DATE; 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.OBFUSCATION_PINNING_CERT; @@ -16,6 +21,7 @@ import static se.leap.bitmaskclient.base.models.Constants.OBFUSCATION_PINNING_IP import static se.leap.bitmaskclient.base.models.Constants.OBFUSCATION_PINNING_KCP; import static se.leap.bitmaskclient.base.models.Constants.OBFUSCATION_PINNING_LOCATION; import static se.leap.bitmaskclient.base.models.Constants.OBFUSCATION_PINNING_PORT; +import static se.leap.bitmaskclient.base.models.Constants.PREFERENCES_APP_VERSION; 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; @@ -40,7 +46,7 @@ import android.content.SharedPreferences; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import androidx.annotation.WorkerThread; import androidx.security.crypto.EncryptedSharedPreferences; import androidx.security.crypto.MasterKey; @@ -57,6 +63,7 @@ import java.util.Map; import java.util.Set; import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.NativeUtils; import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -69,367 +76,493 @@ public class PreferenceHelper { private static final String TAG = PreferenceHelper.class.getSimpleName(); - public static SharedPreferences getSharedPreferences(Context context) { + private static SharedPreferences preferences; + private static final Object LOCK = new Object(); + + private SharedPreferences initSharedPreferences(Context appContext) { + Log.d(TAG, "getSharedPreferences is null"); + SharedPreferences preferences = null; try { - MasterKey masterKey = new MasterKey.Builder(context) + MasterKey masterKey = new MasterKey.Builder(appContext) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build(); - return EncryptedSharedPreferences.create( - context, + preferences = EncryptedSharedPreferences.create( + appContext, SHARED_ENCRYPTED_PREFERENCES, masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM); } catch (GeneralSecurityException | IOException e) { e.printStackTrace(); + preferences = appContext.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + } + + Log.d(TAG, "getSharedPreferences finished"); + return preferences; + } + + public PreferenceHelper(SharedPreferences preferences) { + if (!NativeUtils.isUnitTest()) { + throw new IllegalStateException("PreferenceHelper injected with shared preference outside of an unit test"); + } + synchronized (LOCK) { + PreferenceHelper.preferences = preferences; + } + } + public PreferenceHelper(Context context) { + synchronized (LOCK) { + preferences = initSharedPreferences(context.getApplicationContext()); + } + } + + public static void registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) { + synchronized (LOCK) { + preferences.registerOnSharedPreferenceChangeListener(listener); } - return context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); } - public static Provider getSavedProviderFromSharedPreferences(@NonNull SharedPreferences preferences) { + public static void unregisterOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) { + synchronized (LOCK) { + preferences.unregisterOnSharedPreferenceChangeListener(listener); + } + } + + public static Provider getSavedProviderFromSharedPreferences() { Provider provider = new Provider(); - try { - provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); - provider.setProviderIp(preferences.getString(Provider.PROVIDER_IP, "")); - provider.setProviderApiIp(preferences.getString(Provider.PROVIDER_API_IP, "")); - provider.setGeoipUrl(preferences.getString(Provider.GEOIP_URL, "")); - provider.setMotdUrl(preferences.getString(Provider.MOTD_URL, "")); - provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); - provider.setCaCert(preferences.getString(Provider.CA_CERT, "")); - provider.setVpnCertificate(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); - provider.setPrivateKey(preferences.getString(PROVIDER_PRIVATE_KEY, "")); - provider.setEipServiceJson(new JSONObject(preferences.getString(PROVIDER_EIP_DEFINITION, ""))); - provider.setMotdJson(new JSONObject(preferences.getString(PROVIDER_MOTD, ""))); - provider.setLastMotdSeen(preferences.getLong(PROVIDER_MOTD_LAST_SEEN, 0L)); - provider.setLastMotdUpdate(preferences.getLong(PROVIDER_MOTD_LAST_UPDATED, 0L)); - provider.setMotdLastSeenHashes(preferences.getStringSet(PROVIDER_MOTD_HASHES, new HashSet<>())); - } catch (MalformedURLException | JSONException e) { - e.printStackTrace(); + synchronized (LOCK) { + try { + provider.setMainUrl(new URL(preferences.getString(Provider.MAIN_URL, ""))); + provider.setProviderIp(preferences.getString(Provider.PROVIDER_IP, "")); + provider.setProviderApiIp(preferences.getString(Provider.PROVIDER_API_IP, "")); + provider.setGeoipUrl(preferences.getString(Provider.GEOIP_URL, "")); + provider.setMotdUrl(preferences.getString(Provider.MOTD_URL, "")); + provider.define(new JSONObject(preferences.getString(Provider.KEY, ""))); + provider.setCaCert(preferences.getString(Provider.CA_CERT, "")); + provider.setVpnCertificate(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); + provider.setPrivateKey(preferences.getString(PROVIDER_PRIVATE_KEY, "")); + provider.setEipServiceJson(new JSONObject(preferences.getString(PROVIDER_EIP_DEFINITION, ""))); + provider.setMotdJson(new JSONObject(preferences.getString(PROVIDER_MOTD, ""))); + provider.setLastMotdSeen(preferences.getLong(PROVIDER_MOTD_LAST_SEEN, 0L)); + provider.setLastMotdUpdate(preferences.getLong(PROVIDER_MOTD_LAST_UPDATED, 0L)); + provider.setMotdLastSeenHashes(preferences.getStringSet(PROVIDER_MOTD_HASHES, new HashSet<>())); + } catch (MalformedURLException | JSONException e) { + e.printStackTrace(); + } } return provider; } - public static String getFromPersistedProvider(String toFetch, String providerDomain, SharedPreferences preferences) { - return preferences.getString(toFetch + "." + providerDomain, ""); + public static String getFromPersistedProvider(String toFetch, String providerDomain) { + synchronized (LOCK) { + return preferences.getString(toFetch + "." + providerDomain, ""); + } } - public static long getLongFromPersistedProvider(String toFetch, String providerDomain, SharedPreferences preferences) { - return preferences.getLong(toFetch + "." + providerDomain, 0L); + public static long getLongFromPersistedProvider(String toFetch, String providerDomain) { + synchronized (LOCK) { + return preferences.getLong(toFetch + "." + providerDomain, 0L); + } } - public static Set getStringSetFromPersistedProvider(String toFetch, String providerDomain, SharedPreferences preferences) { - return preferences.getStringSet(toFetch + "." + providerDomain, new HashSet<>()); + public static Set getStringSetFromPersistedProvider(String toFetch, String providerDomain) { + synchronized (LOCK) { + return preferences.getStringSet(toFetch + "." + providerDomain, new HashSet<>()); + } } - public static void persistProviderAsync(Context context, Provider provider) { - SharedPreferences preferences = getSharedPreferences(context); - storeProviderInPreferences(preferences, provider, true); + public static void persistProviderAsync(Provider provider) { + synchronized (LOCK) { + storeProviderInPreferences(provider, true); + } } - public static void storeProviderInPreferences(SharedPreferences preferences, Provider provider) { - storeProviderInPreferences(preferences, provider, false); + public static void storeProviderInPreferences(Provider provider) { + synchronized (LOCK) { + storeProviderInPreferences(provider, false); + } } // TODO: replace commit with apply after refactoring EIP //FIXME: don't save private keys in shared preferences! use the keystore - public static void storeProviderInPreferences(SharedPreferences preferences, Provider provider, boolean async) { - SharedPreferences.Editor editor = preferences.edit(); - editor.putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.PROVIDER_IP, provider.getProviderIp()). - putString(Provider.GEOIP_URL, provider.getGeoipUrl().toString()). - putString(Provider.MOTD_URL, provider.getMotdUrl().toString()). - putString(Provider.PROVIDER_API_IP, provider.getProviderApiIp()). - putString(Provider.MAIN_URL, provider.getMainUrlString()). - putString(Provider.KEY, provider.getDefinitionString()). - putString(Provider.CA_CERT, provider.getCaCert()). - putString(PROVIDER_EIP_DEFINITION, provider.getEipServiceJsonString()). - putString(PROVIDER_PRIVATE_KEY, provider.getPrivateKey()). - putString(PROVIDER_VPN_CERTIFICATE, provider.getVpnCertificate()). - putString(PROVIDER_MOTD, provider.getMotdJsonString()). - putStringSet(PROVIDER_MOTD_HASHES, provider.getMotdLastSeenHashes()). - putLong(PROVIDER_MOTD_LAST_SEEN, provider.getLastMotdSeen()). - putLong(PROVIDER_MOTD_LAST_UPDATED, provider.getLastMotdUpdate()); - if (async) { - editor.apply(); - } else { - editor.commit(); - } - - String providerDomain = provider.getDomain(); - preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). - putString(Provider.PROVIDER_IP + "." + providerDomain, provider.getProviderIp()). - putString(Provider.PROVIDER_API_IP + "." + providerDomain, provider.getProviderApiIp()). - putString(Provider.MAIN_URL + "." + providerDomain, provider.getMainUrlString()). - putString(Provider.GEOIP_URL + "." + providerDomain, provider.getGeoipUrl().toString()). - putString(Provider.MOTD_URL + "." + providerDomain, provider.getMotdUrl().toString()). - putString(Provider.KEY + "." + providerDomain, provider.getDefinitionString()). - putString(Provider.CA_CERT + "." + providerDomain, provider.getCaCert()). - putString(PROVIDER_EIP_DEFINITION + "." + providerDomain, provider.getEipServiceJsonString()). - putString(PROVIDER_MOTD + "." + providerDomain, provider.getMotdJsonString()). - putStringSet(PROVIDER_MOTD_HASHES + "." + providerDomain, provider.getMotdLastSeenHashes()). - putLong(PROVIDER_MOTD_LAST_SEEN + "." + providerDomain, provider.getLastMotdSeen()). - putLong(PROVIDER_MOTD_LAST_UPDATED + "." + providerDomain, provider.getLastMotdUpdate()). - apply(); + public static void storeProviderInPreferences(Provider provider, boolean async) { + synchronized (LOCK) { + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean(PROVIDER_CONFIGURED, true). + putString(Provider.PROVIDER_IP, provider.getProviderIp()). + putString(Provider.GEOIP_URL, provider.getGeoipUrl().toString()). + putString(Provider.MOTD_URL, provider.getMotdUrl().toString()). + putString(Provider.PROVIDER_API_IP, provider.getProviderApiIp()). + putString(Provider.MAIN_URL, provider.getMainUrlString()). + putString(Provider.KEY, provider.getDefinitionString()). + putString(Provider.CA_CERT, provider.getCaCert()). + putString(PROVIDER_EIP_DEFINITION, provider.getEipServiceJsonString()). + putString(PROVIDER_PRIVATE_KEY, provider.getPrivateKey()). + putString(PROVIDER_VPN_CERTIFICATE, provider.getVpnCertificate()). + putString(PROVIDER_MOTD, provider.getMotdJsonString()). + putStringSet(PROVIDER_MOTD_HASHES, provider.getMotdLastSeenHashes()). + putLong(PROVIDER_MOTD_LAST_SEEN, provider.getLastMotdSeen()). + putLong(PROVIDER_MOTD_LAST_UPDATED, provider.getLastMotdUpdate()); + if (async) { + editor.apply(); + } else { + editor.commit(); + } + + String providerDomain = provider.getDomain(); + preferences.edit().putBoolean(PROVIDER_CONFIGURED, true). + putString(Provider.PROVIDER_IP + "." + providerDomain, provider.getProviderIp()). + putString(Provider.PROVIDER_API_IP + "." + providerDomain, provider.getProviderApiIp()). + putString(Provider.MAIN_URL + "." + providerDomain, provider.getMainUrlString()). + putString(Provider.GEOIP_URL + "." + providerDomain, provider.getGeoipUrl().toString()). + putString(Provider.MOTD_URL + "." + providerDomain, provider.getMotdUrl().toString()). + putString(Provider.KEY + "." + providerDomain, provider.getDefinitionString()). + putString(Provider.CA_CERT + "." + providerDomain, provider.getCaCert()). + putString(PROVIDER_EIP_DEFINITION + "." + providerDomain, provider.getEipServiceJsonString()). + putString(PROVIDER_MOTD + "." + providerDomain, provider.getMotdJsonString()). + putStringSet(PROVIDER_MOTD_HASHES + "." + providerDomain, provider.getMotdLastSeenHashes()). + putLong(PROVIDER_MOTD_LAST_SEEN + "." + providerDomain, provider.getLastMotdSeen()). + putLong(PROVIDER_MOTD_LAST_UPDATED + "." + providerDomain, provider.getLastMotdUpdate()). + apply(); + } + } + + public static void putProviderString(String providerDomain, String key, String value) { + synchronized (LOCK) { + putString(key+"."+providerDomain, value); + } } /** * Sets the profile that is connected (to connect if the service restarts) */ - public static void setLastUsedVpnProfile(Context context, VpnProfile connectedProfile) { - SharedPreferences prefs = getSharedPreferences(context); - SharedPreferences.Editor prefsedit = prefs.edit(); - prefsedit.putString(LAST_USED_PROFILE, connectedProfile.toJson()); - prefsedit.apply(); + public static void setLastUsedVpnProfile(VpnProfile connectedProfile) { + synchronized (LOCK) { + preferences.edit().putString(LAST_USED_PROFILE, connectedProfile.toJson()).apply(); + } } /** * Returns the profile that was last connected (to connect if the service restarts) */ - public static VpnProfile getLastConnectedVpnProfile(Context context) { - SharedPreferences preferences = getSharedPreferences(context); - String lastConnectedProfileJson = preferences.getString(LAST_USED_PROFILE, null); + public static VpnProfile getLastConnectedVpnProfile() { + String lastConnectedProfileJson = null; + synchronized (LOCK) { + lastConnectedProfileJson = preferences.getString(LAST_USED_PROFILE, null); + } return VpnProfile.fromJson(lastConnectedProfileJson); } - public static void deleteProviderDetailsFromPreferences(@NonNull SharedPreferences preferences, String providerDomain) { - preferences.edit(). - remove(Provider.KEY + "." + providerDomain). - remove(Provider.CA_CERT + "." + providerDomain). - remove(Provider.PROVIDER_IP + "." + providerDomain). - remove(Provider.PROVIDER_API_IP + "." + providerDomain). - remove(Provider.MAIN_URL + "." + providerDomain). - remove(Provider.GEOIP_URL + "." + providerDomain). - remove(Provider.MOTD_URL + "." + providerDomain). - remove(PROVIDER_EIP_DEFINITION + "." + providerDomain). - remove(PROVIDER_PRIVATE_KEY + "." + providerDomain). - remove(PROVIDER_VPN_CERTIFICATE + "." + providerDomain). - remove(PROVIDER_MOTD + "." + providerDomain). - remove(PROVIDER_MOTD_HASHES + "." + providerDomain). - remove(PROVIDER_MOTD_LAST_SEEN + "." + providerDomain). - remove(PROVIDER_MOTD_LAST_UPDATED + "." + providerDomain). - apply(); - } - - public static void deleteCurrentProviderDetailsFromPreferences(@NonNull SharedPreferences preferences) { - preferences.edit(). - remove(Provider.KEY). - remove(Provider.CA_CERT). - remove(Provider.PROVIDER_IP). - remove(Provider.PROVIDER_API_IP). - remove(Provider.MAIN_URL). - remove(Provider.GEOIP_URL). - remove(Provider.MOTD_URL). - remove(PROVIDER_EIP_DEFINITION). - remove(PROVIDER_PRIVATE_KEY). - remove(PROVIDER_VPN_CERTIFICATE). - remove(PROVIDER_MOTD). - remove(PROVIDER_MOTD_HASHES). - remove(PROVIDER_MOTD_LAST_SEEN). - remove(PROVIDER_MOTD_LAST_UPDATED). - apply(); + public static void deleteProviderDetailsFromPreferences(String providerDomain) { + synchronized (LOCK) { + preferences.edit(). + remove(Provider.KEY + "." + providerDomain). + remove(Provider.CA_CERT + "." + providerDomain). + remove(Provider.PROVIDER_IP + "." + providerDomain). + remove(Provider.PROVIDER_API_IP + "." + providerDomain). + remove(Provider.MAIN_URL + "." + providerDomain). + remove(Provider.GEOIP_URL + "." + providerDomain). + remove(Provider.MOTD_URL + "." + providerDomain). + remove(PROVIDER_EIP_DEFINITION + "." + providerDomain). + remove(PROVIDER_PRIVATE_KEY + "." + providerDomain). + remove(PROVIDER_VPN_CERTIFICATE + "." + providerDomain). + remove(PROVIDER_MOTD + "." + providerDomain). + remove(PROVIDER_MOTD_HASHES + "." + providerDomain). + remove(PROVIDER_MOTD_LAST_SEEN + "." + providerDomain). + remove(PROVIDER_MOTD_LAST_UPDATED + "." + providerDomain). + apply(); + } + } + + public static void deleteCurrentProviderDetailsFromPreferences() { + synchronized (LOCK) { + preferences.edit(). + remove(Provider.KEY). + remove(Provider.CA_CERT). + remove(Provider.PROVIDER_IP). + remove(Provider.PROVIDER_API_IP). + remove(Provider.MAIN_URL). + remove(Provider.GEOIP_URL). + remove(Provider.MOTD_URL). + remove(PROVIDER_EIP_DEFINITION). + remove(PROVIDER_PRIVATE_KEY). + remove(PROVIDER_VPN_CERTIFICATE). + remove(PROVIDER_MOTD). + remove(PROVIDER_MOTD_HASHES). + remove(PROVIDER_MOTD_LAST_SEEN). + remove(PROVIDER_MOTD_LAST_UPDATED). + apply(); + } } // used in fatweb flavor @SuppressWarnings("unused") - public static void setLastAppUpdateCheck(Context context) { - putLong(context, LAST_UPDATE_CHECK, System.currentTimeMillis()); + public static void setLastAppUpdateCheck() { + putLong(LAST_UPDATE_CHECK, System.currentTimeMillis()); + } + + public static long getLastAppUpdateCheck() { + return getLong(LAST_UPDATE_CHECK, 0); + } + + public static void restartOnUpdate(boolean isEnabled) { + putBoolean(RESTART_ON_UPDATE, isEnabled); + } + + public static boolean getRestartOnUpdate() { + return getBoolean(RESTART_ON_UPDATE, false); + } + + public static boolean getRestartOnBoot() { + return getBoolean(EIP_RESTART_ON_BOOT, false); + } + + public static void restartOnBoot(boolean isEnabled) { + putBoolean(EIP_RESTART_ON_BOOT, isEnabled); } - public static long getLastAppUpdateCheck(Context context) { - return getLong(context, LAST_UPDATE_CHECK, 0); + public static void restartOnBootSync(boolean isEnabled) { + putBooleanSync(EIP_RESTART_ON_BOOT, isEnabled); } - public static void restartOnUpdate(Context context, boolean isEnabled) { - putBoolean(context, RESTART_ON_UPDATE, isEnabled); + public static void isAlwaysOnSync(boolean isEnabled) { + putBooleanSync(EIP_IS_ALWAYS_ON, isEnabled); } - public static boolean getRestartOnUpdate(Context context) { - return getBoolean(context, RESTART_ON_UPDATE, false); + public static boolean getIsAlwaysOn() { + return getBoolean(EIP_IS_ALWAYS_ON, false); } - public static boolean getPreferUDP(Context context) { - return getBoolean(context, PREFER_UDP, BuildConfig.prefer_udp); + public static void lastDonationReminderDate(String dateString) { + putString(LAST_DONATION_REMINDER_DATE, dateString); } - public static void preferUDP(Context context, boolean prefer) { - putBoolean(context, PREFER_UDP, prefer); + public static String getLastDonationReminderDate() { + return getString(LAST_DONATION_REMINDER_DATE, null); } - public static String getPinnedGateway(Context context) { - return getString(context, GATEWAY_PINNING, null); + public static void firstTimeUserDate(String dateString) { + putString(FIRST_TIME_USER_DATE, dateString); } - public static void pinGateway(Context context, String value) { - putString(context, GATEWAY_PINNING, value); + public static String getFirstTimeUserDate() { + return getString(FIRST_TIME_USER_DATE, null); } - public static boolean getUseBridges(SharedPreferences preferences) { - return preferences.getBoolean(USE_BRIDGES, false); + public static void setProviderVPNCertificate(String certificate) { + putString(PROVIDER_VPN_CERTIFICATE, certificate); + } + public static String getProviderVPNCertificate() { + return getString(PROVIDER_VPN_CERTIFICATE, ""); + } + + public static int getAppVersion() { + return getInt(PREFERENCES_APP_VERSION, -1); + } + + public static void setAppVersion(int version) { + putInt(PREFERENCES_APP_VERSION, version); + } + + public static boolean getClearLog() { + return getBoolean(CLEARLOG, true); + } + + public static void setClearLog(boolean clearLog) { + putBoolean(CLEARLOG, clearLog); } - public static boolean getUseBridges(Context context) { - return getBoolean(context, USE_BRIDGES, false); + public static boolean getPreferUDP() { + return getBoolean(PREFER_UDP, BuildConfig.prefer_udp); } - public static void useBridges(Context context, boolean isEnabled) { - putBoolean(context, USE_BRIDGES, isEnabled); + public static void preferUDP(boolean prefer) { + putBoolean(PREFER_UDP, prefer); } - public static Boolean getUseSnowflake(SharedPreferences preferences) { - return preferences.getBoolean(USE_SNOWFLAKE, true); + public static String getPinnedGateway() { + return getString(GATEWAY_PINNING, null); } - public static void useSnowflake(Context context, boolean isEnabled) { - putBoolean(context, USE_SNOWFLAKE, isEnabled); + public static void pinGateway(String value) { + putString(GATEWAY_PINNING, value); + } + + public static boolean getUseBridges() { + return getBoolean(USE_BRIDGES, false); + } + + public static void useBridges(boolean isEnabled) { + putBoolean(USE_BRIDGES, isEnabled); + } + + public static void useSnowflake(boolean isEnabled) { + putBoolean(USE_SNOWFLAKE, isEnabled); if (!isEnabled) { TorStatusObservable.setProxyPort(-1); } } - public static boolean hasSnowflakePrefs(SharedPreferences preferences) { - return preferences.contains(USE_SNOWFLAKE); + public static boolean hasSnowflakePrefs() { + return hasKey(USE_SNOWFLAKE); } - public static boolean hasSnowflakePrefs(Context context) { - return hasKey(context, USE_SNOWFLAKE); + public static Boolean getUseSnowflake() { + return getBoolean(USE_SNOWFLAKE, true); } - public static Boolean getUseSnowflake(Context context) { - return getBoolean(context, USE_SNOWFLAKE, true); + public static void saveBattery(boolean isEnabled) { + putBoolean(DEFAULT_SHARED_PREFS_BATTERY_SAVER, isEnabled); } - public static void saveBattery(Context context, boolean isEnabled) { - putBoolean(context, DEFAULT_SHARED_PREFS_BATTERY_SAVER, isEnabled); + public static boolean getSaveBattery() { + return getBoolean(DEFAULT_SHARED_PREFS_BATTERY_SAVER, false); } - public static boolean getSaveBattery(Context context) { - return getBoolean(context, DEFAULT_SHARED_PREFS_BATTERY_SAVER, false); + public static void allowUsbTethering(boolean isEnabled) { + putBoolean(ALLOW_TETHERING_USB, isEnabled); } - public static void allowUsbTethering(Context context, boolean isEnabled) { - putBoolean(context, ALLOW_TETHERING_USB, isEnabled); + public static boolean isUsbTetheringAllowed() { + return getBoolean(ALLOW_TETHERING_USB, false); } - public static boolean isUsbTetheringAllowed(Context context) { - return getBoolean(context, ALLOW_TETHERING_USB, false); + public static void allowWifiTethering(boolean isEnabled) { + putBoolean(ALLOW_TETHERING_WIFI, isEnabled); } - public static void allowWifiTethering(Context context, boolean isEnabled) { - putBoolean(context, ALLOW_TETHERING_WIFI, isEnabled); + public static boolean isWifiTetheringAllowed() { + return getBoolean(ALLOW_TETHERING_WIFI, false); } - public static boolean isWifiTetheringAllowed(Context context) { - return getBoolean(context, ALLOW_TETHERING_WIFI, false); + public static void allowBluetoothTethering(boolean isEnabled) { + putBoolean(ALLOW_TETHERING_BLUETOOTH, isEnabled); } - public static void allowBluetoothTethering(Context context, boolean isEnabled) { - putBoolean(context, ALLOW_TETHERING_BLUETOOTH, isEnabled); + public static boolean isBluetoothTetheringAllowed() { + return getBoolean(ALLOW_TETHERING_BLUETOOTH, false); } - public static boolean isBluetoothTetheringAllowed(Context context) { - return getBoolean(context, ALLOW_TETHERING_BLUETOOTH, false); + public static void setShowExperimentalFeatures(boolean show) { + putBoolean(SHOW_EXPERIMENTAL, show); } - public static void setShowExperimentalFeatures(Context context, boolean show) { - putBoolean(context, SHOW_EXPERIMENTAL, show); + public static boolean showExperimentalFeatures() { + return getBoolean(SHOW_EXPERIMENTAL, false); } - public static boolean showExperimentalFeatures(Context context) { - return getBoolean(context, SHOW_EXPERIMENTAL, false); + public static void setAllowExperimentalTransports(boolean show) { + putBoolean(ALLOW_EXPERIMENTAL_TRANSPORTS, show); } - public static void setAllowExperimentalTransports(Context context, boolean show) { - putBoolean(context, ALLOW_EXPERIMENTAL_TRANSPORTS, show); + public static boolean allowExperimentalTransports() { + return getBoolean(ALLOW_EXPERIMENTAL_TRANSPORTS, false); } - public static boolean allowExperimentalTransports(Context context) { - return getBoolean(context, ALLOW_EXPERIMENTAL_TRANSPORTS, false); + public static void setUseObfuscationPinning(Boolean pinning) { + putBoolean(USE_OBFUSCATION_PINNING, pinning); } - public static void setUseObfuscationPinning(Context context, Boolean pinning) { - putBoolean(context, USE_OBFUSCATION_PINNING, pinning); - } - - public static boolean useObfuscationPinning(Context context) { + public static boolean useObfuscationPinning() { return ConfigHelper.ObfsVpnHelper.useObfsVpn() && - getUseBridges(context) && - getBoolean(context, USE_OBFUSCATION_PINNING, false) && - !TextUtils.isEmpty(getObfuscationPinningIP(context)) && - !TextUtils.isEmpty(getObfuscationPinningCert(context)) && - !TextUtils.isEmpty(getObfuscationPinningPort(context)); + getUseBridges() && + getBoolean(USE_OBFUSCATION_PINNING, false) && + !TextUtils.isEmpty(getObfuscationPinningIP()) && + !TextUtils.isEmpty(getObfuscationPinningCert()) && + !TextUtils.isEmpty(getObfuscationPinningPort()); } - public static void setObfuscationPinningIP(Context context, String ip) { - putString(context, OBFUSCATION_PINNING_IP, ip); + public static void setObfuscationPinningIP(String ip) { + putString(OBFUSCATION_PINNING_IP, ip); } - public static String getObfuscationPinningIP(Context context) { - return getString(context, OBFUSCATION_PINNING_IP, null); + public static String getObfuscationPinningIP() { + return getString(OBFUSCATION_PINNING_IP, null); } - public static void setObfuscationPinningPort(Context context, String port) { - putString(context, OBFUSCATION_PINNING_PORT, port); + public static void setObfuscationPinningPort(String port) { + putString(OBFUSCATION_PINNING_PORT, port); } - public static String getObfuscationPinningPort(Context context) { - return getString(context, OBFUSCATION_PINNING_PORT, null); + public static String getObfuscationPinningPort() { + return getString(OBFUSCATION_PINNING_PORT, null); } - public static void setObfuscationPinningCert(Context context, String cert) { - putString(context, OBFUSCATION_PINNING_CERT, cert); + public static void setObfuscationPinningCert(String cert) { + putString(OBFUSCATION_PINNING_CERT, cert); } - public static String getObfuscationPinningCert(Context context) { - return getString(context, OBFUSCATION_PINNING_CERT, null); + public static String getObfuscationPinningCert() { + return getString(OBFUSCATION_PINNING_CERT, null); } - public static void setObfuscationPinningGatewayLocation(Context context, String location) { - putString(context, OBFUSCATION_PINNING_LOCATION, location); + public static void setObfuscationPinningGatewayLocation(String location) { + putString(OBFUSCATION_PINNING_LOCATION, location); } - public static String getObfuscationPinningGatewayLocation(Context context) { - return getString(context, OBFUSCATION_PINNING_LOCATION, null); + public static String getObfuscationPinningGatewayLocation() { + return getString(OBFUSCATION_PINNING_LOCATION, null); } - public static Boolean getObfuscationPinningKCP(Context context) { - return getBoolean(context, OBFUSCATION_PINNING_KCP, false); + public static Boolean getObfuscationPinningKCP() { + return getBoolean(OBFUSCATION_PINNING_KCP, false); } - public static void setObfuscationPinningKCP(Context context, boolean isKCP) { - putBoolean(context, OBFUSCATION_PINNING_KCP, isKCP); + public static void setObfuscationPinningKCP(boolean isKCP) { + putBoolean(OBFUSCATION_PINNING_KCP, isKCP); } - public static void setUseIPv6Firewall(Context context, boolean useFirewall) { - putBoolean(context, USE_IPv6_FIREWALL, useFirewall); + public static void setUseIPv6Firewall(boolean useFirewall) { + putBoolean(USE_IPv6_FIREWALL, useFirewall); } - public static boolean useIpv6Firewall(Context context) { - return getBoolean(context, USE_IPv6_FIREWALL, false); + public static boolean useIpv6Firewall() { + return getBoolean(USE_IPv6_FIREWALL, false); } - public static void saveShowAlwaysOnDialog(Context context, boolean showAlwaysOnDialog) { - putBoolean(context, ALWAYS_ON_SHOW_DIALOG, showAlwaysOnDialog); + public static void saveShowAlwaysOnDialog(boolean showAlwaysOnDialog) { + putBoolean(ALWAYS_ON_SHOW_DIALOG, showAlwaysOnDialog); } - public static boolean getShowAlwaysOnDialog(Context context) { - return getBoolean(context, ALWAYS_ON_SHOW_DIALOG, true); + public static boolean getShowAlwaysOnDialog() { + return getBoolean(ALWAYS_ON_SHOW_DIALOG, true); } - public static String getPreferredCity(Context context) { - return useObfuscationPinning(context) ? null : getString(context, PREFERRED_CITY, null); + public static String getPreferredCity() { + return useObfuscationPinning() ? null : getString(PREFERRED_CITY, null); } @WorkerThread - public static void setPreferredCity(Context context, String city) { - putStringSync(context, PREFERRED_CITY, city); + public static void setPreferredCity(String city) { + putStringSync(PREFERRED_CITY, city); } + @VisibleForTesting public static JSONObject getEipDefinitionFromPreferences(SharedPreferences preferences) { JSONObject result = new JSONObject(); + String eipDefinitionString = ""; + try { + synchronized (LOCK) { + eipDefinitionString = preferences.getString(PROVIDER_EIP_DEFINITION, ""); + } + if (!eipDefinitionString.isEmpty()) { + result = new JSONObject(eipDefinitionString); + } + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return result; + } + + public static JSONObject getEipDefinitionFromPreferences() { + JSONObject result = new JSONObject(); + String eipDefinitionString = ""; try { - String eipDefinitionString = preferences.getString(PROVIDER_EIP_DEFINITION, ""); + synchronized (LOCK) { + eipDefinitionString = preferences.getString(PROVIDER_EIP_DEFINITION, ""); + } if (!eipDefinitionString.isEmpty()) { result = new JSONObject(eipDefinitionString); } @@ -440,125 +573,121 @@ public class PreferenceHelper { return result; } - public static void setExcludedApps(Context context, Set apps) { - putStringSet(context, EXCLUDED_APPS, apps); + public static void setExcludedApps(Set apps) { + putStringSet(EXCLUDED_APPS, apps); } - public static Set getExcludedApps(Context context) { - if (context == null) { - return null; + public static Set getExcludedApps() { + synchronized (LOCK) { + return preferences.getStringSet(EXCLUDED_APPS, new HashSet<>()); } - SharedPreferences preferences = getSharedPreferences(context); - return preferences.getStringSet(EXCLUDED_APPS, new HashSet<>()); } - public static long getLong(Context context, String key, long defValue) { - if (context == null) { - return defValue; + public static long getLong(String key, long defValue) { + synchronized (LOCK) { + return preferences.getLong(key, defValue); } - SharedPreferences preferences = getSharedPreferences(context); - return preferences.getLong(key, defValue); } - public static void putLong(Context context, String key, long value) { - if (context == null) { - return; + public static void putLong(String key, long value) { + synchronized (LOCK) { + preferences.edit().putLong(key, value).apply(); } - SharedPreferences preferences = getSharedPreferences(context); - preferences.edit().putLong(key, value).apply(); } - public static String getString(Context context, String key, String defValue) { - if (context == null) { - return defValue; + public static int getInt(String key, int defValue) { + synchronized (LOCK) { + return preferences.getInt(key, defValue); } - SharedPreferences preferences = getSharedPreferences(context); - return preferences.getString(key, defValue); } - @WorkerThread - public static void putStringSync(Context context, String key, String value) { - if (context == null) { - return; + public static void putInt(String key, int value) { + synchronized (LOCK) { + preferences.edit().putInt(key, value).apply(); } - SharedPreferences preferences = getSharedPreferences(context); - preferences.edit().putString(key, value).commit(); } - public static void putString(Context context, String key, String value) { - if (context == null) { - return; + public static String getString(String key, String defValue) { + synchronized (LOCK) { + return preferences.getString(key, defValue); } - SharedPreferences preferences = getSharedPreferences(context); - preferences.edit().putString(key, value).apply(); } - public static void putStringSet(Context context, String key, Set value) { - if (context == null) { - return; + @WorkerThread + public static void putStringSync(String key, String value) { + synchronized (LOCK) { + preferences.edit().putString(key, value).commit(); } - SharedPreferences preferences = getSharedPreferences(context); - preferences.edit().putStringSet(key, value).apply(); } - public static boolean getBoolean(Context context, String key, Boolean defValue) { - if (context == null) { - return false; + public static void putString(String key, String value) { + synchronized (LOCK) { + preferences.edit().putString(key, value).apply(); } - - SharedPreferences preferences = getSharedPreferences(context); - return preferences.getBoolean(key, defValue); } - public static void putBoolean(Context context, String key, Boolean value) { - if (context == null) { - return; + public static void putStringSet(String key, Set value) { + synchronized (LOCK) { + preferences.edit().putStringSet(key, value).apply(); } + } - SharedPreferences preferences = getSharedPreferences(context); - preferences.edit().putBoolean(key, value).apply(); + public static boolean getBoolean(String key, Boolean defValue) { + synchronized (LOCK) { + return preferences.getBoolean(key, defValue); + } } - private static Boolean hasKey(Context context, String key) { - if (context == null) { - return false; + public static void putBoolean(String key, Boolean value) { + synchronized (LOCK) { + preferences.edit().putBoolean(key, value).apply(); } + } - SharedPreferences preferences = getSharedPreferences(context); - return preferences.contains(key); + public static void putBooleanSync(String key, Boolean value) { + synchronized (LOCK) { + preferences.edit().putBoolean(key, value).commit(); + } } - public static void migrateToEncryptedPrefs(Context context) { - SharedPreferences encryptedPrefs = getSharedPreferences(context); - if (!(encryptedPrefs instanceof EncryptedSharedPreferences)) { - Log.e(TAG, "Failed to migrate shared preferences"); - return; + public static Boolean hasKey(String key) { + synchronized (LOCK) { + return preferences.contains(key); } - SharedPreferences.Editor encryptedEditor = encryptedPrefs.edit(); - SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); - Map keys = preferences.getAll(); + } - for(Map.Entry entry : keys.entrySet()){ - try { - Object value = entry.getValue(); - if (value instanceof String) { - encryptedEditor.putString(entry.getKey(), (String) value); - } else if (value instanceof Boolean) { - encryptedEditor.putBoolean(entry.getKey(), (Boolean) value); - } else if (value instanceof Integer) { - encryptedEditor.putInt(entry.getKey(), (Integer) value); - } else if (value instanceof Set) { - encryptedEditor.putStringSet(entry.getKey(), (Set) value); - } else if (value instanceof Long) { - encryptedEditor.putLong(entry.getKey(), (Long) value); - } else if (value instanceof Float) { - encryptedEditor.putFloat(entry.getKey(), (Float) value); + public static void migrateToEncryptedPrefs(Context context) { + synchronized (LOCK) { + if (!(preferences instanceof EncryptedSharedPreferences)) { + Log.e(TAG, "Failed to migrate shared preferences"); + return; + } + SharedPreferences.Editor encryptedEditor = preferences.edit(); + SharedPreferences preferences = context.getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE); + Map keys = preferences.getAll(); + + for(Map.Entry entry : keys.entrySet()){ + try { + Object value = entry.getValue(); + if (value instanceof String) { + encryptedEditor.putString(entry.getKey(), (String) value); + } else if (value instanceof Boolean) { + encryptedEditor.putBoolean(entry.getKey(), (Boolean) value); + } else if (value instanceof Integer) { + encryptedEditor.putInt(entry.getKey(), (Integer) value); + } else if (value instanceof Set) { + encryptedEditor.putStringSet(entry.getKey(), (Set) value); + } else if (value instanceof Long) { + encryptedEditor.putLong(entry.getKey(), (Long) value); + } else if (value instanceof Float) { + encryptedEditor.putFloat(entry.getKey(), (Float) value); + } + } catch (ClassCastException e) { + e.printStackTrace(); } - } catch (ClassCastException e) { - e.printStackTrace(); } + encryptedEditor.commit(); + preferences.edit().clear().apply(); + } } - encryptedEditor.commit(); - preferences.edit().clear().apply(); - } } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java index 29714670..d8905bca 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EIP.java @@ -22,7 +22,6 @@ import static se.leap.bitmaskclient.R.string.vpn_certificate_is_invalid; import static se.leap.bitmaskclient.R.string.warning_client_parsing_error_gateways; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT; import static se.leap.bitmaskclient.base.models.Constants.BROADCAST_RESULT_KEY; -import static se.leap.bitmaskclient.base.models.Constants.CLEARLOG; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_CHECK_CERT_VALIDITY; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_IS_RUNNING; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_LAUNCH_VPN; @@ -50,7 +49,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.content.SharedPreferences; import android.net.VpnService; import android.os.Build; import android.os.Bundle; @@ -81,7 +79,6 @@ import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.core.ConnectionStatus; import de.blinkt.openvpn.core.IOpenVPNServiceInternal; import de.blinkt.openvpn.core.OpenVPNService; -import de.blinkt.openvpn.core.Preferences; import de.blinkt.openvpn.core.VpnStatus; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.OnBootReceiver; @@ -108,7 +105,6 @@ public final class EIP extends JobIntentService implements Observer { ERRORS = "errors", ERRORID = "errorId"; - private volatile SharedPreferences preferences; private volatile EipStatus eipStatus; // Service connection to OpenVpnService, shared between threads private volatile OpenVpnServiceConnection openVpnServiceConnection; @@ -144,7 +140,6 @@ public final class EIP extends JobIntentService implements Observer { super.onCreate(); eipStatus = EipStatus.getInstance(); eipStatus.addObserver(this); - preferences = PreferenceHelper.getSharedPreferences(this); } @Override @@ -230,8 +225,9 @@ public final class EIP extends JobIntentService implements Observer { earlyRoutes(result); } - if (!preferences.getBoolean(EIP_RESTART_ON_BOOT, false)) { - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, true).commit(); + if (!PreferenceHelper.getRestartOnBoot()) { + // TODO: check if move to async here was ok + PreferenceHelper.restartOnBoot(true); } if (!isVPNCertificateValid()) { @@ -328,7 +324,7 @@ public final class EIP extends JobIntentService implements Observer { if (gatewayOptions == null || gatewayOptions.gateway == null || (profile = gatewayOptions.gateway.getProfile(gatewayOptions.transportType)) == null) { - String preferredLocation = getPreferredCity(getApplicationContext()); + String preferredLocation = getPreferredCity(); if (preferredLocation != null) { setErrorResult(result, NO_MORE_GATEWAYS.toString(), getStringResourceForNoMoreGateways(), getString(R.string.app_name), preferredLocation); } else { @@ -354,8 +350,9 @@ public final class EIP extends JobIntentService implements Observer { LocalBroadcastManager.getInstance(this).sendBroadcast(setupObserverIntent); // Check if we need to clear the log - if (Preferences.getDefaultSharedPreferences(this).getBoolean(CLEARLOG, true)) + if (PreferenceHelper.getClearLog()) { VpnStatus.clearLog(); + } // check profile configuration int vpnok = profile.checkProfile(this); @@ -421,12 +418,12 @@ public final class EIP extends JobIntentService implements Observer { * @return true if VPN certificate is valid false otherwise */ private boolean isVPNCertificateValid() { - VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); + VpnCertificateValidator validator = new VpnCertificateValidator(PreferenceHelper.getProviderVPNCertificate()); return validator.isValid(); } private boolean shouldUpdateVPNCertificate() { - VpnCertificateValidator validator = new VpnCertificateValidator(preferences.getString(PROVIDER_VPN_CERTIFICATE, "")); + VpnCertificateValidator validator = new VpnCertificateValidator(PreferenceHelper.getProviderVPNCertificate()); return validator.shouldBeUpdated(); } @@ -476,7 +473,7 @@ public final class EIP extends JobIntentService implements Observer { * then stop VPN */ private boolean stop() { - preferences.edit().putBoolean(EIP_RESTART_ON_BOOT, false).apply(); + PreferenceHelper.restartOnBoot(false); if (eipStatus.isBlockingVpnEstablished()) { stopBlockingVpn(); } @@ -549,11 +546,11 @@ public final class EIP extends JobIntentService implements Observer { private @StringRes int getStringResourceForNoMoreGateways() { - boolean isManualGatewaySelection = PreferenceHelper.getPreferredCity(getApplicationContext()) != null; + boolean isManualGatewaySelection = PreferenceHelper.getPreferredCity() != null; if (isManualGatewaySelection) { return R.string.warning_no_more_gateways_manual_gw_selection; } else if (ProviderObservable.getInstance().getCurrentProvider().supportsPluggableTransports()) { - if (PreferenceHelper.getUseBridges(getApplicationContext())) { + if (PreferenceHelper.getUseBridges()) { return R.string.warning_no_more_gateways_use_ovpn; } else { return R.string.warning_no_more_gateways_use_pt; diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java index bb05810c..ed83770b 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java @@ -56,7 +56,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; @@ -98,12 +97,10 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta AtomicBoolean changingGateway = new AtomicBoolean(false); AtomicInteger setupNClosestGateway = new AtomicInteger(); private Vector listeners = new Vector<>(); - private SharedPreferences preferences; private static EipSetupObserver instance; - private EipSetupObserver(Context context, SharedPreferences preferences) { + private EipSetupObserver(Context context) { this.appContext = context.getApplicationContext(); - this.preferences = preferences; IntentFilter updateIntentFilter = new IntentFilter(BROADCAST_GATEWAY_SETUP_OBSERVER_EVENT); updateIntentFilter.addAction(BROADCAST_EIP_EVENT); updateIntentFilter.addAction(BROADCAST_PROVIDER_API_EVENT); @@ -115,9 +112,9 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta VpnStatus.addLogListener(this); } - public static void init(Context context, SharedPreferences preferences) { + public static void init(Context context) { if (instance == null) { - instance = new EipSetupObserver(context, preferences); + instance = new EipSetupObserver(context); } } @@ -196,7 +193,7 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta Log.d(TAG, "correctly updated service json"); provider = resultData.getParcelable(PROVIDER_KEY); ProviderObservable.getInstance().updateProvider(provider); - PreferenceHelper.storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); if (EipStatus.getInstance().isDisconnected()) { EipCommand.startVPN(appContext, false); } @@ -204,7 +201,7 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta case CORRECTLY_UPDATED_INVALID_VPN_CERTIFICATE: provider = resultData.getParcelable(PROVIDER_KEY); ProviderObservable.getInstance().updateProvider(provider); - PreferenceHelper.storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); EipCommand.startVPN(appContext, false); EipStatus.getInstance().setUpdatingVpnCert(false); if (TorStatusObservable.isRunning()) { @@ -214,7 +211,7 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta case CORRECTLY_DOWNLOADED_GEOIP_JSON: provider = resultData.getParcelable(PROVIDER_KEY); ProviderObservable.getInstance().updateProvider(provider); - PreferenceHelper.storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); maybeStartEipService(resultData); break; case INCORRECTLY_DOWNLOADED_GEOIP_JSON: @@ -400,7 +397,7 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta } private boolean shouldCheckAppUpdate() { - return System.currentTimeMillis() - PreferenceHelper.getLastAppUpdateCheck(appContext) >= UPDATE_CHECK_TIMEOUT; + return System.currentTimeMillis() - PreferenceHelper.getLastAppUpdateCheck() >= UPDATE_CHECK_TIMEOUT; } private void selectNextGateway() { 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 719b960e..d2592cd7 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/Gateway.java @@ -37,8 +37,6 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getObfuscationPi import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getPreferUDP; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.useObfuscationPinning; -import android.content.Context; - import androidx.annotation.NonNull; import com.google.gson.Gson; @@ -86,12 +84,12 @@ public class Gateway { * Build a gateway object from a JSON OpenVPN gateway definition in eip-service.json * and create a VpnProfile belonging to it. */ - public Gateway(JSONObject eipDefinition, JSONObject secrets, JSONObject gateway, Context context) + public Gateway(JSONObject eipDefinition, JSONObject secrets, JSONObject gateway) throws ConfigParser.ConfigParseError, JSONException, IOException { - this(eipDefinition, secrets, gateway, null, context); + this(eipDefinition, secrets, gateway, null); } - public Gateway(JSONObject eipDefinition, JSONObject secrets, JSONObject gateway, JSONObject load, Context context) + public Gateway(JSONObject eipDefinition, JSONObject secrets, JSONObject gateway, JSONObject load) throws ConfigParser.ConfigParseError, JSONException, IOException { this.gateway = gateway; @@ -99,28 +97,28 @@ public class Gateway { this.load = load; apiVersion = getApiVersion(eipDefinition); - VpnConfigGenerator.Configuration configuration = getProfileConfig(context, eipDefinition, apiVersion); + VpnConfigGenerator.Configuration configuration = getProfileConfig(eipDefinition, apiVersion); generalConfiguration = getGeneralConfiguration(eipDefinition); timezone = getTimezone(eipDefinition); name = configuration.profileName; vpnProfiles = createVPNProfiles(configuration); } - private VpnConfigGenerator.Configuration getProfileConfig(Context context, JSONObject eipDefinition, int apiVersion) { + private VpnConfigGenerator.Configuration getProfileConfig(JSONObject eipDefinition, int apiVersion) { VpnConfigGenerator.Configuration config = new VpnConfigGenerator.Configuration(); config.apiVersion = apiVersion; - config.preferUDP = getPreferUDP(context); - config.experimentalTransports = allowExperimentalTransports(context); - config.excludedApps = getExcludedApps(context); + config.preferUDP = getPreferUDP(); + config.experimentalTransports = allowExperimentalTransports(); + config.excludedApps = getExcludedApps(); - config.remoteGatewayIP = config.useObfuscationPinning ? getObfuscationPinningIP(context) : gateway.optString(IP_ADDRESS); - config.useObfuscationPinning = useObfuscationPinning(context); - config.profileName = config.useObfuscationPinning ? getObfuscationPinningGatewayLocation(context) : locationAsName(eipDefinition); + config.remoteGatewayIP = config.useObfuscationPinning ? getObfuscationPinningIP() : gateway.optString(IP_ADDRESS); + config.useObfuscationPinning = useObfuscationPinning(); + config.profileName = config.useObfuscationPinning ? getObfuscationPinningGatewayLocation() : locationAsName(eipDefinition); if (config.useObfuscationPinning) { - config.obfuscationProxyIP = getObfuscationPinningIP(context); - config.obfuscationProxyPort = getObfuscationPinningPort(context); - config.obfuscationProxyCert = getObfuscationPinningCert(context); - config.obfuscationProxyKCP = getObfuscationPinningKCP(context); + config.obfuscationProxyIP = getObfuscationPinningIP(); + config.obfuscationProxyPort = getObfuscationPinningPort(); + config.obfuscationProxyCert = getObfuscationPinningCert(); + config.obfuscationProxyKCP = getObfuscationPinningKCP(); } return config; } 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 5e05b7c1..9b4d431c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/GatewaysManager.java @@ -134,7 +134,7 @@ public class GatewaysManager { * @return the n closest Gateway */ public GatewayOptions select(int nClosest) { - if (PreferenceHelper.useObfuscationPinning(context)) { + if (PreferenceHelper.useObfuscationPinning()) { if (nClosest > 2) { // no need to try again the pinned proxy, probably configuration error return null; @@ -145,12 +145,12 @@ public class GatewaysManager { } return new GatewayOptions(gateway, OBFS4); } - String selectedCity = getPreferredCity(context); + String selectedCity = getPreferredCity(); return select(nClosest, selectedCity); } public GatewayOptions select(int nClosest, String city) { - TransportType[] transportTypes = getUseBridges(context) ? new TransportType[]{OBFS4, OBFS4_HOP} : new TransportType[]{OPENVPN}; + TransportType[] transportTypes = getUseBridges() ? new TransportType[]{OBFS4, OBFS4_HOP} : new TransportType[]{OPENVPN}; if (presortedList.size() > 0) { return getGatewayFromPresortedList(nClosest, transportTypes, city); } @@ -193,7 +193,7 @@ public class GatewaysManager { HashMap locationNames = new HashMap<>(); ArrayList locations = new ArrayList<>(); - String preferredCity = PreferenceHelper.getPreferredCity(context); + String preferredCity = PreferenceHelper.getPreferredCity(); for (Gateway gateway : gateways.values()) { String name = gateway.getName(); if (name == null) { @@ -399,16 +399,18 @@ public class GatewaysManager { e.printStackTrace(); } - if (PreferenceHelper.useObfuscationPinning(context)) { + if (PreferenceHelper.useObfuscationPinning()) { try { Transport[] transports = new Transport[]{ new Transport(OBFS4.toString(), - new String[]{getObfuscationPinningKCP(context) ? "kcp" : "tcp"}, - new String[]{getObfuscationPinningPort(context)}, - getObfuscationPinningCert(context))}; + new String[]{getObfuscationPinningKCP() ? "kcp" : "tcp"}, + new String[]{getObfuscationPinningPort()}, + getObfuscationPinningCert())}; GatewayJson.Capabilities capabilities = new GatewayJson.Capabilities(false, false, false, transports, false); - GatewayJson gatewayJson = new GatewayJson(context.getString(R.string.unknown_location), getObfuscationPinningIP(context), null, PINNED_OBFUSCATION_PROXY, capabilities); - Gateway gateway = new Gateway(eipDefinition, secrets, new JSONObject(gatewayJson.toString()), this.context); + GatewayJson gatewayJson = new GatewayJson(context.getString(R.string.unknown_location), getObfuscationPinningIP( + + ), null, PINNED_OBFUSCATION_PROXY, capabilities); + Gateway gateway = new Gateway(eipDefinition, secrets, new JSONObject(gatewayJson.toString())); addGateway(gateway); } catch (JSONException | ConfigParser.ConfigParseError | IOException e) { e.printStackTrace(); @@ -417,7 +419,7 @@ public class GatewaysManager { for (int i = 0; i < gatewaysDefined.length(); i++) { try { JSONObject gw = gatewaysDefined.getJSONObject(i); - Gateway aux = new Gateway(eipDefinition, secrets, gw, this.context); + Gateway aux = new Gateway(eipDefinition, secrets, gw); if (gateways.get(aux.getHost()) == null) { addGateway(aux); } @@ -515,7 +517,7 @@ public class GatewaysManager { } private boolean handleGatewayPinning() { - String host = PreferenceHelper.getPinnedGateway(this.context); + String host = PreferenceHelper.getPinnedGateway(); if (host == null) { return false; } diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java index d9da622c..53781f52 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VoidVpnService.java @@ -19,12 +19,10 @@ package se.leap.bitmaskclient.eip; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_ALWAYS_ON_VPN; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_START_BLOCKING_VPN; import static se.leap.bitmaskclient.base.models.Constants.EIP_ACTION_STOP_BLOCKING_VPN; -import static se.leap.bitmaskclient.base.models.Constants.EIP_IS_ALWAYS_ON; import static se.leap.bitmaskclient.base.utils.ConfigHelper.getProviderFormattedString; import android.app.Notification; import android.content.Intent; -import android.content.SharedPreferences; import android.net.VpnService; import android.os.Binder; import android.os.Build; @@ -84,8 +82,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat thread = new Thread(new Runnable() { public void run() { establishBlockingVpn(); - SharedPreferences preferences = PreferenceHelper.getSharedPreferences(VoidVpnService.this.getApplicationContext()); - preferences.edit().putBoolean(EIP_IS_ALWAYS_ON, false).commit(); + PreferenceHelper.isAlwaysOnSync(false); Log.d(TAG, "start blocking vpn profile - always on = false"); } }); @@ -96,8 +93,7 @@ public class VoidVpnService extends VpnService implements Observer, VpnNotificat thread = new Thread(new Runnable() { public void run() { establishBlockingVpn(); - SharedPreferences preferences = PreferenceHelper.getSharedPreferences(VoidVpnService.this.getApplicationContext()); - preferences.edit().putBoolean(EIP_IS_ALWAYS_ON, true).commit(); + PreferenceHelper.isAlwaysOnSync(true); requestVpnWithLastSelectedProfile(); Log.d(TAG, "start blocking vpn profile - always on = true"); } 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 fa2ab352..6d5a406e 100644 --- a/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java +++ b/app/src/main/java/se/leap/bitmaskclient/eip/VpnConfigGenerator.java @@ -25,7 +25,6 @@ import static se.leap.bitmaskclient.base.models.Constants.IP_ADDRESS6; import static se.leap.bitmaskclient.base.models.Constants.KCP; import static se.leap.bitmaskclient.base.models.Constants.PORTS; import static se.leap.bitmaskclient.base.models.Constants.PROTOCOLS; -import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE; import static se.leap.bitmaskclient.base.models.Constants.REMOTE; import static se.leap.bitmaskclient.base.models.Constants.TCP; diff --git a/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java b/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java index 0e81ce30..8df1638c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/firewall/FirewallManager.java @@ -92,10 +92,10 @@ public class FirewallManager implements FirewallCallback, Observer { TetheringObservable.allowVpnWifiTethering(false); TetheringObservable.allowVpnUsbTethering(false); TetheringObservable.allowVpnBluetoothTethering(false); - PreferenceHelper.allowWifiTethering(context, false); - PreferenceHelper.allowUsbTethering(context, false); - PreferenceHelper.allowBluetoothTethering(context, false); - PreferenceHelper.setUseIPv6Firewall(context, false); + PreferenceHelper.allowWifiTethering(false); + PreferenceHelper.allowUsbTethering(false); + PreferenceHelper.allowBluetoothTethering(false); + PreferenceHelper.setUseIPv6Firewall(false); } } @@ -107,7 +107,7 @@ public class FirewallManager implements FirewallCallback, Observer { public void start() { if (!isRunning) { isRunning = true; - if (PreferenceHelper.useIpv6Firewall(context)) { + if (PreferenceHelper.useIpv6Firewall()) { startIPv6Firewall(); } TetheringState tetheringState = TetheringObservable.getInstance().getTetheringState(); @@ -120,7 +120,7 @@ public class FirewallManager implements FirewallCallback, Observer { public void stop() { isRunning = false; - if (PreferenceHelper.useIpv6Firewall(context)) { + if (PreferenceHelper.useIpv6Firewall()) { stopIPv6Firewall(); } TetheringState tetheringState = TetheringObservable.getInstance().getTetheringState(); diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index 0e7e1f4a..07ea4691 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -178,7 +178,7 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB private ProviderApiManager initApiManager() { OkHttpClientGenerator clientGenerator = new OkHttpClientGenerator(getResources()); - return new ProviderApiManager(PreferenceHelper.getSharedPreferences(this), getResources(), clientGenerator, this); + return new ProviderApiManager(getResources(), clientGenerator, this); } } 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 fdaef28b..fbb0d507 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -101,7 +101,6 @@ import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.ON; import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort; import android.content.Intent; -import android.content.SharedPreferences; import android.content.res.Resources; import android.os.Bundle; import android.os.ResultReceiver; @@ -172,12 +171,10 @@ public abstract class ProviderApiManagerBase { private final ProviderApiServiceCallback serviceCallback; - protected SharedPreferences preferences; protected Resources resources; OkHttpClientGenerator clientGenerator; - ProviderApiManagerBase(SharedPreferences preferences, Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) { - this.preferences = preferences; + ProviderApiManagerBase(Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) { this.resources = resources; this.serviceCallback = callback; this.clientGenerator = clientGenerator; @@ -221,7 +218,7 @@ public abstract class ProviderApiManagerBase { } try { - if (PreferenceHelper.hasSnowflakePrefs(preferences) && !VpnStatus.isVPNActive()) { + if (PreferenceHelper.hasSnowflakePrefs() && !VpnStatus.isVPNActive()) { startTorProxy(); } } catch (InterruptedException | IllegalStateException e) { @@ -303,7 +300,7 @@ public abstract class ProviderApiManagerBase { if (result.getBoolean(BROADCAST_RESULT_KEY)) { Log.d(TAG, "successfully downloaded VPN certificate"); provider.setShouldUpdateVpnCertificate(false); - PreferenceHelper.storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); ProviderObservable.getInstance().updateProvider(provider); } ProviderObservable.getInstance().setProviderForDns(null); @@ -315,7 +312,7 @@ public abstract class ProviderApiManagerBase { provider.setMotdJson(motd); provider.setLastMotdUpdate(System.currentTimeMillis()); } - PreferenceHelper.storeProviderInPreferences(preferences, provider); + PreferenceHelper.storeProviderInPreferences(provider); ProviderObservable.getInstance().updateProvider(provider); break; @@ -359,7 +356,7 @@ public abstract class ProviderApiManagerBase { protected boolean startTorProxy() throws InterruptedException, IllegalStateException, TimeoutException { if (EipStatus.getInstance().isDisconnected() && - PreferenceHelper.getUseSnowflake(preferences) && + PreferenceHelper.getUseSnowflake() && serviceCallback.startTorService()) { waitForTorCircuits(); if (TorStatusObservable.isCancelled()) { @@ -385,7 +382,7 @@ public abstract class ProviderApiManagerBase { void resetProviderDetails(Provider provider) { provider.reset(); - deleteProviderDetailsFromPreferences(preferences, provider.getDomain()); + deleteProviderDetailsFromPreferences(provider.getDomain()); } String formatErrorMessage(final int errorStringId) { @@ -1037,16 +1034,16 @@ public abstract class ProviderApiManagerBase { } protected String getPersistedPrivateKey(String providerDomain) { - return getFromPersistedProvider(PROVIDER_PRIVATE_KEY, providerDomain, preferences); + return getFromPersistedProvider(PROVIDER_PRIVATE_KEY, providerDomain); } protected String getPersistedVPNCertificate(String providerDomain) { - return getFromPersistedProvider(PROVIDER_VPN_CERTIFICATE, providerDomain, preferences); + return getFromPersistedProvider(PROVIDER_VPN_CERTIFICATE, providerDomain); } protected JSONObject getPersistedProviderDefinition(String providerDomain) { try { - return new JSONObject(getFromPersistedProvider(Provider.KEY, providerDomain, preferences)); + return new JSONObject(getFromPersistedProvider(Provider.KEY, providerDomain)); } catch (JSONException e) { e.printStackTrace(); return new JSONObject(); @@ -1054,44 +1051,44 @@ public abstract class ProviderApiManagerBase { } protected String getPersistedProviderCA(String providerDomain) { - return getFromPersistedProvider(CA_CERT, providerDomain, preferences); + return getFromPersistedProvider(CA_CERT, providerDomain); } protected String getPersistedProviderApiIp(String providerDomain) { - return getFromPersistedProvider(PROVIDER_API_IP, providerDomain, preferences); + return getFromPersistedProvider(PROVIDER_API_IP, providerDomain); } protected String getPersistedProviderIp(String providerDomain) { - return getFromPersistedProvider(PROVIDER_IP, providerDomain, preferences); + return getFromPersistedProvider(PROVIDER_IP, providerDomain); } protected String getPersistedGeoIp(String providerDomain) { - return getFromPersistedProvider(GEOIP_URL, providerDomain, preferences); + return getFromPersistedProvider(GEOIP_URL, providerDomain); } protected JSONObject getPersistedMotd(String providerDomain) { try { - return new JSONObject(getFromPersistedProvider(PROVIDER_MOTD, providerDomain, preferences)); + return new JSONObject(getFromPersistedProvider(PROVIDER_MOTD, providerDomain)); } catch (JSONException e) { return new JSONObject(); } } protected long getPersistedMotdLastSeen(String providerDomain) { - return getLongFromPersistedProvider(PROVIDER_MOTD_LAST_SEEN, providerDomain, preferences); + return getLongFromPersistedProvider(PROVIDER_MOTD_LAST_SEEN, providerDomain); } protected long getPersistedMotdLastUpdate(String providerDomain) { - return getLongFromPersistedProvider(PROVIDER_MOTD_LAST_UPDATED, providerDomain, preferences); + return getLongFromPersistedProvider(PROVIDER_MOTD_LAST_UPDATED, providerDomain); } protected Set getPersistedMotdHashes(String providerDomain) { - return getStringSetFromPersistedProvider(PROVIDER_MOTD_HASHES, providerDomain, preferences); + return getStringSetFromPersistedProvider(PROVIDER_MOTD_HASHES, providerDomain); } protected boolean hasUpdatedProviderDetails(String domain) { - return preferences.contains(Provider.KEY + "." + domain) && preferences.contains(CA_CERT + "." + domain); + return PreferenceHelper.hasKey(Provider.KEY + "." + domain) && PreferenceHelper.hasKey(CA_CERT + "." + domain); } /** diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java index 0d5f903f..338a60e9 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupFailedDialog.java @@ -143,7 +143,7 @@ public class ProviderSetupFailedDialog extends DialogFragment { handleTorTimeoutError(); }); builder.setNeutralButton(R.string.retry_unobfuscated, ((dialog, id) -> { - PreferenceHelper.useSnowflake(getContext(), false); + PreferenceHelper.useSnowflake(false); handleTorTimeoutError(); })); default: @@ -189,7 +189,7 @@ public class ProviderSetupFailedDialog extends DialogFragment { interfaceWithConfigurationWizard = (DownloadFailedDialogInterface) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString() - + " must implement NoticeDialogListener"); + + " must implement DownloadFailedDialogInterface"); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java index fdc482fd..1bf66d7d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/ConfigWizardBaseActivity.java @@ -11,7 +11,6 @@ import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog; import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog; import static se.leap.bitmaskclient.tor.TorStatusObservable.getStringForCurrentStatus; -import android.content.SharedPreferences; import android.graphics.Rect; import android.os.Build; import android.os.Bundle; @@ -39,7 +38,6 @@ import java.util.Observer; import butterknife.BindView; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Provider; -import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.base.views.ProviderHeaderView; import se.leap.bitmaskclient.providersetup.TorLogAdapter; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -54,7 +52,6 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple private static final String TAG = ConfigWizardBaseActivity.class.getName(); public static final float GUIDE_LINE_COMPACT_DELTA = 0.1f; - protected SharedPreferences preferences; @BindView(R.id.header) ProviderHeaderView providerHeaderView; @@ -133,7 +130,6 @@ public abstract class ConfigWizardBaseActivity extends ButterKnifeActivity imple @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - preferences = PreferenceHelper.getSharedPreferences(this); provider = getIntent().getParcelableExtra(PROVIDER_KEY); } 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 1bc12f57..2709fd0b 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 @@ -29,16 +29,16 @@ public class CircumventionSetupFragment extends BaseSetupFragment { binding.circumventionRadioGroup.setOnCheckedChangeListener((group, checkedId) -> { if (binding.rbCircumvention.getId() == checkedId) { - PreferenceHelper.useBridges(getContext(), true); - PreferenceHelper.useSnowflake(getContext(), true); + PreferenceHelper.useBridges(true); + PreferenceHelper.useSnowflake(true); binding.tvCircumventionDetailDescription.setVisibility(View.VISIBLE); binding.rbCircumvention.setTypeface(Typeface.DEFAULT, Typeface.BOLD); binding.rbPlainVpn.setTypeface(Typeface.DEFAULT, Typeface.NORMAL); return; } - PreferenceHelper.useBridges(getContext(), false); - PreferenceHelper.useSnowflake(getContext(), false); + PreferenceHelper.useBridges(false); + PreferenceHelper.useSnowflake(false); 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/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java index 41e7cb8e..26f62042 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java @@ -72,7 +72,7 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FConfigureProviderBinding.inflate(inflater, container, false); - binding.detailContainer.setVisibility(PreferenceHelper.getUseSnowflake(getContext()) ? VISIBLE : GONE); + binding.detailContainer.setVisibility(PreferenceHelper.getUseSnowflake() ? VISIBLE : GONE); binding.detailHeaderContainer.setOnClickListener(v -> { binding.ivExpand.animate().setDuration(250).rotation(isExpanded ? -90 : 0); showConnectionDetails(); @@ -99,7 +99,7 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse public void onFragmentSelected() { super.onFragmentSelected(); ignoreProviderAPIUpdates = false; - binding.detailContainer.setVisibility(PreferenceHelper.getUseSnowflake(getContext()) ? VISIBLE : GONE); + binding.detailContainer.setVisibility(PreferenceHelper.getUseSnowflake() ? VISIBLE : GONE); setupActivityCallback.setNavigationButtonHidden(true); setupActivityCallback.setCancelButtonHidden(false); ProviderAPICommand.execute(getContext(), SET_UP_PROVIDER, setupActivityCallback.getSelectedProvider()); diff --git a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java index d74175f5..926affe0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/tethering/TetheringStateManager.java @@ -62,9 +62,9 @@ public class TetheringStateManager { intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED"); context.getApplicationContext().registerReceiver(broadcastReceiver, intentFilter); instance.wifiManager = new WifiManagerWrapper(context); - TetheringObservable.allowVpnWifiTethering(isWifiTetheringAllowed(context)); - TetheringObservable.allowVpnUsbTethering(isUsbTetheringAllowed(context)); - TetheringObservable.allowVpnBluetoothTethering(isBluetoothTetheringAllowed(context)); + TetheringObservable.allowVpnWifiTethering(isWifiTetheringAllowed()); + TetheringObservable.allowVpnUsbTethering(isUsbTetheringAllowed()); + TetheringObservable.allowVpnBluetoothTethering(isBluetoothTetheringAllowed()); updateWifiTetheringState(); updateUsbTetheringState(); updateBluetoothTetheringState(); 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 b99abb3d..9e95700c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java +++ b/app/src/main/java/se/leap/bitmaskclient/tor/TorServiceCommand.java @@ -15,6 +15,10 @@ package se.leap.bitmaskclient.tor; * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + +import static se.leap.bitmaskclient.tor.TorNotificationManager.TOR_SERVICE_NOTIFICATION_ID; +import static se.leap.bitmaskclient.tor.TorStatusObservable.waitUntil; + import android.app.Notification; import android.content.Context; import android.content.Intent; @@ -29,9 +33,6 @@ import java.util.concurrent.TimeoutException; import se.leap.bitmaskclient.base.utils.PreferenceHelper; -import static se.leap.bitmaskclient.tor.TorNotificationManager.TOR_SERVICE_NOTIFICATION_ID; -import static se.leap.bitmaskclient.tor.TorStatusObservable.waitUntil; - public class TorServiceCommand { @@ -132,7 +133,7 @@ public class TorServiceCommand { private static TorServiceConnection initTorServiceConnection(Context context) throws InterruptedException, IllegalStateException { Log.d(TAG, "initTorServiceConnection"); - if (PreferenceHelper.getUseSnowflake(context)) { + if (PreferenceHelper.getUseSnowflake()) { Log.d(TAG, "serviceConnection is still null"); if (!TorService.hasClientTransportPlugin()) { TorService.setClientTransportPlugin(new ClientTransportPlugin(context.getApplicationContext())); diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java index 63823925..59b9159c 100644 --- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java +++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java @@ -37,7 +37,6 @@ import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWN import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort; -import android.content.SharedPreferences; import android.content.res.Resources; import android.os.Bundle; import android.util.Pair; @@ -54,6 +53,7 @@ import okhttp3.OkHttpClient; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.utils.ConfigHelper; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; import se.leap.bitmaskclient.eip.EIP; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; import se.leap.bitmaskclient.tor.TorStatusObservable; @@ -68,8 +68,8 @@ public class ProviderApiManager extends ProviderApiManagerBase { private static final String TAG = ProviderApiManager.class.getSimpleName(); - public ProviderApiManager(SharedPreferences preferences, Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) { - super(preferences, resources, clientGenerator, callback); + public ProviderApiManager(Resources resources, OkHttpClientGenerator clientGenerator, ProviderApiServiceCallback callback) { + super(resources, clientGenerator, callback); } /** @@ -271,7 +271,7 @@ public class ProviderApiManager extends ProviderApiManagerBase { if (DEBUG_MODE) { VpnStatus.logDebug("[API] CA CERT: " + certString); } - preferences.edit().putString(Provider.CA_CERT + "." + providerDomain, certString).apply(); + PreferenceHelper.putProviderString(providerDomain, Provider.CA_CERT, certString); result.putBoolean(BROADCAST_RESULT_KEY, true); } else { setErrorResult(result, warning_corrupted_provider_cert, ERROR_CERTIFICATE_PINNING.toString()); diff --git a/app/src/test/java/se/leap/bitmaskclient/base/utils/PreferenceHelperTest.java b/app/src/test/java/se/leap/bitmaskclient/base/utils/PreferenceHelperTest.java index 955ddc44..e03fccff 100644 --- a/app/src/test/java/se/leap/bitmaskclient/base/utils/PreferenceHelperTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/base/utils/PreferenceHelperTest.java @@ -13,6 +13,7 @@ import static org.junit.Assert.assertTrue; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_EIP_DEFINITION; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_PRIVATE_KEY; import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.preferUDP; import static se.leap.bitmaskclient.testutils.TestSetupHelper.getInputAsString; import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSavedProviderFromSharedPreferences; @@ -22,16 +23,18 @@ import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSavedProvider public class PreferenceHelperTest { private SharedPreferences mockPreferences; + PreferenceHelper preferenceHelper; @Before public void setup() { mockPreferences = new MockSharedPreferences(); + preferenceHelper = new PreferenceHelper(mockPreferences); } @Test public void getSavedProviderFromSharedPreferences_notInPreferences_returnsDefaultProvider() throws Exception { - Provider provider = getSavedProviderFromSharedPreferences(mockPreferences); + Provider provider = getSavedProviderFromSharedPreferences(); assertFalse(provider.isConfigured()); } @@ -45,7 +48,7 @@ public class PreferenceHelperTest { .putString(PROVIDER_VPN_CERTIFICATE, getInputAsString(getClass().getClassLoader().getResourceAsStream("riseup.net.vpn_cert.pem"))) .putString(PROVIDER_PRIVATE_KEY, getInputAsString(getClass().getClassLoader().getResourceAsStream("private_rsa_key.pem"))) .apply(); - Provider provider = getSavedProviderFromSharedPreferences(mockPreferences); + Provider provider = getSavedProviderFromSharedPreferences(); assertTrue(provider.isConfigured()); } diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/EipStatusTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/EipStatusTest.java index 1e15c5ab..cec627ef 100644 --- a/app/src/test/java/se/leap/bitmaskclient/eip/EipStatusTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/eip/EipStatusTest.java @@ -61,7 +61,7 @@ public class EipStatusTest { VpnProfile mockVpnProfile = new VpnProfile("mockProfile", OPENVPN); mockVpnProfile.mPersistTun = true; doNothing().when(PreferenceHelper.class); - VpnStatus.setLastConnectedVpnProfile(null, mockVpnProfile); + VpnStatus.setLastConnectedVpnProfile(mockVpnProfile); VpnStatus.updateStateString("SCREENOFF", "", R.string.state_screenoff, LEVEL_VPNPAUSED); assertTrue("LEVEL_VPN_PAUSED eipLevel", eipStatus.getEipLevel() == CONNECTING); assertTrue("LEVEL_VPN_PAUSED level", eipStatus.getLevel() == LEVEL_VPNPAUSED); @@ -74,7 +74,7 @@ public class EipStatusTest { VpnProfile mockVpnProfile = new VpnProfile("mockProfile", OPENVPN); mockVpnProfile.mPersistTun = false; doNothing().when(PreferenceHelper.class); - VpnStatus.setLastConnectedVpnProfile(null, mockVpnProfile); + VpnStatus.setLastConnectedVpnProfile(mockVpnProfile); VpnStatus.updateStateString("SCREENOFF", "", R.string.state_screenoff, LEVEL_VPNPAUSED); assertTrue("LEVEL_VPN_PAUSED eipLevel", eipStatus.getEipLevel() == DISCONNECTED); assertTrue("LEVEL_VPN_PAUSED level", eipStatus.getLevel() == LEVEL_VPNPAUSED); diff --git a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java index 6f26e494..74762813 100644 --- a/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/eip/GatewaySelectorTest.java @@ -24,6 +24,8 @@ import java.util.ArrayList; import de.blinkt.openvpn.core.ConfigParser; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.utils.ConfigHelper; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; +import se.leap.bitmaskclient.testutils.MockSharedPreferences; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; @@ -69,6 +71,7 @@ public class GatewaySelectorTest { */ + PreferenceHelper preferenceHelper; GatewaySelector gatewaySelector; JSONObject eipDefinition; ArrayList gatewayList = new ArrayList<>(); @@ -78,6 +81,7 @@ public class GatewaySelectorTest { mockStatic(ConfigHelper.class); when(ConfigHelper.timezoneDistance(anyInt(), anyInt())).thenCallRealMethod(); mockTextUtils(); + preferenceHelper = new PreferenceHelper(new MockSharedPreferences()); eipDefinition = new JSONObject(getInputAsString(getClass().getClassLoader().getResourceAsStream("eip-service-four-gateways.json"))); JSONArray gateways = eipDefinition.getJSONArray("gateways"); for (int i = 0; i < gateways.length(); i++) { diff --git a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java index 4ef8b9cc..91823433 100644 --- a/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java +++ b/app/src/test/java/se/leap/bitmaskclient/testutils/MockHelper.java @@ -469,7 +469,7 @@ public class MockHelper { public static void mockPreferenceHelper(final Provider providerFromPrefs) { // FIXME use MockSharedPreferences instead of provider mockStatic(PreferenceHelper.class); - when(getFromPersistedProvider(anyString(), anyString(), any(SharedPreferences.class))).thenAnswer(new Answer() { + when(getFromPersistedProvider(anyString(), anyString())).thenAnswer(new Answer() { @Override public String answer(InvocationOnMock invocation) throws Throwable { String key = (String) invocation.getArguments()[0]; @@ -495,7 +495,7 @@ public class MockHelper { return null; } }); - when(getLongFromPersistedProvider(anyString(), anyString(), any(SharedPreferences.class))).thenAnswer(new Answer() { + when(getLongFromPersistedProvider(anyString(), anyString())).thenAnswer(new Answer() { @Override public Long answer(InvocationOnMock invocation) throws Throwable { String key = (String) invocation.getArguments()[0]; @@ -508,7 +508,7 @@ public class MockHelper { return 0L; } }); - when(getStringSetFromPersistedProvider(anyString(), anyString(), any(SharedPreferences.class))).thenAnswer(new Answer>() { + when(getStringSetFromPersistedProvider(anyString(), anyString())).thenAnswer(new Answer>() { @Override public Set answer(InvocationOnMock invocation) throws Throwable { String key = (String) invocation.getArguments()[0]; @@ -519,14 +519,43 @@ public class MockHelper { return null; } }); + when(PreferenceHelper.hasKey(anyString())).then(new Answer() { + @Override + public Boolean answer(InvocationOnMock invocation) throws Throwable { + String key = (String) invocation.getArguments()[0]; + if (key!= null && key.contains(providerFromPrefs.getDomain())) { + key = key.substring(0, key.indexOf(providerFromPrefs.getDomain()) - 1 /* -1 -> "." at the end */); + } + switch (key) { + case PROVIDER_PRIVATE_KEY: + return providerFromPrefs.getPrivateKey() != null; + case PROVIDER_VPN_CERTIFICATE: + return providerFromPrefs.getVpnCertificate() != null; + case Provider.KEY: + return providerFromPrefs.getDefinition().keys().hasNext(); + case Provider.CA_CERT_FINGERPRINT: + return providerFromPrefs.getCaCertFingerprint().length() > 1; + case Provider.CA_CERT: + return providerFromPrefs.getCaCert() != null; + case Provider.GEOIP_URL: + return !providerFromPrefs.getGeoipUrl().isDefault(); + case Provider.MOTD_URL: + return !providerFromPrefs.getMotdUrl().isDefault(); + case PROVIDER_MOTD: + return providerFromPrefs.getMotdJson().keys().hasNext(); + } + return false; + } + }); } public static void mockPreferenceHelper(MockSharedPreferences preferences) { mockStatic(PreferenceHelper.class); - when(getEipDefinitionFromPreferences(any(SharedPreferences.class))).thenAnswer(new Answer() { + when(getEipDefinitionFromPreferences()).thenAnswer(new Answer() { @Override public JSONObject answer(InvocationOnMock invocation) throws Throwable { + return getEipDefinitionFromPreferences(preferences); } }); diff --git a/app/src/test/java/se/leap/bitmaskclient/tethering/TetheringStateManagerTest.java b/app/src/test/java/se/leap/bitmaskclient/tethering/TetheringStateManagerTest.java index d972923c..a2569282 100644 --- a/app/src/test/java/se/leap/bitmaskclient/tethering/TetheringStateManagerTest.java +++ b/app/src/test/java/se/leap/bitmaskclient/tethering/TetheringStateManagerTest.java @@ -68,8 +68,6 @@ public class TetheringStateManagerTest { PowerMockito.whenNew(IntentFilter.class).withArguments(anyString()).thenReturn(intentFilter); PowerMockito.whenNew(IntentFilter.class).withNoArguments().thenReturn(intentFilter); mockStatic(PreferenceHelper.class); - SharedPreferences sharedPreferences = new MockSharedPreferences(); - when(PreferenceHelper.getSharedPreferences(any())).thenReturn(sharedPreferences); observable = TetheringObservable.getInstance(); -- cgit v1.2.3