summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcyBerta <cyberta@riseup.net>2023-10-25 14:54:41 +0200
committercyBerta <cyberta@riseup.net>2023-10-25 14:54:41 +0200
commitb2956073c6f0770347ec71bdc592b74426fddf2a (patch)
tree35cd853c8653909f13114d8c6eb368527aa044e8
parent6d7a966b39a8a1208d67981e726c63d02efd4f4a (diff)
always show provider setup progress in percentage, combine tor bootstrap progress and provider api communication progress in case circumvention is needed
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java5
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java2
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java6
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupObservable.java103
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivity.java3
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java25
-rw-r--r--app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java7
7 files changed, 143 insertions, 8 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 a66f75d7..0fa62285 100644
--- a/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java
+++ b/app/src/main/java/se/leap/bitmaskclient/base/BitmaskApp.java
@@ -26,7 +26,6 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.isCalyxOSWithTetheri
import static se.leap.bitmaskclient.base.utils.PreferenceHelper.getSavedProviderFromSharedPreferences;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -42,6 +41,7 @@ import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.PRNGFixes;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.eip.EipSetupObserver;
+import se.leap.bitmaskclient.providersetup.ProviderSetupObservable;
import se.leap.bitmaskclient.tethering.TetheringStateManager;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -56,6 +56,8 @@ public class BitmaskApp extends MultiDexApplication {
private DownloadBroadcastReceiver downloadBroadcastReceiver;
private TorStatusObservable torStatusObservable;
+ private ProviderSetupObservable providerSetupObservable;
+
private PreferenceHelper preferenceHelper;
@@ -69,6 +71,7 @@ public class BitmaskApp extends MultiDexApplication {
providerObservable = ProviderObservable.getInstance();
providerObservable.updateProvider(getSavedProviderFromSharedPreferences());
torStatusObservable = TorStatusObservable.getInstance();
+ providerSetupObservable = ProviderSetupObservable.getInstance();
EipSetupObserver.init(this);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
if (!isCalyxOSWithTetheringSupport(this)) {
diff --git a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
index ed83770b..c8b8bea4 100644
--- a/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
+++ b/app/src/main/java/se/leap/bitmaskclient/eip/EipSetupObserver.java
@@ -79,6 +79,7 @@ import se.leap.bitmaskclient.base.models.ProviderObservable;
import se.leap.bitmaskclient.base.utils.PreferenceHelper;
import se.leap.bitmaskclient.providersetup.ProviderAPI;
import se.leap.bitmaskclient.providersetup.ProviderAPICommand;
+import se.leap.bitmaskclient.providersetup.ProviderSetupObservable;
import se.leap.bitmaskclient.tor.TorServiceCommand;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -177,6 +178,7 @@ public class EipSetupObserver extends BroadcastReceiver implements VpnStatus.Sta
Integer bootstrap = intent.getIntExtra(TorService.EXTRA_STATUS_DETAIL_BOOTSTRAP, -1);
String logKey = intent.getStringExtra(TorService.EXTRA_STATUS_DETAIL_LOGKEY);
TorStatusObservable.updateState(appContext, status, bootstrap, logKey);
+ ProviderSetupObservable.updateTorSetupProgress();
}
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 9468f76e..93648bb0 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderApiManagerBase.java
@@ -96,6 +96,8 @@ import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWN
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_INVALID_CERTIFICATE;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_TOR_TIMEOUT;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_GEOIP_JSON;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_VPN_CERTIFICATE;
import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF;
import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.ON;
import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort;
@@ -256,6 +258,9 @@ public abstract class ProviderApiManagerBase {
result = setUpProvider(provider, parameters);
if (result.getBoolean(BROADCAST_RESULT_KEY)) {
getGeoIPJson(provider);
+ if (provider.hasGeoIpJson()) {
+ ProviderSetupObservable.updateProgress(DOWNLOADED_GEOIP_JSON);
+ }
sendToReceiverOrBroadcast(receiver, PROVIDER_OK, result, provider);
} else {
sendToReceiverOrBroadcast(receiver, PROVIDER_NOK, result, provider);
@@ -289,6 +294,7 @@ public abstract class ProviderApiManagerBase {
ProviderObservable.getInstance().setProviderForDns(provider);
result = updateVpnCertificate(provider);
if (result.getBoolean(BROADCAST_RESULT_KEY)) {
+ ProviderSetupObservable.updateProgress(DOWNLOADED_VPN_CERTIFICATE);
sendToReceiverOrBroadcast(receiver, CORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider);
} else {
sendToReceiverOrBroadcast(receiver, INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE, result, provider);
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupObservable.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupObservable.java
new file mode 100644
index 00000000..56ef357b
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/ProviderSetupObservable.java
@@ -0,0 +1,103 @@
+package se.leap.bitmaskclient.providersetup;
+/**
+ * Copyright (c) 2023 LEAP Encryption Access Project and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.Observable;
+
+import se.leap.bitmaskclient.tor.TorStatusObservable;
+
+public class ProviderSetupObservable extends Observable {
+
+ private static final String TAG = ProviderSetupObservable.class.getSimpleName();
+
+ private int progress = 0;
+ private boolean canceled = false;
+ public static final int DOWNLOADED_PROVIDER_JSON = 20;
+ public static final int DOWNLOADED_CA_CERT = 40;
+ public static final int DOWNLOADED_EIP_SERVICE_JSON = 60;
+ public static final int DOWNLOADED_GEOIP_JSON = 80;
+ public static final int DOWNLOADED_VPN_CERTIFICATE = 100;
+
+ private static ProviderSetupObservable instance;
+ private final Handler handler = new Handler(Looper.getMainLooper());
+ private long lastUpdate = 0;
+
+ public static ProviderSetupObservable getInstance() {
+ if (instance == null) {
+ instance = new ProviderSetupObservable();
+ }
+ return instance;
+ }
+
+ public static void updateProgress(int progress) {
+ if (instance.canceled) {
+ return;
+ }
+ long now = System.currentTimeMillis();
+ getInstance().handler.postDelayed(() -> {
+ if (TorStatusObservable.isRunning()) {
+ getInstance().progress = (TorStatusObservable.getBootstrapProgress() + progress) / 2;
+ } else {
+ getInstance().progress = progress;
+ }
+
+ getInstance().setChanged();
+ getInstance().notifyObservers();
+ }, now - getInstance().lastUpdate < 500L ? 500L : 0L);
+ getInstance().lastUpdate = System.currentTimeMillis() + 500;
+ }
+
+ public static void updateTorSetupProgress() {
+ if (!TorStatusObservable.isRunning() || getInstance().canceled) {
+ return;
+ }
+ long now = System.currentTimeMillis();
+ getInstance().handler.postDelayed(() -> {
+ getInstance().progress = (TorStatusObservable.getBootstrapProgress()) / 2;
+
+ getInstance().setChanged();
+ getInstance().notifyObservers();
+ }, now - getInstance().lastUpdate < 500L ? 500L : 0);
+ getInstance().lastUpdate = System.currentTimeMillis() + 500;
+ }
+
+ public static int getProgress() {
+ return getInstance().progress;
+ }
+
+ public static void reset() {
+ getInstance().progress = 0;
+ getInstance().setChanged();
+ getInstance().notifyObservers();
+ }
+
+ public static void cancel() {
+ getInstance().canceled = true;
+ reset();
+ }
+
+ public static boolean isCanceled() {
+ return getInstance().canceled;
+ }
+
+ public static void startSetup() {
+ getInstance().canceled = false;
+ }
+}
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivity.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivity.java
index 724543e4..b258a100 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivity.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivity.java
@@ -48,6 +48,7 @@ import se.leap.bitmaskclient.base.utils.ViewHelper;
import se.leap.bitmaskclient.base.views.ActionBarTitle;
import se.leap.bitmaskclient.databinding.ActivitySetupBinding;
import se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog;
+import se.leap.bitmaskclient.providersetup.ProviderSetupObservable;
import se.leap.bitmaskclient.providersetup.SetupViewPagerAdapter;
import se.leap.bitmaskclient.tor.TorServiceCommand;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -166,6 +167,7 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal
private void cancel() {
binding.viewPager.setCurrentItem(0, false);
+ ProviderSetupObservable.cancel();
if (TorStatusObservable.getStatus() != OFF) {
Log.d(TAG, "SHUTDOWN - cancelSettingUpProvider");
TorServiceCommand.stopTorServiceAsync(this);
@@ -287,6 +289,7 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal
@Override
public void onSetupFinished() {
+ ProviderSetupObservable.reset();
Intent intent = getIntent();
if (provider == null && ProviderObservable.getInstance().getCurrentProvider().isConfigured()) {
// only permissions were requested, no new provider configured, so reuse previously configured one
diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java
index 26eb5f4c..ec646cac 100644
--- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java
+++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/ConfigureProviderFragment.java
@@ -22,7 +22,6 @@ import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_OK;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.SET_UP_PROVIDER;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_EXCEPTION;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.TOR_TIMEOUT;
-import static se.leap.bitmaskclient.tor.TorStatusObservable.getBootstrapProgress;
import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastLogs;
import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastSnowflakeLog;
import static se.leap.bitmaskclient.tor.TorStatusObservable.getLastTorLog;
@@ -31,6 +30,8 @@ import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -51,6 +52,7 @@ import se.leap.bitmaskclient.databinding.FConfigureProviderBinding;
import se.leap.bitmaskclient.eip.EipSetupListener;
import se.leap.bitmaskclient.eip.EipSetupObserver;
import se.leap.bitmaskclient.providersetup.ProviderAPICommand;
+import se.leap.bitmaskclient.providersetup.ProviderSetupObservable;
import se.leap.bitmaskclient.providersetup.TorLogAdapter;
import se.leap.bitmaskclient.providersetup.activities.CancelCallback;
import se.leap.bitmaskclient.tor.TorStatusObservable;
@@ -64,6 +66,8 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
private boolean ignoreProviderAPIUpdates = false;
private TorLogAdapter torLogAdapter;
+ private Handler handler = new Handler(Looper.getMainLooper());
+
public static ConfigureProviderFragment newInstance(int position) {
ConfigureProviderFragment fragment = new ConfigureProviderFragment();
@@ -101,14 +105,14 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setupActivityCallback.registerCancelCallback(this);
- TorStatusObservable.getInstance().addObserver(this);
+ ProviderSetupObservable.getInstance().addObserver(this);
EipSetupObserver.addListener(this);
}
@Override
public void onDestroyView() {
setupActivityCallback.removeCancelCallback(this);
- TorStatusObservable.getInstance().deleteObserver(this);
+ ProviderSetupObservable.getInstance().deleteObserver(this);
EipSetupObserver.removeListener(this);
binding = null;
super.onDestroyView();
@@ -124,8 +128,10 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.setup_progress_spinner, null);
binding.progressSpinner.setAnimatedSpinnerDrawable(drawable);
}
+ binding.progressSpinner.update(ProviderSetupObservable.getProgress());
setupActivityCallback.setNavigationButtonHidden(true);
setupActivityCallback.setCancelButtonHidden(false);
+ ProviderSetupObservable.startSetup();
ProviderAPICommand.execute(getContext(), SET_UP_PROVIDER, setupActivityCallback.getSelectedProvider());
}
@@ -153,7 +159,7 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
@Override
public void update(Observable o, Object arg) {
- if (o instanceof TorStatusObservable) {
+ if (o instanceof ProviderSetupObservable) {
Activity activity = getActivity();
if (activity == null || binding == null) {
return;
@@ -170,7 +176,7 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
}
}
binding.tvProgressStatus.setText(TorStatusObservable.getStringForCurrentStatus(activity));
- binding.progressSpinner.update(getBootstrapProgress());
+ binding.progressSpinner.update(ProviderSetupObservable.getProgress());
});
}
}
@@ -199,7 +205,8 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
Provider provider = resultData.getParcelable(PROVIDER_KEY);
if (ignoreProviderAPIUpdates ||
provider == null ||
- !setupActivityCallback.getSelectedProvider().getDomain().equals(provider.getDomain())) {
+ (setupActivityCallback.getSelectedProvider() != null &&
+ !setupActivityCallback.getSelectedProvider().getDomain().equals(provider.getDomain()))) {
return;
}
@@ -213,7 +220,11 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse
break;
case CORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
setupActivityCallback.onProviderSelected(provider);
- setupActivityCallback.onConfigurationSuccess();
+ handler.postDelayed(() -> {
+ if (!ProviderSetupObservable.isCanceled()) {
+ setupActivityCallback.onConfigurationSuccess();
+ }
+ }, 750);
break;
case PROVIDER_NOK:
case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE:
diff --git a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
index 59b9159c..b08f27ef 100644
--- a/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
+++ b/app/src/production/java/se/leap/bitmaskclient/providersetup/ProviderApiManager.java
@@ -34,6 +34,9 @@ import static se.leap.bitmaskclient.base.utils.ConfigHelper.isDefaultBitmask;
import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CERTIFICATE_PINNING;
import static se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog.DOWNLOAD_ERRORS.ERROR_CORRUPTED_PROVIDER_JSON;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_CA_CERT;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_EIP_SERVICE_JSON;
+import static se.leap.bitmaskclient.providersetup.ProviderSetupObservable.DOWNLOADED_PROVIDER_JSON;
import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF;
import static se.leap.bitmaskclient.tor.TorStatusObservable.getProxyPort;
@@ -112,15 +115,19 @@ public class ProviderApiManager extends ProviderApiManagerBase {
currentDownload = getAndSetProviderJson(provider);
if (provider.hasDefinition() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ ProviderSetupObservable.updateProgress(DOWNLOADED_PROVIDER_JSON);
if (!provider.hasCaCert()) {
currentDownload = downloadCACert(provider);
}
if (provider.hasCaCert() || (currentDownload.containsKey(BROADCAST_RESULT_KEY) && currentDownload.getBoolean(BROADCAST_RESULT_KEY))) {
+ ProviderSetupObservable.updateProgress(DOWNLOADED_CA_CERT);
currentDownload = getAndSetEipServiceJson(provider);
}
if (provider.hasEIP() && !provider.allowsRegistered() && !provider.allowsAnonymous()) {
setErrorResult(currentDownload, isDefaultBitmask() ? setup_error_text : setup_error_text_custom, null);
+ } else if (provider.hasEIP()) {
+ ProviderSetupObservable.updateProgress(DOWNLOADED_EIP_SERVICE_JSON);
}
}