diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ProxyValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ProxyValues.java index d45c2881cc..160e31aec0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ProxyValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ProxyValues.java @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.keyvalue; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.internal.configuration.SignalProxy; public final class ProxyValues extends SignalStoreValues { @@ -19,8 +20,11 @@ public final class ProxyValues extends SignalStoreValues { void onFirstEverAppLaunch() { } - public void enableProxy(@NonNull SignalProxy proxy) { + if (Util.isEmpty(proxy.getHost())) { + throw new IllegalArgumentException("Empty host!"); + } + getStore().beginWrite() .putBoolean(KEY_PROXY_ENABLED, true) .putString(KEY_HOST, proxy.getHost()) @@ -67,4 +71,9 @@ public final class ProxyValues extends SignalStoreValues { return null; } } + + public @Nullable String getProxyHost() { + SignalProxy proxy = getProxy(); + return proxy != null ? proxy.getHost() : null; + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyFragment.java index dc150f5cef..ffdea7d6d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyFragment.java @@ -20,9 +20,12 @@ import androidx.lifecycle.ViewModelProviders; import com.dd.CircularProgressButton; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher; import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.net.PipeConnectivityListener; import org.thoughtcrime.securesms.util.SignalProxyUtil; +import org.thoughtcrime.securesms.util.Util; +import org.thoughtcrime.securesms.util.ViewUtil; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.internal.configuration.SignalProxy; @@ -54,6 +57,13 @@ public class EditProxyFragment extends Fragment { this.saveButton = view.findViewById(R.id.edit_proxy_save); this.shareButton = view.findViewById(R.id.edit_proxy_share); + proxyText.addTextChangedListener(new SimpleTextWatcher() { + @Override + public void onTextChanged(String text) { + onProxyTextChanged(text); + } + }); + this.proxyText.setText(Optional.fromNullable(SignalStore.proxy().getProxy()).transform(SignalProxy::getHost).or("")); this.proxySwitch.setChecked(SignalStore.proxy().isProxyEnabled()); @@ -87,12 +97,8 @@ public class EditProxyFragment extends Fragment { case ALL_ENABLED: proxyText.setEnabled(true); proxyText.setAlpha(1); - saveButton.setEnabled(true); - saveButton.setAlpha(1); - shareButton.setEnabled(true); - shareButton.setAlpha(1); proxyTitle.setAlpha(1); - proxyStatus.setVisibility(View.VISIBLE); + onProxyTextChanged(proxyText.getText().toString()); break; case ALL_DISABLED: proxyText.setEnabled(false); @@ -137,12 +143,16 @@ public class EditProxyFragment extends Fragment { new AlertDialog.Builder(requireContext()) .setTitle(R.string.preferences_success) .setMessage(R.string.preferences_you_are_connected_to_the_proxy) - .setPositiveButton(android.R.string.ok, (d, i) -> d.dismiss()) + .setPositiveButton(android.R.string.ok, (d, i) -> { + d.dismiss(); + requireActivity().onBackPressed(); + }) .show(); break; case PROXY_FAILURE: proxyStatus.setVisibility(View.INVISIBLE); proxyText.setText(Optional.fromNullable(SignalStore.proxy().getProxy()).transform(SignalProxy::getHost).or("")); + ViewUtil.focusAndMoveCursorToEndAndOpenKeyboard(proxyText); new AlertDialog.Builder(requireContext()) .setTitle(R.string.preferences_failed_to_connect) .setMessage(R.string.preferences_couldnt_connect_to_the_proxy) @@ -172,10 +182,32 @@ public class EditProxyFragment extends Fragment { } private void onShareClicked() { - String host = proxyText.getText().toString(); + String link = SignalProxyUtil.generateProxyUrl(proxyText.getText().toString()); ShareCompat.IntentBuilder.from(requireActivity()) - .setText(host) + .setText(link) .setType("text/plain") .startChooser(); } + + private void onProxyTextChanged(@NonNull String text) { + if (Util.isEmpty(text)) { + saveButton.setEnabled(false); + saveButton.setAlpha(0.5f); + shareButton.setEnabled(false); + shareButton.setAlpha(0.5f); + proxyStatus.setVisibility(View.INVISIBLE); + } else { + saveButton.setEnabled(true); + saveButton.setAlpha(1); + shareButton.setEnabled(true); + shareButton.setAlpha(1); + + String trueHost = SignalProxyUtil.convertUserEnteredAddressToHost(proxyText.getText().toString()); + if (SignalStore.proxy().isProxyEnabled() && trueHost.equals(SignalStore.proxy().getProxyHost())) { + proxyStatus.setVisibility(View.VISIBLE); + } else { + proxyStatus.setVisibility(View.INVISIBLE); + } + } + } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyViewModel.java index f198144f65..98f5c1a3d0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/EditProxyViewModel.java @@ -12,6 +12,7 @@ import org.thoughtcrime.securesms.net.PipeConnectivityListener; import org.thoughtcrime.securesms.util.SignalProxyUtil; import org.thoughtcrime.securesms.util.SingleLiveEvent; import org.thoughtcrime.securesms.util.TextSecurePreferences; +import org.thoughtcrime.securesms.util.Util; import org.whispersystems.signalservice.internal.configuration.SignalProxy; import java.util.concurrent.TimeUnit; @@ -41,7 +42,7 @@ public class EditProxyViewModel extends ViewModel { if (enabled) { SignalProxy currentProxy = SignalStore.proxy().getProxy(); - if (currentProxy != null) { + if (currentProxy != null && !Util.isEmpty(currentProxy.getHost())) { SignalProxyUtil.enableProxy(currentProxy); } uiState.postValue(UiState.ALL_ENABLED); @@ -52,8 +53,7 @@ public class EditProxyViewModel extends ViewModel { } public void onSaveClicked(@NonNull String host) { - String parsedHost = SignalProxyUtil.parseHostFromProxyLink(host); - String trueHost = parsedHost != null ? parsedHost : host; + String trueHost = SignalProxyUtil.convertUserEnteredAddressToHost(host); saveState.postValue(SaveState.IN_PROGRESS); diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java index 2b580b790b..dd62cb00d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java @@ -243,7 +243,9 @@ public class SignalServiceNetworkAccess { } public SignalServiceConfiguration getConfiguration(@Nullable String localNumber) { - if (localNumber == null) return this.uncensoredConfiguration; + if (localNumber == null || SignalStore.proxy().isProxyEnabled()) { + return this.uncensoredConfiguration; + } if (SignalStore.internalValues().forcedCensorship()) { return this.censorshipConfiguration.get(COUNTRY_CODE_QATAR); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java index 992da00341..e876785628 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/CommunicationActions.java @@ -213,7 +213,7 @@ public class CommunicationActions { * Otherwise returns false, indicating was not a proxy link. */ public static boolean handlePotentialProxyLinkUrl(@NonNull FragmentActivity activity, @NonNull String potentialProxyLinkUrl) { - String proxy = SignalProxyUtil.parseHostFromProxyLink(potentialProxyLinkUrl); + String proxy = SignalProxyUtil.parseHostFromProxyDeepLink(potentialProxyLinkUrl); if (proxy != null) { ProxyBottomSheetFragment.showForProxy(activity.getSupportFragmentManager(), proxy); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SignalProxyUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/SignalProxyUtil.java index 37e1cde09f..7351677264 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SignalProxyUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SignalProxyUtil.java @@ -100,10 +100,10 @@ public final class SignalProxyUtil { } /** - * If this is a valid proxy link, this will return the embedded host. If not, it will return + * If this is a valid proxy deep link, this will return the embedded host. If not, it will return * null. */ - public static @Nullable String parseHostFromProxyLink(@NonNull String proxyLink) { + public static @Nullable String parseHostFromProxyDeepLink(@NonNull String proxyLink) { try { URI uri = new URI(proxyLink); @@ -130,4 +130,24 @@ public final class SignalProxyUtil { return null; } } + + /** + * Takes in an address that could be in various formats, and converts it to the format we should + * be storing and connecting to. + */ + public static @NonNull String convertUserEnteredAddressToHost(@NonNull String host) { + String parsedHost = SignalProxyUtil.parseHostFromProxyDeepLink(host); + return parsedHost != null ? parsedHost : host; + } + + public static @NonNull String generateProxyUrl(@NonNull String link) { + String host = link; + String parsed = parseHostFromProxyDeepLink(link); + + if (parsed != null) { + host = parsed; + } + + return "https://" + PROXY_LINK_HOST + "/#" + host; + } } diff --git a/app/src/main/res/layout/edit_proxy_fragment.xml b/app/src/main/res/layout/edit_proxy_fragment.xml index b64d23b472..cdc257bd5f 100644 --- a/app/src/main/res/layout/edit_proxy_fragment.xml +++ b/app/src/main/res/layout/edit_proxy_fragment.xml @@ -40,6 +40,8 @@ android:id="@+id/edit_proxy_host" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginStart="-2dp" + android:hint="@string/preferences_enter_proxy_address" app:layout_constraintTop_toBottomOf="@id/edit_proxy_address_title" tools:hint="https://proxy.parker.org"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1364b2c2fb..7f4374d565 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2325,6 +2325,7 @@ You are connected to the proxy. You can turn the proxy off at any time from Settings. Success Failed to connect + Enter proxy address Customize option