summaryrefslogtreecommitdiff
path: root/app/src/main/java/se/leap/bitmaskclient/base
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/base')
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/MainActivity.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/OnBootReceiver.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/StartActivity.java35
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/AlwaysOnDialog.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/DonationReminderDialog.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/EipFragment.java26
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/ExcludeAppsFragment.java4
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/GatewaySelectionFragment.java20
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/LogFragment.java8
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/MainActivityErrorDialog.java10
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/NavigationDrawerFragment.java24
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/ObfuscationProxyDialog.java23
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/SettingsFragment.java50
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/fragments/TetheringDialog.java12
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/PreferenceHelper.java725
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java71
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java14
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/views/MainButton.java13
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java63
20 files changed, 690 insertions, 447 deletions
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 94000a0f..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;
@@ -54,8 +53,8 @@ import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.DateHelper;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.eip.EipCommand;
-import se.leap.bitmaskclient.providersetup.ProviderListActivity;
import se.leap.bitmaskclient.providersetup.activities.CustomProviderSetupActivity;
+import se.leap.bitmaskclient.providersetup.activities.SetupActivity;
/**
* Activity shown at startup. Evaluates if App is started for the first time or has been upgraded
@@ -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();
@@ -249,7 +244,7 @@ public class StartActivity extends Activity{
getIntent().removeExtra(APP_ACTION_CONFIGURE_ALWAYS_ON_PROFILE);
}
if (isDefaultBitmask()) {
- startActivityForResult(new Intent(this, ProviderListActivity.class), REQUEST_CODE_CONFIGURE_LEAP);
+ startActivityForResult(new Intent(this, SetupActivity.class), REQUEST_CODE_CONFIGURE_LEAP);
} else { // custom branded app
startActivityForResult(new Intent(this, CustomProviderSetupActivity.class), REQUEST_CODE_CONFIGURE_LEAP);
}
@@ -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..18f20a6f 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;
@@ -67,6 +65,7 @@ import se.leap.bitmaskclient.base.views.IconSwitchEntry;
import se.leap.bitmaskclient.base.views.IconTextEntry;
import se.leap.bitmaskclient.eip.EipStatus;
import se.leap.bitmaskclient.providersetup.ProviderListActivity;
+import se.leap.bitmaskclient.providersetup.activities.SetupActivity;
import se.leap.bitmaskclient.tethering.TetheringObservable;
/**
@@ -99,8 +98,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 +105,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
@@ -242,7 +236,7 @@ public class NavigationDrawerFragment extends Fragment implements SharedPreferen
switchProvider.setVisibility(VISIBLE);
switchProvider.setOnClickListener(v -> {
closeDrawer();
- getActivity().startActivityForResult(new Intent(getActivity(), ProviderListActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
+ getActivity().startActivityForResult(new Intent(getActivity(), SetupActivity.class), REQUEST_CODE_SWITCH_PROVIDER);
});
}
}
@@ -260,7 +254,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 +262,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 +282,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 +382,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 +411,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<String> apps = PreferenceHelper.getExcludedApps(this.getContext());
+ Set<String> 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<String> getStringSetFromPersistedProvider(String toFetch, String providerDomain, SharedPreferences preferences) {
- return preferences.getStringSet(toFetch + "." + providerDomain, new HashSet<>());
+ public static Set<String> 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<String> apps) {
- putStringSet(context, EXCLUDED_APPS, apps);
+ public static void setExcludedApps(Set<String> apps) {
+ putStringSet(EXCLUDED_APPS, apps);
}
- public static Set<String> getExcludedApps(Context context) {
- if (context == null) {
- return null;
+ public static Set<String> 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<String> 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<String> 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<String,?> keys = preferences.getAll();
+ }
- for(Map.Entry<String,?> 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<String>) 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<String,?> keys = preferences.getAll();
+
+ for(Map.Entry<String,?> 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<String>) 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/base/utils/ViewHelper.java b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java
index 51bcb2b1..ebf26048 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/utils/ViewHelper.java
@@ -1,11 +1,14 @@
package se.leap.bitmaskclient.base.utils;
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
import android.app.Activity;
-import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
-import android.os.Build;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
@@ -13,13 +16,14 @@ import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes;
+import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.widget.AppCompatTextView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
@@ -146,4 +150,65 @@ public class ViewHelper {
bar.setTitle(spannableTitle);
}
+ public interface AnimationInterface {
+ void onAnimationEnd();
+ }
+
+ public static void animateContainerVisibility(View container, boolean isExpanded) {
+ animateContainerVisibility(container, isExpanded, null);
+ }
+
+ public static void animateContainerVisibility(View container, boolean isExpanded, AnimationInterface animationInterface) {
+
+ int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+ int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
+
+ container.measure(widthMeasureSpec, heightMeasureSpec);
+ int measuredHeight = container.getMeasuredHeight();
+
+ int targetHeight = isExpanded ? 0 : measuredHeight; // Get the actual content height of the view
+ int initialHeight = isExpanded ? measuredHeight : 0;
+
+ ValueAnimator animator = ValueAnimator.ofInt(initialHeight, targetHeight);
+ animator.setDuration(250); // Set the duration of the animation in milliseconds
+
+ animator.addUpdateListener(animation -> {
+ container.getLayoutParams().height = (int) animation.getAnimatedValue();
+ container.requestLayout();
+ });
+ animator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(@NonNull Animator animation) {
+ if (initialHeight == 0 && container.getVisibility() == GONE) {
+ container.setVisibility(VISIBLE);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(@NonNull Animator animation) {
+ if (targetHeight == 0) {
+ container.setVisibility(GONE);
+ }
+ if (animationInterface != null) {
+ animationInterface.onAnimationEnd();
+ }
+ }
+
+ @Override
+ public void onAnimationCancel(@NonNull Animator animation) {
+ container.setVisibility(targetHeight == 0 ? GONE : VISIBLE);
+ }
+
+ @Override
+ public void onAnimationRepeat(@NonNull Animator animation) {}
+ });
+
+ animator.start();
+ }
+
+ public static void hideKeyboardFrom(Context context, View view) {
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
+ }
+
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java b/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java
index a151305e..3aa21ae9 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/views/ActionBarTitle.java
@@ -1,10 +1,11 @@
package se.leap.bitmaskclient.base.views;
import android.content.Context;
+import android.graphics.Typeface;
+import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
-import android.widget.RelativeLayout;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
@@ -90,7 +91,16 @@ public class ActionBarTitle extends LinearLayoutCompat {
actionBarTitle.setLayoutParams(titleLayoutParams);
actionBarSubtitle.setLayoutParams(subtitleLayoutParams);
container.setLayoutParams(containerLayoutParams);
+ }
-
+ public void setSingleBoldTitle() {
+ showSubtitle(false);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+ actionBarTitle.setTypeface(Typeface.create(null,900,false));
+ } else {
+ actionBarTitle.setTypeface(actionBarTitle.getTypeface(), Typeface.BOLD);
+ }
+ actionBarTitle.setLetterSpacing(0.05f);
+ actionBarTitle.setTextSize(24f);
}
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/MainButton.java b/app/src/main/java/se/leap/bitmaskclient/base/views/MainButton.java
index c7273613..e322e6c6 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/views/MainButton.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/views/MainButton.java
@@ -2,10 +2,13 @@ package se.leap.bitmaskclient.base.views;
import android.annotation.TargetApi;
import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
+import androidx.annotation.DrawableRes;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat;
@@ -56,4 +59,14 @@ public class MainButton extends RelativeLayout {
button.setTag(isOn ? "button_circle_stop" : "button_circle_start");
}
}
+
+ public void setCustomDrawable(@DrawableRes int drawableResource) {
+ Drawable drawable = ContextCompat.getDrawable(getContext(), drawableResource);
+ if (drawable == null) {
+ return;
+ }
+
+ button.setImageDrawable(drawable);
+ button.setTag("button_setup_circle_custom");
+ }
}
diff --git a/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java b/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java
new file mode 100644
index 00000000..380ddf23
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/base/views/ProgressSpinner.java
@@ -0,0 +1,63 @@
+package se.leap.bitmaskclient.base.views;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.RelativeLayout;
+
+import androidx.appcompat.widget.AppCompatImageView;
+import androidx.appcompat.widget.AppCompatTextView;
+import androidx.core.content.ContextCompat;
+
+import se.leap.bitmaskclient.R;
+import se.leap.bitmaskclient.databinding.VProgressSpinnerBinding;
+
+public class ProgressSpinner extends RelativeLayout {
+
+ private static final String TAG = ProgressSpinner.class.getSimpleName();
+
+ AppCompatImageView spinnerView;
+ AppCompatTextView textView;
+
+ public ProgressSpinner(Context context) {
+ super(context);
+ initLayout(context);
+ }
+
+ public ProgressSpinner(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initLayout(context);
+ }
+
+ public ProgressSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initLayout(context);
+ }
+
+
+ public ProgressSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initLayout(context);
+ }
+
+ private void initLayout(Context context) {
+ VProgressSpinnerBinding binding = VProgressSpinnerBinding.inflate(LayoutInflater.from(context), this, true);
+ spinnerView = binding.spinnerView;
+ textView = binding.tvProgress;
+ }
+
+ public void update(int progress) {
+ String text = "";
+ if (progress > 0) {
+ if ((progress / 10) == 0) {
+ text = text + " ";
+ }
+ if ((progress / 100) == 0) {
+ text = text + " ";
+ }
+ text = text + progress + "%";
+ }
+ textView.setText(text);
+ }
+}