diff options
Diffstat (limited to 'app/src/main/java/se/leap/bitmaskclient/providersetup')
7 files changed, 63 insertions, 102 deletions
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java index ed30c454..68699da2 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderAPI.java @@ -30,7 +30,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import java.util.concurrent.TimeoutException; -import se.leap.bitmaskclient.base.utils.PreferenceHelper; +import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.providersetup.connectivity.OkHttpClientGenerator; import se.leap.bitmaskclient.tor.TorServiceCommand; @@ -177,6 +177,12 @@ public class ProviderAPI extends JobIntentService implements ProviderApiManagerB } } + @Override + public void saveProvider(Provider p) { + ProviderManager pm = ProviderManager.getInstance(this.getAssets()); + pm.add(p); + pm.saveCustomProviders(); + } private ProviderApiManager initApiManager() { diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java index 1f737b0c..ae55f81c 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java @@ -170,6 +170,7 @@ public abstract class ProviderApiManagerBase { void stopTorService(); int getTorHttpTunnelPort(); boolean hasNetworkConnection(); + void saveProvider(Provider p); } private final ProviderApiServiceCallback serviceCallback; @@ -295,6 +296,7 @@ public abstract class ProviderApiManagerBase { ProviderObservable.getInstance().setProviderForDns(provider); result = updateVpnCertificate(provider); if (result.getBoolean(BROADCAST_RESULT_KEY)) { + serviceCallback.saveProvider(provider); ProviderSetupObservable.updateProgress(DOWNLOADED_VPN_CERTIFICATE); sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider); } else { @@ -362,6 +364,10 @@ public abstract class ProviderApiManagerBase { } } + private void saveCustomProvider() { + + } + protected boolean startTorProxy() throws InterruptedException, IllegalStateException, TimeoutException { if (EipStatus.getInstance().isDisconnected() && PreferenceHelper.getUseSnowflake() && diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderManager.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderManager.java index 38198f89..9eacae5d 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderManager.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderManager.java @@ -3,15 +3,11 @@ package se.leap.bitmaskclient.providersetup; import static se.leap.bitmaskclient.base.models.Constants.EXT_JSON; import static se.leap.bitmaskclient.base.models.Constants.EXT_PEM; import static se.leap.bitmaskclient.base.models.Constants.URLS; -import static se.leap.bitmaskclient.base.models.Provider.DOMAIN; import static se.leap.bitmaskclient.base.models.Provider.GEOIP_URL; import static se.leap.bitmaskclient.base.models.Provider.MAIN_URL; import static se.leap.bitmaskclient.base.models.Provider.MOTD_URL; import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_API_IP; import static se.leap.bitmaskclient.base.models.Provider.PROVIDER_IP; -import static se.leap.bitmaskclient.base.utils.FileHelper.createFile; -import static se.leap.bitmaskclient.base.utils.FileHelper.persistFile; -import static se.leap.bitmaskclient.base.utils.InputStreamHelper.getInputStreamFrom; import static se.leap.bitmaskclient.base.utils.InputStreamHelper.inputStreamToJson; import static se.leap.bitmaskclient.base.utils.InputStreamHelper.loadInputStreamAsString; @@ -21,18 +17,18 @@ import androidx.annotation.VisibleForTesting; import org.json.JSONObject; -import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import se.leap.bitmaskclient.base.models.Provider; +import se.leap.bitmaskclient.base.utils.PreferenceHelper; /** * Created by parmegv on 4/12/14. @@ -40,18 +36,17 @@ import se.leap.bitmaskclient.base.models.Provider; public class ProviderManager { private final AssetManager assetsManager; - private File externalFilesDir; private Set<Provider> defaultProviders; - private Set<Provider> customProviders; + // key: MainURL String, value: Provider + private HashMap<String, Provider> customProviders; private Set<String> defaultProviderURLs; - private Set<String> customProviderURLs; private static ProviderManager instance; private boolean addDummyEntry = false; - public static ProviderManager getInstance(AssetManager assetsManager, File externalFilesDir) { + public static ProviderManager getInstance(AssetManager assetsManager) { if (instance == null) - instance = new ProviderManager(assetsManager, externalFilesDir); + instance = new ProviderManager(assetsManager); return instance; } @@ -65,10 +60,10 @@ public class ProviderManager { this.addDummyEntry = addDummyEntry; } - private ProviderManager(AssetManager assetManager, File externalFilesDir) { + private ProviderManager(AssetManager assetManager) { this.assetsManager = assetManager; addDefaultProviders(assetManager); - addCustomProviders(externalFilesDir); + addCustomProviders(); } private void addDefaultProviders(AssetManager assetManager) { @@ -122,29 +117,8 @@ public class ProviderManager { } - private void addCustomProviders(File externalFilesDir) { - this.externalFilesDir = externalFilesDir; - customProviders = externalFilesDir != null && externalFilesDir.isDirectory() ? - customProvidersFromFiles(externalFilesDir.list()) : - new HashSet<>(); - customProviderURLs = getProviderUrlSetFromProviderSet(customProviders); - } - - private Set<Provider> customProvidersFromFiles(String[] files) { - Set<Provider> providers = new HashSet<>(); - try { - for (String file : files) { - InputStream inputStream = getInputStreamFrom(externalFilesDir.getAbsolutePath() + "/" + file); - JSONObject providerConfig = inputStreamToJson(inputStream); - String mainUrl = providerConfig.optString(MAIN_URL); - String domain = providerConfig.optString(DOMAIN); - providers.add(Provider.createCustomProvider(mainUrl, domain)); - } - } catch (FileNotFoundException | NullPointerException e) { - e.printStackTrace(); - } - - return providers; + private void addCustomProviders() { + customProviders = PreferenceHelper.getCustomProviders(); } public List<Provider> providers() { @@ -155,7 +129,7 @@ public class ProviderManager { List<Provider> allProviders = new ArrayList<>(); allProviders.addAll(defaultProviders); if(customProviders != null) - allProviders.addAll(customProviders); + allProviders.addAll(customProviders.values()); if (addEmptyProvider) { //add an option to add a custom provider allProviders.add(new Provider()); @@ -177,16 +151,19 @@ public class ProviderManager { } public boolean add(Provider element) { - return element != null && - !defaultProviderURLs.contains(element.getMainUrl().toString()) && - customProviders.add(element) && - customProviderURLs.add(element.getMainUrl().toString()); + boolean addElement = element != null && + !defaultProviderURLs.contains(element.getMainUrlString()) && + !customProviders.containsKey(element.getMainUrlString()); + if (addElement) { + customProviders.put(element.getMainUrlString(), element); + return true; + } + return false; } public boolean remove(Object element) { return element instanceof Provider && - customProviders.remove(element) && - customProviderURLs.remove(((Provider) element).getMainUrl().toString()); + customProviders.remove(((Provider) element).getMainUrlString()) != null; } public boolean addAll(Collection<? extends Provider> elements) { @@ -194,9 +171,11 @@ public class ProviderManager { boolean addedAll = true; while (iterator.hasNext()) { Provider p = (Provider) iterator.next(); - addedAll = customProviders.add(p) && - customProviderURLs.add(p.getMainUrl().toString()) && - addedAll; + boolean containsKey = customProviders.containsKey(p.getMainUrlString()); + if (!containsKey) { + customProviders.put(p.getMainUrlString(), p); + } + addedAll = !containsKey && addedAll; } return addedAll; } @@ -204,15 +183,8 @@ public class ProviderManager { public boolean removeAll(Collection<?> elements) { Iterator iterator = elements.iterator(); boolean removedAll = true; - try { - while (iterator.hasNext()) { - Provider p = (Provider) iterator.next(); - removedAll = ((defaultProviders.remove(p) && defaultProviderURLs.remove(p.getMainUrl().toString())) || - (customProviders.remove(p) && customProviderURLs.remove(p.getMainUrl().toString()))) && - removedAll; - } - } catch (ClassCastException e) { - return false; + while (iterator.hasNext()) { + removedAll = remove(iterator.next()) && removedAll; } return removedAll; @@ -221,37 +193,10 @@ public class ProviderManager { public void clear() { defaultProviders.clear(); customProviders.clear(); - customProviderURLs.clear(); defaultProviderURLs.clear(); } - void saveCustomProvidersToFile() { - try { - deleteLegacyCustomProviders(); - - for (Provider provider : customProviders) { - File providerFile = createFile(externalFilesDir, provider.getName() + EXT_JSON); - if (!providerFile.exists()) { - persistFile(providerFile, provider.toJson().toString()); - } - } - } catch (IOException | SecurityException e) { - e.printStackTrace(); - } - } - - /** - * Deletes persisted custom providers from from internal storage that are not in customProviders list anymore - */ - private void deleteLegacyCustomProviders() throws IOException, SecurityException { - Set<Provider> persistedCustomProviders = externalFilesDir != null && externalFilesDir.isDirectory() ? - customProvidersFromFiles(externalFilesDir.list()) : new HashSet<Provider>(); - persistedCustomProviders.removeAll(customProviders); - for (Provider providerToDelete : persistedCustomProviders) { - File providerFile = createFile(externalFilesDir, providerToDelete.getName() + EXT_JSON); - if (providerFile.exists()) { - providerFile.delete(); - } - } + public void saveCustomProviders() { + PreferenceHelper.setCustomProviders(new HashSet<>(customProviders.values())); } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java index cdb8bd78..58fccc65 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/CircumventionSetupFragment.java @@ -78,8 +78,7 @@ public class CircumventionSetupFragment extends BaseSetupFragment implements Can } private void loadProviderFromAssets() { - ProviderManager providerManager = ProviderManager.getInstance(getContext().getApplicationContext().getAssets(), - getContext().getExternalFilesDir(null)); + ProviderManager providerManager = ProviderManager.getInstance(getContext().getApplicationContext().getAssets()); providerManager.setAddDummyEntry(false); setupActivityCallback.onProviderSelected(providerManager.providers().get(0)); } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java index e8f37e43..f15aaa43 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ProviderSelectionFragment.java @@ -2,7 +2,6 @@ package se.leap.bitmaskclient.providersetup.fragments; import static se.leap.bitmaskclient.providersetup.fragments.viewmodel.ProviderSelectionViewModel.ADD_PROVIDER; -import android.content.Context; import android.graphics.Typeface; import android.os.Bundle; import android.text.Editable; @@ -20,7 +19,6 @@ import java.util.ArrayList; import se.leap.bitmaskclient.R; import se.leap.bitmaskclient.base.models.Provider; -import se.leap.bitmaskclient.base.models.ProviderObservable; import se.leap.bitmaskclient.base.utils.ViewHelper; import se.leap.bitmaskclient.databinding.FProviderSelectionBinding; import se.leap.bitmaskclient.providersetup.activities.CancelCallback; @@ -46,8 +44,7 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this, new ProviderSelectionViewModelFactory( - getContext().getApplicationContext().getAssets(), - getContext().getExternalFilesDir(null))). + getContext().getApplicationContext().getAssets())). get(ProviderSelectionViewModel.class); } @@ -110,7 +107,7 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc if (viewModel.isCustomProviderSelected()) { setupActivityCallback.onSetupStepValidationChanged(viewModel.isValidConfig()); if (viewModel.isValidConfig()) { - setupActivityCallback.onProviderSelected(new Provider(s.toString())); + setupActivityCallback.onProviderSelected(new Provider(viewModel.getCustomUrl())); } } } @@ -124,6 +121,12 @@ public class ProviderSelectionFragment extends BaseSetupFragment implements Canc ViewHelper.hideKeyboardFrom(getContext(), v); } }); + + binding.getRoot().getViewTreeObserver().addOnGlobalLayoutListener(() -> { + if(ViewHelper.isKeyboardShown(getContext())) { + binding.getRoot().smoothScrollTo(binding.editCustomProvider.getLeft(), binding.getRoot().getBottom()); + } + }); binding.providerRadioGroup.check(viewModel.getSelected()); } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModel.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModel.java index aa2fe7cb..29dab98a 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModel.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModel.java @@ -8,7 +8,6 @@ import android.webkit.URLUtil; import androidx.lifecycle.ViewModel; -import java.io.File; import java.util.List; import se.leap.bitmaskclient.R; @@ -22,8 +21,8 @@ public class ProviderSelectionViewModel extends ViewModel { private int selected = 0; private String customUrl; - public ProviderSelectionViewModel(AssetManager assetManager, File externalFilesDir) { - providerManager = ProviderManager.getInstance(assetManager, externalFilesDir); + public ProviderSelectionViewModel(AssetManager assetManager) { + providerManager = ProviderManager.getInstance(assetManager); providerManager.setAddDummyEntry(false); } @@ -49,7 +48,7 @@ public class ProviderSelectionViewModel extends ViewModel { public boolean isValidConfig() { if (selected == ADD_PROVIDER) { - return URLUtil.isValidUrl(customUrl) && Patterns.WEB_URL.matcher(customUrl).matches(); + return customUrl != null && (Patterns.DOMAIN_NAME.matcher(customUrl).matches() || (URLUtil.isNetworkUrl(customUrl) && Patterns.WEB_URL.matcher(customUrl).matches())); } return true; } @@ -83,6 +82,13 @@ public class ProviderSelectionViewModel extends ViewModel { customUrl = url; } + public String getCustomUrl() { + if (customUrl != null && Patterns.DOMAIN_NAME.matcher(customUrl).matches()) { + return "https://" + customUrl; + } + return customUrl; + } + public String getProviderName(int pos) { String domain = getProvider(pos).getDomain(); diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModelFactory.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModelFactory.java index a21e4924..f6d86e07 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModelFactory.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/viewmodel/ProviderSelectionViewModelFactory.java @@ -6,22 +6,18 @@ import androidx.annotation.NonNull; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; -import java.io.File; - public class ProviderSelectionViewModelFactory implements ViewModelProvider.Factory { private final AssetManager assetManager; - private final File externalFilesDir; - public ProviderSelectionViewModelFactory(AssetManager assetManager, File externalFilesDir) { + public ProviderSelectionViewModelFactory(AssetManager assetManager) { this.assetManager = assetManager; - this.externalFilesDir = externalFilesDir; } @NonNull @Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { if (modelClass.isAssignableFrom(ProviderSelectionViewModel.class)) { - return (T) new ProviderSelectionViewModel(assetManager, externalFilesDir); + return (T) new ProviderSelectionViewModel(assetManager); } throw new IllegalArgumentException("Unknown ViewModel class"); } |