From 5ceaf7c7a2fc847c52b1764725ceabacd708a15a Mon Sep 17 00:00:00 2001 From: cyBerta Date: Thu, 3 Aug 2023 15:55:24 +0200 Subject: show error dialogs if provider setup fails --- .../providersetup/SetupViewPagerAdapter.java | 4 + .../providersetup/activities/SetupActivity.java | 103 +++++++++++++++++---- .../activities/SetupActivityCallback.java | 2 + .../fragments/ConfigureProviderFragment.java | 38 ++++++-- .../fragments/SetupFragmentFactory.java | 4 + 5 files changed, 122 insertions(+), 29 deletions(-) (limited to 'app/src/main') diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/SetupViewPagerAdapter.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/SetupViewPagerAdapter.java index 3f585c35..39122572 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/SetupViewPagerAdapter.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/SetupViewPagerAdapter.java @@ -54,5 +54,9 @@ public class SetupViewPagerAdapter extends FragmentStateAdapter { return setupFragmentFactory.getItemCount(); } + public int getFragmentPostion(int fragmentType) { + return setupFragmentFactory.getPos(fragmentType); + } + } 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 3e91795b..e7a1d4e2 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 @@ -3,16 +3,10 @@ package se.leap.bitmaskclient.providersetup.activities; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static androidx.appcompat.app.ActionBar.DISPLAY_SHOW_CUSTOM; - -import static se.leap.bitmaskclient.base.models.Constants.REQUEST_CODE_CONFIGURE_LEAP; +import static se.leap.bitmaskclient.base.utils.PreferenceHelper.deleteProviderDetailsFromPreferences; +import static se.leap.bitmaskclient.providersetup.fragments.SetupFragmentFactory.CONFIGURE_PROVIDER_FRAGMENT; import static se.leap.bitmaskclient.tor.TorStatusObservable.TorStatus.OFF; -import androidx.annotation.ColorInt; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.content.ContextCompat; -import androidx.viewpager2.widget.ViewPager2; - import android.Manifest; import android.annotation.SuppressLint; import android.content.Context; @@ -27,24 +21,40 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Toast; +import androidx.annotation.ColorInt; +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentTransaction; +import androidx.viewpager2.widget.ViewPager2; + +import org.json.JSONException; +import org.json.JSONObject; + import java.util.ArrayList; import java.util.HashSet; import se.leap.bitmaskclient.BuildConfig; import se.leap.bitmaskclient.R; +import se.leap.bitmaskclient.base.FragmentManagerEnhanced; import se.leap.bitmaskclient.base.models.Provider; import se.leap.bitmaskclient.base.views.ActionBarTitle; import se.leap.bitmaskclient.databinding.ActivitySetupBinding; +import se.leap.bitmaskclient.providersetup.ProviderSetupFailedDialog; import se.leap.bitmaskclient.providersetup.SetupViewPagerAdapter; import se.leap.bitmaskclient.tor.TorServiceCommand; import se.leap.bitmaskclient.tor.TorStatusObservable; -public class SetupActivity extends AppCompatActivity implements SetupActivityCallback { +public class SetupActivity extends AppCompatActivity implements SetupActivityCallback, ProviderSetupFailedDialog.DownloadFailedDialogInterface { private static final String TAG = SetupActivity.class.getSimpleName(); ActivitySetupBinding binding; Provider provider; private final HashSet cancelCallbacks = new HashSet<>(); + private FragmentManagerEnhanced fragmentManager; + SetupViewPagerAdapter adapter; @SuppressLint("ClickableViewAccessibility") @Override @@ -52,6 +62,7 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal super.onCreate(savedInstanceState); binding = ActivitySetupBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + fragmentManager = new FragmentManagerEnhanced(getSupportFragmentManager()); ArrayList indicatorViews = new ArrayList<>(); for (int i = 0; i < 4; i++) { @@ -75,7 +86,7 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal } } - SetupViewPagerAdapter adapter = new SetupViewPagerAdapter(getSupportFragmentManager(), getLifecycle(), requestVpnPermission, showNotificationPermissionFragments); + adapter = new SetupViewPagerAdapter(getSupportFragmentManager(), getLifecycle(), requestVpnPermission, showNotificationPermissionFragments); binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override @@ -100,20 +111,24 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal binding.viewPager.setCurrentItem(newPos); }); binding.setupCancelButton.setOnClickListener(v -> { - binding.viewPager.setCurrentItem(0, false); - if (TorStatusObservable.getStatus() != OFF) { - Log.d(TAG, "SHUTDOWN - cancelSettingUpProvider"); - TorServiceCommand.stopTorServiceAsync(this); - } - provider = null; - for (CancelCallback cancelCallback : cancelCallbacks) { - cancelCallback.onCanceled(); - } + cancel(); }); setupActionBar(); } + private void cancel() { + binding.viewPager.setCurrentItem(0, false); + if (TorStatusObservable.getStatus() != OFF) { + Log.d(TAG, "SHUTDOWN - cancelSettingUpProvider"); + TorServiceCommand.stopTorServiceAsync(this); + } + provider = null; + for (CancelCallback cancelCallback : cancelCallbacks) { + cancelCallback.onCanceled(); + } + } + private void addIndicatorView(ArrayList indicatorViews) { // FIXME: we have to work around a bug in our usage of CardView, that // doesn't let us programmatically add new indicator views as needed. @@ -216,4 +231,54 @@ public class SetupActivity extends AppCompatActivity implements SetupActivityCal finish(); } + @Override + public void onError(String reasonToFail) { + binding.viewPager.setCurrentItem(0, false); + try { + FragmentTransaction fragmentTransaction = fragmentManager.removePreviousFragment(ProviderSetupFailedDialog.TAG); + DialogFragment newFragment; + try { + JSONObject errorJson = new JSONObject(reasonToFail); + newFragment = ProviderSetupFailedDialog.newInstance(provider, errorJson, false); + } catch (JSONException e) { + e.printStackTrace(); + newFragment = ProviderSetupFailedDialog.newInstance(provider, reasonToFail); + } catch (NullPointerException e) { + //reasonToFail was null + return; + } + newFragment.show(fragmentTransaction, ProviderSetupFailedDialog.TAG); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + } + + @Override + public void retrySetUpProvider(@NonNull Provider provider) { + onProviderSelected(provider); + binding.viewPager.setCurrentItem(adapter.getFragmentPostion(CONFIGURE_PROVIDER_FRAGMENT)); + } + + @Override + public void cancelSettingUpProvider() { + cancel(); + } + + @Override + public void updateProviderDetails() { + provider.reset(); + deleteProviderDetailsFromPreferences(provider.getDomain()); + binding.viewPager.setCurrentItem(adapter.getFragmentPostion(CONFIGURE_PROVIDER_FRAGMENT)); + } + + @Override + public void addAndSelectNewProvider(String url) { + // ignore, not implemented anymore in new setup flow + } + + @Override + protected void onDestroy() { + super.onDestroy(); + adapter = null; + } } \ No newline at end of file diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivityCallback.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivityCallback.java index 3906d73a..2c77dfd0 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivityCallback.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/activities/SetupActivityCallback.java @@ -27,5 +27,7 @@ public interface SetupActivityCallback { int getCurrentPosition(); void onSetupFinished(); + + void onError(String reasonToFail); } 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 26f62042..8475108f 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 @@ -10,8 +10,14 @@ import static se.leap.bitmaskclient.base.models.Constants.PROVIDER_KEY; import static se.leap.bitmaskclient.base.utils.ViewHelper.animateContainerVisibility; import static se.leap.bitmaskclient.providersetup.ProviderAPI.CORRECTLY_DOWNLOADED_VPN_CERTIFICATE; import static se.leap.bitmaskclient.providersetup.ProviderAPI.DOWNLOAD_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.ERRORS; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.MISSING_NETWORK_CONNECTION; +import static se.leap.bitmaskclient.providersetup.ProviderAPI.PROVIDER_NOK; 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; @@ -191,16 +197,28 @@ public class ConfigureProviderFragment extends BaseSetupFragment implements Obse !setupActivityCallback.getSelectedProvider().getDomain().equals(provider.getDomain())) { return; } - if (resultCode == PROVIDER_OK) { - setupActivityCallback.onProviderSelected(provider); - if (provider.allowsAnonymous()) { - ProviderAPICommand.execute(this.getContext(), DOWNLOAD_VPN_CERTIFICATE, provider); - } else { - // TODO: implement error message that this client only supports anonymous usage - } - } else if (resultCode == CORRECTLY_DOWNLOADED_VPN_CERTIFICATE) { - setupActivityCallback.onProviderSelected(provider); - setupActivityCallback.onConfigurationSuccess(); + + switch (resultCode) { + case PROVIDER_OK: + if (provider.allowsAnonymous()) { + ProviderAPICommand.execute(this.getContext(), DOWNLOAD_VPN_CERTIFICATE, provider); + } else { + // TODO: implement error message that this client only supports anonymous usage + } + break; + case CORRECTLY_DOWNLOADED_VPN_CERTIFICATE: + setupActivityCallback.onProviderSelected(provider); + setupActivityCallback.onConfigurationSuccess(); + break; + case PROVIDER_NOK: + case INCORRECTLY_DOWNLOADED_VPN_CERTIFICATE: + case MISSING_NETWORK_CONNECTION: + case TOR_EXCEPTION: + case TOR_TIMEOUT: + String reasonToFail = resultData.getString(ERRORS); + setupActivityCallback.onError(reasonToFail); + break; + } } diff --git a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/SetupFragmentFactory.java b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/SetupFragmentFactory.java index fd76a841..eaf3fbfa 100644 --- a/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/SetupFragmentFactory.java +++ b/app/src/main/java/se/leap/bitmaskclient/providersetup/fragments/SetupFragmentFactory.java @@ -58,4 +58,8 @@ public class SetupFragmentFactory { public int getItemCount() { return fragmentTypes.size(); } + + public int getPos(int fragmentType) { + return fragmentTypes.indexOf(fragmentType); + } } -- cgit v1.2.3