From 7ab1fe53f9e91388471967500029fe5c976b7294 Mon Sep 17 00:00:00 2001 From: tmgrask Date: Wed, 18 Feb 2026 09:51:10 -0500 Subject: [PATCH 1/7] Add personal pairing flow with soft-timeout fallback on next-release --- app/src/main/AndroidManifest.xml | 57 +- .../java/com/psiphon3/HomeTabFragment.java | 11 +- .../main/java/com/psiphon3/MainActivity.java | 373 ++++++++++-- .../com/psiphon3/MainActivityViewModel.java | 59 ++ .../java/com/psiphon3/OptionsTabFragment.java | 56 ++ .../main/java/com/psiphon3/TunnelState.java | 7 +- .../psiphonlibrary/PersonalPairingHelper.java | 547 ++++++++++++++++++ .../PersonalPairingPreferenceActivity.java | 288 +++++++++ .../psiphonlibrary/TunnelManager.java | 76 ++- .../TunnelServiceInteractor.java | 4 + .../notification_icon_connected_pp.png | Bin 0 -> 788 bytes .../notification_icon_connecting_pp_01.png | Bin 0 -> 1066 bytes .../notification_icon_connecting_pp_02.png | Bin 0 -> 1101 bytes .../notification_icon_connecting_pp_03.png | Bin 0 -> 1118 bytes .../notification_icon_connecting_pp_04.png | Bin 0 -> 1129 bytes .../notification_icon_connecting_pp_05.png | Bin 0 -> 1112 bytes .../notification_icon_connecting_pp_06.png | Bin 0 -> 1099 bytes .../drawable-hdpi/status_icon_connected.png | Bin 3971 -> 0 bytes .../drawable-hdpi/status_icon_connecting.png | Bin 5371 -> 0 bytes .../status_icon_disconnected.png | Bin 2265 -> 0 bytes .../notification_icon_connected_pp.png | Bin 0 -> 486 bytes .../notification_icon_connecting_pp_01.png | Bin 0 -> 739 bytes .../notification_icon_connecting_pp_02.png | Bin 0 -> 752 bytes .../notification_icon_connecting_pp_03.png | Bin 0 -> 762 bytes .../notification_icon_connecting_pp_04.png | Bin 0 -> 771 bytes .../notification_icon_connecting_pp_05.png | Bin 0 -> 765 bytes .../notification_icon_connecting_pp_06.png | Bin 0 -> 756 bytes .../drawable-mdpi/status_icon_connected.png | Bin 2199 -> 0 bytes .../drawable-mdpi/status_icon_connecting.png | Bin 2770 -> 0 bytes .../status_icon_disconnected.png | Bin 1391 -> 0 bytes .../notification_icon_connected_pp.png | Bin 0 -> 1137 bytes .../notification_icon_connecting_pp_01.png | Bin 0 -> 1383 bytes .../notification_icon_connecting_pp_02.png | Bin 0 -> 1435 bytes .../notification_icon_connecting_pp_03.png | Bin 0 -> 1462 bytes .../notification_icon_connecting_pp_04.png | Bin 0 -> 1490 bytes .../notification_icon_connecting_pp_05.png | Bin 0 -> 1457 bytes .../notification_icon_connecting_pp_06.png | Bin 0 -> 1431 bytes .../drawable-xhdpi/status_icon_connected.png | Bin 5461 -> 0 bytes .../drawable-xhdpi/status_icon_connecting.png | Bin 7514 -> 0 bytes .../status_icon_disconnected.png | Bin 2882 -> 0 bytes .../notification_icon_connected_pp.png | Bin 0 -> 1786 bytes .../notification_icon_connecting_pp_01.png | Bin 0 -> 2044 bytes .../notification_icon_connecting_pp_02.png | Bin 0 -> 2118 bytes .../notification_icon_connecting_pp_03.png | Bin 0 -> 2166 bytes .../notification_icon_connecting_pp_04.png | Bin 0 -> 2204 bytes .../notification_icon_connecting_pp_05.png | Bin 0 -> 2162 bytes .../notification_icon_connecting_pp_06.png | Bin 0 -> 2117 bytes .../drawable-xxhdpi/status_icon_connected.png | Bin 12286 -> 0 bytes .../status_icon_connecting.png | Bin 16838 -> 0 bytes .../status_icon_disconnected.png | Bin 5416 -> 0 bytes .../notification_icon_connected_pp.png | Bin 0 -> 2673 bytes .../notification_icon_connecting_pp_01.png | Bin 0 -> 2029 bytes .../notification_icon_connecting_pp_02.png | Bin 0 -> 2091 bytes .../notification_icon_connecting_pp_03.png | Bin 0 -> 2144 bytes .../notification_icon_connecting_pp_04.png | Bin 0 -> 2193 bytes .../notification_icon_connecting_pp_05.png | Bin 0 -> 2140 bytes .../notification_icon_connecting_pp_06.png | Bin 0 -> 2090 bytes .../status_icon_connected.png | Bin 14913 -> 0 bytes .../status_icon_connecting.png | Bin 21225 -> 0 bytes .../status_icon_disconnected.png | Bin 5922 -> 0 bytes ...ification_icon_connecting_animation_pp.xml | 12 + app/src/main/res/drawable/p2p_24px.xml | 9 + .../res/drawable/status_icon_connected.xml | 21 + .../res/drawable/status_icon_connected_pp.xml | 21 + .../res/drawable/status_icon_connecting.xml | 21 + .../drawable/status_icon_connecting_pp.xml | 21 + .../res/drawable/status_icon_disconnected.xml | 9 + .../main/res/layout/dialog_import_pairing.xml | 21 + .../main/res/layout/dialog_pairing_enable.xml | 24 + .../main/res/layout/dialog_pairing_update.xml | 37 ++ .../main/res/layout/dialog_reset_pairing.xml | 38 ++ app/src/main/res/layout/main_activity.xml | 50 +- .../res/layout/preference_button_layout.xml | 8 + .../res/layout/preference_category_title.xml | 18 + ...n_android_library_untranslated_strings.xml | 6 + app/src/main/res/values/strings.xml | 120 +++- .../res/xml/personal_pairing_preferences.xml | 34 ++ .../res/xml/settings_preferences_screen.xml | 4 + .../PersonalPairingHelperTest.java | 117 ++++ 79 files changed, 1956 insertions(+), 113 deletions(-) create mode 100644 app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingHelper.java create mode 100644 app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingPreferenceActivity.java create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connected_pp.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_01.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_02.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_03.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_04.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_05.png create mode 100644 app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_06.png delete mode 100644 app/src/main/res/drawable-hdpi/status_icon_connected.png delete mode 100644 app/src/main/res/drawable-hdpi/status_icon_connecting.png delete mode 100644 app/src/main/res/drawable-hdpi/status_icon_disconnected.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connected_pp.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_01.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_02.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_03.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_04.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_05.png create mode 100644 app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_06.png delete mode 100644 app/src/main/res/drawable-mdpi/status_icon_connected.png delete mode 100644 app/src/main/res/drawable-mdpi/status_icon_connecting.png delete mode 100644 app/src/main/res/drawable-mdpi/status_icon_disconnected.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connected_pp.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_01.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_02.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_03.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_04.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_05.png create mode 100644 app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_06.png delete mode 100644 app/src/main/res/drawable-xhdpi/status_icon_connected.png delete mode 100644 app/src/main/res/drawable-xhdpi/status_icon_connecting.png delete mode 100644 app/src/main/res/drawable-xhdpi/status_icon_disconnected.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connected_pp.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_01.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_02.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_03.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_04.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_05.png create mode 100644 app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_06.png delete mode 100644 app/src/main/res/drawable-xxhdpi/status_icon_connected.png delete mode 100644 app/src/main/res/drawable-xxhdpi/status_icon_connecting.png delete mode 100644 app/src/main/res/drawable-xxhdpi/status_icon_disconnected.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connected_pp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_01.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_02.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_03.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_04.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_05.png create mode 100644 app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_06.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/status_icon_connected.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/status_icon_connecting.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/status_icon_disconnected.png create mode 100644 app/src/main/res/drawable/notification_icon_connecting_animation_pp.xml create mode 100644 app/src/main/res/drawable/p2p_24px.xml create mode 100644 app/src/main/res/drawable/status_icon_connected.xml create mode 100644 app/src/main/res/drawable/status_icon_connected_pp.xml create mode 100644 app/src/main/res/drawable/status_icon_connecting.xml create mode 100644 app/src/main/res/drawable/status_icon_connecting_pp.xml create mode 100644 app/src/main/res/drawable/status_icon_disconnected.xml create mode 100644 app/src/main/res/layout/dialog_import_pairing.xml create mode 100644 app/src/main/res/layout/dialog_pairing_enable.xml create mode 100644 app/src/main/res/layout/dialog_pairing_update.xml create mode 100644 app/src/main/res/layout/dialog_reset_pairing.xml create mode 100644 app/src/main/res/layout/preference_button_layout.xml create mode 100644 app/src/main/res/layout/preference_category_title.xml create mode 100644 app/src/main/res/xml/personal_pairing_preferences.xml create mode 100644 app/src/test/java/com/psiphon3/psiphonlibrary/PersonalPairingHelperTest.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 434fb2f73..feb78a97a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,26 @@ android:scheme="psiphon" android:host="settings" /> + + + + + + + + + + + + + + + + + + @@ -165,35 +193,6 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/java/com/psiphon3/HomeTabFragment.java b/app/src/main/java/com/psiphon3/HomeTabFragment.java index 48578efa5..df4576f24 100644 --- a/app/src/main/java/com/psiphon3/HomeTabFragment.java +++ b/app/src/main/java/com/psiphon3/HomeTabFragment.java @@ -35,6 +35,7 @@ import android.widget.TextView; import android.widget.ViewFlipper; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -164,16 +165,20 @@ public void onDestroy() { } private void updateStatusUI(TunnelState tunnelState) { + @DrawableRes int statusIconResId; if (tunnelState.isRunning()) { if (tunnelState.connectionData().isConnected()) { - statusViewImage.setImageResource(R.drawable.status_icon_connected); + statusIconResId = tunnelState.connectionData().personalPairingEnabled() ? + R.drawable.status_icon_connected_pp : R.drawable.status_icon_connected; } else { - statusViewImage.setImageResource(R.drawable.status_icon_connecting); + statusIconResId = tunnelState.connectionData().personalPairingEnabled() ? + R.drawable.status_icon_connecting_pp : R.drawable.status_icon_connecting; } } else { // the tunnel state is either unknown or not running - statusViewImage.setImageResource(R.drawable.status_icon_disconnected); + statusIconResId = R.drawable.status_icon_disconnected; } + statusViewImage.setImageResource(statusIconResId); } private void loadEmbeddedWebView(String url) { diff --git a/app/src/main/java/com/psiphon3/MainActivity.java b/app/src/main/java/com/psiphon3/MainActivity.java index 802db2462..bca26868b 100644 --- a/app/src/main/java/com/psiphon3/MainActivity.java +++ b/app/src/main/java/com/psiphon3/MainActivity.java @@ -34,6 +34,9 @@ import android.nfc.cardemulation.CardEmulation; import android.os.Build; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.SystemClock; import android.provider.Settings; import android.text.SpannableString; import android.text.SpannableStringBuilder; @@ -55,7 +58,9 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.widget.SwitchCompat; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.content.PermissionChecker; @@ -69,8 +74,10 @@ import com.google.android.material.tabs.TabLayout; import com.psiphon3.VpnRulesHelper; import com.psiphon3.log.LogsMaintenanceWorker; +import com.psiphon3.log.MyLog; import com.psiphon3.psiphonlibrary.EmbeddedValues; import com.psiphon3.psiphonlibrary.LocalizedActivities; +import com.psiphon3.psiphonlibrary.PersonalPairingHelper; import com.psiphon3.psiphonlibrary.TunnelManager; import com.psiphon3.psiphonlibrary.Utils; import com.psiphon3.psiphonlibrary.VpnAppsUtils; @@ -90,11 +97,14 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeUnit; import io.reactivex.Completable; +import io.reactivex.Flowable; import io.reactivex.Maybe; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.schedulers.Schedulers; public class MainActivity extends LocalizedActivities.AppCompatActivity { @@ -128,6 +138,17 @@ public MainActivity() { // Keeps track of the Psiphon Bump help state private PsiphonBumpHelpState psiphonBumpHelpState = PsiphonBumpHelpState.DISABLED; + private View personalPairingToggleContainer; + private SwitchCompat personalPairingToggle; + private TextView personalPairingLabel; + private Button personalPairingTurnOffButton; + private boolean personalPairingEnabled; + private TunnelState latestTunnelState; + private long personalPairingConnectingSinceMs = -1; + private static final long PERSONAL_PAIRING_TURN_OFF_PROMPT_DELAY_MS = TimeUnit.MINUTES.toMillis(2); + private final Handler personalPairingPromptHandler = new Handler(Looper.getMainLooper()); + private final Runnable personalPairingPromptRunnable = this::updatePersonalPairingTurnOffPrompt; + enum PsiphonBumpHelpState { DISABLED, NEED_SYSTEM_NFC, @@ -208,6 +229,22 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { helpConnectFab = findViewById(R.id.help_connect_fab); + personalPairingToggleContainer = findViewById(R.id.personalPairingToggleContainer); + personalPairingToggle = findViewById(R.id.personalPairingToggle); + personalPairingToggle.setOnCheckedChangeListener((buttonView, isChecked) -> + viewModel.setPersonalParingEnabled(isChecked)); + + personalPairingLabel = findViewById(R.id.personalPairingLabel); + personalPairingTurnOffButton = findViewById(R.id.personalPairingTurnOffButton); + personalPairingTurnOffButton.setOnClickListener(v -> { + if (personalPairingToggle.isChecked()) { + personalPairingToggle.setChecked(false); + } else { + viewModel.setPersonalParingEnabled(false); + } + }); + + EmbeddedValues.initialize(getApplicationContext()); // Load VPN exclusion rules from storage for main app process @@ -301,6 +338,7 @@ public void onTabReselected(TabLayout.Tab tab) { @Override public void onDestroy() { + personalPairingPromptHandler.removeCallbacks(personalPairingPromptRunnable); compositeDisposable.dispose(); super.onDestroy(); } @@ -309,6 +347,7 @@ public void onDestroy() { protected void onPause() { super.onPause(); cancelInvalidProxySettingsToast(); + personalPairingPromptHandler.removeCallbacks(personalPairingPromptRunnable); compositeDisposable.clear(); } @@ -346,19 +385,8 @@ protected void onResume() { .doOnNext(this::updateServiceStateUI) .subscribe()); - // If device supports Psiphon Bump observe tunnel state and update NFC UI and HCE state accordingly - if (Utils.supportsPsiphonBump(this)) { - compositeDisposable.add(getTunnelServiceInteractor().tunnelStateFlowable() - .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(this::updatePsiphonBumpState) - // disable Psiphon Bump HCE and hide help connect FAB when this subscription is - // disposed. - .doOnCancel(() -> { - updatePsiphonBumpHceState(false); - helpConnectFab.setVisibility(View.GONE); - }) - .subscribe()); - } + // Set up Psiphon Bump state handling + setupPsiphonBumpHandling(); // Observe custom proxy validation results to show a toast for invalid ones compositeDisposable.add(viewModel.customProxyValidationResultFlowable() @@ -397,6 +425,88 @@ protected void onResume() { .andThen(autoStartMaybe()) .doOnSuccess(__ -> startTunnel()) .subscribe()); + + // Observe personal pairing state changes and restart the tunnel if needed +// Observe personal pairing state changes and restart the tunnel if needed + compositeDisposable.add( + viewModel.pairingStateRestartTunnelFlowable() + .observeOn(AndroidSchedulers.mainThread()) + .switchMap(__ -> getTunnelServiceInteractor().tunnelStateFlowable() + .filter(tunnelState -> !tunnelState.isUnknown()) + .take(1) + .doOnNext(tunnelState -> { + if (tunnelState.isRunning()) { + getTunnelServiceInteractor().commandTunnelRestart(); + } + }) + ) + .subscribe()); + + // Observe personal paring state and update the UI + compositeDisposable.add( + viewModel.personalPairingStateFlowable() + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(state -> { + personalPairingEnabled = state.enabled; + + if (state.data == null || state.data.compartmentId == null || state.data.compartmentId.isEmpty()) { + // Hide the personal pairing toggle layout if there is no data + personalPairingToggleContainer.setVisibility(View.GONE); + } else { + // Show the personal pairing toggle layout if there is data + personalPairingToggleContainer.setVisibility(View.VISIBLE); + } + + if (state.enabled && state.data != null && state.data.compartmentId != null && !state.data.compartmentId.isEmpty()) { + String alias = state.data.alias; + personalPairingToggle.setChecked(true); + if (alias != null && !alias.isEmpty()) { + personalPairingLabel.setText(getString(R.string.preference_summary_personal_pairing_enabled_with_alias, alias)); + } else { + personalPairingLabel.setText(getString(R.string.preference_summary_personal_pairing_enabled)); + } + personalPairingLabel.setVisibility(View.VISIBLE); + } else { + personalPairingToggle.setChecked(false); + personalPairingLabel.setVisibility(View.INVISIBLE); // Not GONE, we want to keep the space + } + + updatePersonalPairingTurnOffPrompt(); + }) + .subscribe()); + } + + private void setupPsiphonBumpHandling() { + if (!Utils.supportsPsiphonBump(this)) { + updatePsiphonBumpHceState(false); + helpConnectFab.setVisibility(View.GONE); + helpConnectFab.setOnClickListener(null); + return; + } + + compositeDisposable.add( + Flowable.combineLatest( + getTunnelServiceInteractor().tunnelStateFlowable(), + viewModel.personalPairingStateFlowable(), + (tunnelState, personalPairingEnabled) -> { + // If personal pairing is enabled, override everything else + if (personalPairingEnabled.enabled) { + updatePsiphonBumpHceState(false); + helpConnectFab.setVisibility(View.GONE); + helpConnectFab.setOnClickListener(null); + } else { + // Otherwise process normal tunnel state + updatePsiphonBumpState(tunnelState); + } + return tunnelState; // return tunnel state for further processing if needed + }) + .observeOn(AndroidSchedulers.mainThread()) + .doOnCancel(() -> { + updatePsiphonBumpHceState(false); + helpConnectFab.setVisibility(View.GONE); + }) + .subscribe() + ); } // Check runtime permissions and show rationales if needed. @@ -551,7 +661,47 @@ protected void onNewIntent(Intent intent) { HandleCurrentIntent(intent); } + private boolean shouldShowPersonalPairingTurnOffPrompt() { + if (!personalPairingEnabled || latestTunnelState == null || !latestTunnelState.isRunning()) { + return false; + } + + TunnelState.ConnectionData connectionData = latestTunnelState.connectionData(); + return connectionData != null + && connectionData.networkConnectionState() == TunnelState.ConnectionData.NetworkConnectionState.CONNECTING; + } + + private void hidePersonalPairingTurnOffPrompt() { + personalPairingConnectingSinceMs = -1; + personalPairingPromptHandler.removeCallbacks(personalPairingPromptRunnable); + personalPairingTurnOffButton.setVisibility(View.GONE); + } + + private void updatePersonalPairingTurnOffPrompt() { + if (!shouldShowPersonalPairingTurnOffPrompt()) { + hidePersonalPairingTurnOffPrompt(); + return; + } + + if (personalPairingConnectingSinceMs < 0) { + personalPairingConnectingSinceMs = SystemClock.elapsedRealtime(); + } + + long elapsed = SystemClock.elapsedRealtime() - personalPairingConnectingSinceMs; + long remaining = PERSONAL_PAIRING_TURN_OFF_PROMPT_DELAY_MS - elapsed; + + personalPairingPromptHandler.removeCallbacks(personalPairingPromptRunnable); + if (remaining <= 0) { + personalPairingTurnOffButton.setVisibility(View.VISIBLE); + } else { + personalPairingTurnOffButton.setVisibility(View.GONE); + personalPairingPromptHandler.postDelayed(personalPairingPromptRunnable, remaining); + } + } + private void updateServiceStateUI(final TunnelState tunnelState) { + latestTunnelState = tunnelState; + if (tunnelState.isUnknown()) { openBrowserButton.setEnabled(false); toggleButton.setEnabled(false); @@ -595,6 +745,8 @@ private void updateServiceStateUI(final TunnelState tunnelState) { connectionProgressBar.setVisibility(View.INVISIBLE); connectionWaitingNetworkIndicator.setVisibility(View.INVISIBLE); } + + updatePersonalPairingTurnOffPrompt(); } // update NFC UI @@ -848,6 +1000,7 @@ private void HandleCurrentIntent(Intent intent) { } } + // Handles deep links and app links private boolean handleDeepLinkIntent(@NonNull Intent intent) { final String FWD_SLASH = "/"; @@ -857,40 +1010,183 @@ private boolean handleDeepLinkIntent(@NonNull Intent intent) { final String SETTINGS_PATH_VPN = "/vpn"; final String SETTINGS_PATH_PROXY = "/proxy"; final String SETTINGS_PATH_MORE_OPTIONS = "/more-options"; + final String PAIR_HOST = "pair"; + final String PAIR_PATH_PREFIX = "/pair"; + final String HTTPS_SCHEME = "https"; + final String APP_LINK_HOST = "hextempulant.net"; Uri intentUri = intent.getData(); - // Check if this is a deep link intent we can handle - if (!Intent.ACTION_VIEW.equals(intent.getAction()) || - intentUri == null || - !PSIPHON_SCHEME.equals(intentUri.getScheme())) { - // Intent not handled + // Check if the intent is a view action and has a valid URI + if (!Intent.ACTION_VIEW.equals(intent.getAction()) || intentUri == null) { + // Intent was not handled return false; } + String scheme = intentUri.getScheme(); + String host = intentUri.getHost(); String path = intentUri.getPath(); - switch (intentUri.getHost()) { - case SETTINGS_HOST: - selectTabByTag("settings"); - if (path != null) { - // If uri path is "/vpn" or "/vpn/.*" then signal to navigate to VPN settings screen. - // If the path is "/proxy" or "/proxy/.*" then signal to navigate to Proxy settings screen. - // If the path is "/more-options" or "/more-options/.*" then signal to navigate to More Options screen. - if (path.equals(SETTINGS_PATH_VPN) || path.startsWith(SETTINGS_PATH_VPN + FWD_SLASH)) { - viewModel.signalOpenVpnSettings(); - } else if (path.equals(SETTINGS_PATH_PROXY) || path.startsWith(SETTINGS_PATH_PROXY + FWD_SLASH)) { - viewModel.signalOpenProxySettings(); - } else if (path.equals(SETTINGS_PATH_MORE_OPTIONS) || path.startsWith(SETTINGS_PATH_MORE_OPTIONS)) { - viewModel.signalOpenMoreOptions(); - } + // Handle Personal Pairing app links (https://hextempulant.net/pair/) first + if (HTTPS_SCHEME.equals(scheme) && APP_LINK_HOST.equals(host)) { + // Only process paths that start with /pair/ + if (path != null && path.startsWith(PAIR_PATH_PREFIX + FWD_SLASH)) { + if (!intentUri.getPathSegments().isEmpty() && intentUri.getPathSegments().size() > 1) { + handlePersonalPairingData(intentUri.toString()); + // Intent was handled + return true; } - // intent handled + MyLog.w("MainActivity::handleDeepLinkIntent: empty pairing data in URL"); + // Intent was not handled + return false; + } + } + + // Handle Personal Pairing deep links (psiphon://pair/) next + if (PSIPHON_SCHEME.equals(scheme) && PAIR_HOST.equals(host)) { + // Return false if path is missing or invalid + if (path == null || path.length() <= 1) { + // Intent was not handled + return false; + } + + if (!intentUri.getPathSegments().isEmpty()) { + handlePersonalPairingData(intentUri.toString()); + // Intent was handled return true; + } + MyLog.w("MainActivity::handleDeepLinkIntent: empty pairing data in deep link"); + // Intent was not handled + return false; } - // intent not handled + + // Finally, handle psiphon://settings/... deep links + if (SETTINGS_HOST.equals(host)) { + selectTabByTag("settings"); + // If uri path is "/vpn" or "/vpn/.*" then signal to navigate to VPN settings screen. + // If the path is "/proxy" or "/proxy/.*" then signal to navigate to Proxy settings screen. + // If the path is "/more-options" or "/more-options/.*" then signal to navigate to More Options screen. + if (path != null) { + if (path.equals(SETTINGS_PATH_VPN) || path.startsWith(SETTINGS_PATH_VPN + FWD_SLASH)) { + viewModel.signalOpenVpnSettings(); + } else if (path.equals(SETTINGS_PATH_PROXY) || path.startsWith(SETTINGS_PATH_PROXY + FWD_SLASH)) { + viewModel.signalOpenProxySettings(); + } else if (path.equals(SETTINGS_PATH_MORE_OPTIONS) || path.startsWith(SETTINGS_PATH_MORE_OPTIONS + FWD_SLASH)) { + viewModel.signalOpenMoreOptions(); + } + } + // Intent was handled + return true; + } + // Intent was not handled return false; } + // Handles personal pairing data import from deep / app links + private void handlePersonalPairingData(String input) { + Flowable tunnelStateFlowable = getTunnelServiceInteractor() + .tunnelStateFlowable() + .filter(state -> !state.isUnknown()); + + compositeDisposable.add( + viewModel.handlePersonalPairingData(input, tunnelStateFlowable) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(result -> { + switch (result.action) { + case SHOW_SUCCESS: + showToast(R.string.personal_pairing_data_import_success); + break; + case SHOW_ALREADY_EXISTS: + showToast(R.string.personal_pairing_data_already_exists); + break; + case SHOW_ERROR: + showToast(getPairingImportErrorString(result.validationError)); + break; + case PROMPT_ENABLE: + showEnableConfirmationDialog(result.data); + break; + case PROMPT_UPDATE: + showUpdateConfirmationDialog(result.data, result.existingCompartmentId, result.existingEnabled); + break; + } + }, error -> showToast(getPairingImportErrorString( + PersonalPairingHelper.validationErrorFromException(error)))) + ); + } + + @StringRes + private int getPairingImportErrorString(PersonalPairingHelper.ImportValidationError validationError) { + if (validationError == PersonalPairingHelper.ImportValidationError.UNSUPPORTED_VERSION) { + return R.string.personal_pairing_unsupported_version; + } + if (validationError == PersonalPairingHelper.ImportValidationError.INVALID_INPUT_FORMAT) { + return R.string.personal_pairing_invalid_url; + } + return R.string.personal_pairing_invalid_data; + } + + // Keeps track of any import pairing data toast to cancel if we need to show a new one + Toast importPairingDataToast; + + // Shows a toast while cancelling any current import pairing data toast + private void showToast(@StringRes int messageId) { + if (importPairingDataToast != null) { + importPairingDataToast.cancel(); + } + importPairingDataToast = Toast.makeText(MainActivity.this, messageId, Toast.LENGTH_LONG); + importPairingDataToast.show(); + } + + // Keep track of the update confirmation dialog to dismiss if we need to show a new one + AlertDialog updateConfirmationDialog; + // Confirms updating existing personal pairing data if the compartment ID already present in the settings + private void showUpdateConfirmationDialog(PersonalPairingHelper.PersonalPairingData newData, String existingId, boolean enabled) { + if (updateConfirmationDialog != null && updateConfirmationDialog.isShowing()) { + updateConfirmationDialog.dismiss(); + } + View dialogView = getLayoutInflater().inflate(R.layout.dialog_pairing_update, null); + TextView oldIdView = dialogView.findViewById(R.id.old_compartment_id); + TextView newIdView = dialogView.findViewById(R.id.new_compartment_id); + oldIdView.setText(existingId); + newIdView.setText(newData.compartmentId); + + updateConfirmationDialog = new AlertDialog.Builder(this) + .setIcon(R.drawable.ic_psiphon_alert_notification) + .setTitle(R.string.personal_pairing_update_title) + .setView(dialogView) + .setPositiveButton(R.string.personal_pairing_update_positive_button, + (dialog, which) -> { + viewModel.confirmPersonalPairingImport(newData, enabled); + showToast(R.string.personal_pairing_data_update_success); + }) + .setNegativeButton(R.string.personal_pairing_update_negative_button, null) + .show(); + } + + // Keep track of the enable confirmation dialog to dismiss if we need to show a new one + AlertDialog enableConfirmationDialog; + // Confirms enabling personal pairing feature while importing personal pairing data + private void showEnableConfirmationDialog(PersonalPairingHelper.PersonalPairingData data) { + if (enableConfirmationDialog != null && enableConfirmationDialog.isShowing()) { + enableConfirmationDialog.dismiss(); + } + View dialogView = getLayoutInflater().inflate(R.layout.dialog_pairing_enable, null); + + enableConfirmationDialog = new AlertDialog.Builder(this) + .setIcon(R.drawable.ic_psiphon_alert_notification) + .setTitle(R.string.personal_pairing_enable_confirmation_dialog_title) + .setView(dialogView) + .setPositiveButton(R.string.lbl_yes, (dialog, which) -> { + viewModel.confirmPersonalPairingImport(data, true); + showToast(R.string.personal_pairing_data_import_success); + }) + .setNegativeButton(R.string.lbl_no, (dialog, which) -> { + viewModel.confirmPersonalPairingImport(data, false); + showToast(R.string.personal_pairing_data_import_success); + }) + .show(); + } + @Override public void startTunnel() { // Don't start if custom proxy settings is selected and values are invalid @@ -916,8 +1212,15 @@ private void preventAutoStart() { } private boolean shouldAutoStart() { + Intent intent = getIntent(); + + // Check if launched from a deep link or app link and prevent auto-start if so + boolean isDeepLink = Intent.ACTION_VIEW.equals(intent.getAction()) && + (intent.getData() != null); + return isFirstRun && - !getIntent().getBooleanExtra(INTENT_EXTRA_PREVENT_AUTO_START, false); + !intent.getBooleanExtra(INTENT_EXTRA_PREVENT_AUTO_START, false) && + !isDeepLink; } // Returns an object only if tunnel should be auto-started, diff --git a/app/src/main/java/com/psiphon3/MainActivityViewModel.java b/app/src/main/java/com/psiphon3/MainActivityViewModel.java index d8cc5ad4b..ea9a93284 100644 --- a/app/src/main/java/com/psiphon3/MainActivityViewModel.java +++ b/app/src/main/java/com/psiphon3/MainActivityViewModel.java @@ -34,10 +34,15 @@ import com.psiphon3.log.LogsDataSourceFactory; import com.psiphon3.log.LogsLastEntryHelper; import com.psiphon3.log.MyLog; +import com.psiphon3.psiphonlibrary.PersonalPairingHelper; import com.psiphon3.psiphonlibrary.UpstreamProxySettings; +import java.util.Objects; + import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; +import io.reactivex.Single; +import io.reactivex.disposables.CompositeDisposable; public class MainActivityViewModel extends AndroidViewModel implements DefaultLifecycleObserver { private final PublishRelay customProxyValidationResultRelay = PublishRelay.create(); @@ -49,9 +54,12 @@ public class MainActivityViewModel extends AndroidViewModel implements DefaultLi private final Flowable lastLogEntryFlowable; private final Flowable> logsPagedListFlowable; private final ContentObserver loggingObserver; + private final PersonalPairingHelper personalPairingHelper; + private final CompositeDisposable compositeDisposable = new CompositeDisposable(); public MainActivityViewModel(@NonNull Application application) { super(application); + personalPairingHelper = new PersonalPairingHelper(application); LogsLastEntryHelper logsLastEntryHelper = new LogsLastEntryHelper(application.getContentResolver()); LogsDataSourceFactory logsDataSourceFactory = new LogsDataSourceFactory(application.getContentResolver()); @@ -92,6 +100,7 @@ public void onChange(boolean selfChange) { @Override protected void onCleared() { super.onCleared(); + compositeDisposable.clear(); getApplication().getContentResolver().unregisterContentObserver(loggingObserver); } @@ -166,4 +175,54 @@ public Flowable lastLogEntryFlowable() { return lastLogEntryFlowable .map(logEntry -> MyLog.getStatusLogMessageForDisplay(logEntry.getLogJson(), getApplication())); } + + public Flowable personalPairingStateFlowable() { + return personalPairingHelper.observePersonalPairingState() + .distinctUntilChanged(); + } + + public Single handlePersonalPairingData( + String input, + Flowable tunnelState) { + return personalPairingHelper.handleImport(input, tunnelState); + } + + public void confirmPersonalPairingImport(PersonalPairingHelper.PersonalPairingData data, boolean enableSetting) { + personalPairingHelper.confirmImport(data, enableSetting); + } + + public void setPersonalPairingState(boolean isEnabled, @NonNull PersonalPairingHelper.PersonalPairingData data) { + personalPairingHelper.setPersonalPairingState(isEnabled, data); + } + + public void setPersonalParingEnabled(boolean isEnabled) { + personalPairingHelper.setPersonalPairingEnabled(isEnabled); + } + + // Keep track of the last known pairing state to determine when tunnel restart is needed + private PersonalPairingHelper.PersonalPairingState lastKnownPersonalPairingState; + + + // Observes pairing state changes and triggers tunnel restart when necessary. Restart occurs when: + // - Pairing is enabled/ disabled + // - Compartment ID changes while pairing is enabled + // returns a flowable that emits true when a restart is needed + public Flowable pairingStateRestartTunnelFlowable() { + return personalPairingStateFlowable() + .map(currentState -> { + boolean shouldRestart = false; + + if (lastKnownPersonalPairingState != null) { + boolean enableChanged = lastKnownPersonalPairingState.enabled != currentState.enabled; + boolean compartmentChanged = lastKnownPersonalPairingState.enabled && currentState.enabled && + !Objects.equals(lastKnownPersonalPairingState.data.compartmentId, currentState.data.compartmentId); + + shouldRestart = enableChanged || compartmentChanged; + } + + lastKnownPersonalPairingState = currentState; + return shouldRestart; + }) + .switchMap(shouldRestart -> shouldRestart ? Flowable.just(true) : Flowable.empty()); + } } diff --git a/app/src/main/java/com/psiphon3/OptionsTabFragment.java b/app/src/main/java/com/psiphon3/OptionsTabFragment.java index 37d7e18c7..d7c3285e3 100644 --- a/app/src/main/java/com/psiphon3/OptionsTabFragment.java +++ b/app/src/main/java/com/psiphon3/OptionsTabFragment.java @@ -17,6 +17,8 @@ import com.psiphon3.psiphonlibrary.LocalizedActivities; import com.psiphon3.psiphonlibrary.MoreOptionsPreferenceActivity; +import com.psiphon3.psiphonlibrary.PersonalPairingHelper; +import com.psiphon3.psiphonlibrary.PersonalPairingPreferenceActivity; import com.psiphon3.psiphonlibrary.ProxyOptionsPreferenceActivity; import com.psiphon3.psiphonlibrary.PsiphonConstants; import com.psiphon3.psiphonlibrary.PsiphonPreferenceFragmentCompat; @@ -42,10 +44,12 @@ private enum RestartMode { private static final int REQUEST_CODE_VPN_PREFERENCES = 100; private static final int REQUEST_CODE_PROXY_PREFERENCES = 101; private static final int REQUEST_CODE_MORE_PREFERENCES = 102; + private static final int REQUEST_CODE_PERSONAL_PAIRING = 103; private RegionListPreference regionListPreference; private Preference vpnOptionsPreference; private Preference proxyOptionsPreference; + private Preference personalPairingPreference; private AppPreferences multiProcessPreferences; private MainActivityViewModel viewModel; private final CompositeDisposable compositeDisposable = new CompositeDisposable(); @@ -105,6 +109,15 @@ public void onCreatePreferences(Bundle bundle, String s) { } return true; }); + personalPairingPreference = findPreference(getContext().getString(R.string.personalPairingPreferenceKey)); + personalPairingPreference.setOnPreferenceClickListener(__ -> { + final FragmentActivity activity = getActivity(); + if (activity != null && !activity.isFinishing()) { + startActivityForResult(new Intent(getActivity(), + PersonalPairingPreferenceActivity.class), REQUEST_CODE_PERSONAL_PAIRING); + } + return true; + }); } @Override @@ -167,6 +180,13 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat } }) .subscribe()); + + // Observe 'Personal Pairing` signal from deep link intent handler + // and update the preference summary + compositeDisposable.add(viewModel.personalPairingStateFlowable() + .observeOn(AndroidSchedulers.mainThread()) + .doOnNext(this::setPersonalPairingSummary) + .subscribe()); } private void onRegionSelected(String selectedRegionCode) { @@ -218,6 +238,21 @@ private void setSummaryFromPreferences() { } } + private void setPersonalPairingSummary(PersonalPairingHelper.PersonalPairingState personalPairingState) { + if (personalPairingState.enabled) { + String alias = personalPairingState.data == null ? null : personalPairingState.data.alias; + if (alias == null || alias.isEmpty()) { + // If no alias show just Enabled + personalPairingPreference.setSummary(R.string.preference_summary_personal_pairing_enabled); + } else { + // If alias then show the alias + personalPairingPreference.setSummary(getString(R.string.preference_summary_personal_pairing_enabled_with_alias, alias)); + } + } else { + personalPairingPreference.setSummary(R.string.preference_summary_personal_pairing_disabled); + } + } + @Override public void onActivityResult(int request, int result, Intent data) { final @NonNull RestartMode restartMode; @@ -237,6 +272,14 @@ public void onActivityResult(int request, int result, Intent data) { updateMoreSettingsFromPreferences(); break; + case REQUEST_CODE_PERSONAL_PAIRING: + // Note: we are not checking for restart requirements here + // because the personal pairing settings may be changed from the main screen or by importing data from a deep link as well as from the personal pairing settings screen + // and we will be taking care of the restart requirements centrally + restartMode = RestartMode.NONE; + updatePersonalPairingFromPreferences(); + break; + default: restartMode = RestartMode.NONE; super.onActivityResult(request, result, data); @@ -450,4 +493,17 @@ private void updateMoreSettingsFromPreferences() { new SharedPreferencesImport(requireContext(), prefName, getString(R.string.nfcBumpPreference), getString(R.string.nfcBumpPreference)) ); } + + private void updatePersonalPairingFromPreferences() { + String prefName = getString(R.string.moreOptionsPreferencesName); + boolean isEnabled = requireContext().getSharedPreferences(prefName, MODE_PRIVATE) + .getBoolean(getString(R.string.personalPairingEnabledPreference), false); + String compartmentId = requireContext().getSharedPreferences(prefName, MODE_PRIVATE) + .getString(getString(R.string.personalPairingCompartmentIdPreference), ""); + String alias = requireContext().getSharedPreferences(prefName, MODE_PRIVATE) + .getString(getString(R.string.personalPairingAliasPreference), ""); + + PersonalPairingHelper.PersonalPairingData data = new PersonalPairingHelper.PersonalPairingData(compartmentId, alias); + viewModel.setPersonalPairingState(isEnabled, data); + } } diff --git a/app/src/main/java/com/psiphon3/TunnelState.java b/app/src/main/java/com/psiphon3/TunnelState.java index 841e48d14..f3867f4c5 100644 --- a/app/src/main/java/com/psiphon3/TunnelState.java +++ b/app/src/main/java/com/psiphon3/TunnelState.java @@ -62,6 +62,8 @@ public enum NetworkConnectionState { @Nullable public abstract ArrayList vpnApps(); + public abstract boolean personalPairingEnabled(); + public static Builder builder() { return new AutoValue_TunnelState_ConnectionData.Builder() .setNetworkConnectionState(NetworkConnectionState.CONNECTING) @@ -72,7 +74,8 @@ public static Builder builder() { .setHttpPort(0) .setHomePages(null) .setVpnMode(com.psiphon3.psiphonlibrary.VpnAppsUtils.VpnAppsExclusionSetting.ALL_APPS) - .setVpnApps(null); + .setVpnApps(null) + .setPersonalPairingEnabled(false); } @AutoValue.Builder @@ -95,6 +98,8 @@ public static abstract class Builder { public abstract Builder setVpnApps(@Nullable ArrayList vpnApps); + public abstract Builder setPersonalPairingEnabled(boolean value); + public abstract ConnectionData build(); } diff --git a/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingHelper.java b/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingHelper.java new file mode 100644 index 000000000..eeee0f0bb --- /dev/null +++ b/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingHelper.java @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2024, Psiphon Inc. + * All rights reserved. + * + * 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 . + * + */ + +package com.psiphon3.psiphonlibrary; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.jakewharton.rxrelay2.BehaviorRelay; +import com.psiphon3.R; +import com.psiphon3.TunnelState; +import com.psiphon3.log.MyLog; + +import net.grandcentrix.tray.AppPreferences; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Objects; +import java.util.regex.Pattern; + +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; +import io.reactivex.Single; + +/** + * Helper class to manage the state and configuration of the personal pairing feature. + * Provides utilities to observe, validate, and update personal pairing settings, + * handle user imports, and manage storage and relay mechanisms for state changes. + */ +public class PersonalPairingHelper { + private static final String PSIPHON_SCHEME = "psiphon"; + private static final String PSIPHON_PAIR_HOST = "pair"; + private static final String HTTP_SCHEME = "http"; + private static final String HTTPS_SCHEME = "https"; + private static final String PAIR_PATH_SEGMENT = "pair"; + private static final String SUPPORTED_VERSION = "1"; + private static final String VERSION_KEY = "v"; + private static final String DATA_KEY = "data"; + private static final String ID_KEY = "id"; + private static final String NAME_KEY = "name"; + private static final Pattern BASE64URL_PATTERN = Pattern.compile("^[A-Za-z0-9_-]+$"); + private static final Pattern BASE64_PATTERN = Pattern.compile("^[A-Za-z0-9+/]+={0,2}$"); + private static final Pattern COMPARTMENT_ID_PATTERN = Pattern.compile("^[A-Za-z0-9_-]{43}$"); + private static final JsonFactory JSON_FACTORY = new JsonFactory(); + + public enum ImportValidationError { + INVALID_INPUT_FORMAT, + MALFORMED_TOKEN, + UNSUPPORTED_VERSION + } + + public static class PersonalPairingImportException extends IllegalArgumentException { + public final ImportValidationError validationError; + + public PersonalPairingImportException(ImportValidationError validationError) { + super(validationError.name()); + this.validationError = validationError; + } + + public PersonalPairingImportException(ImportValidationError validationError, Throwable cause) { + super(validationError.name(), cause); + this.validationError = validationError; + } + } + + public static class PersonalPairingState { + public final boolean enabled; + public final PersonalPairingData data; + + public PersonalPairingState(boolean enabled, PersonalPairingData data) { + this.enabled = enabled; + this.data = data; + } + + public static PersonalPairingState create(boolean enabled, PersonalPairingData data) { + return new PersonalPairingState(enabled, data); + } + + public PersonalPairingState withEnabled(boolean enabled) { + return new PersonalPairingState(enabled, this.data); + } + + public PersonalPairingState withData(PersonalPairingData data) { + return new PersonalPairingState(this.enabled, data); + } + } + + public static class PersonalPairingData { + public final String compartmentId; + public final String alias; + + public PersonalPairingData(String compartmentId, String alias) { + this.compartmentId = compartmentId; + this.alias = alias; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PersonalPairingData that = (PersonalPairingData) o; + return Objects.equals(compartmentId, that.compartmentId) && + Objects.equals(alias, that.alias); + } + + @Override + public int hashCode() { + return Objects.hash(compartmentId, alias); + } + } + + private final BehaviorRelay personalPairingStateRelay; + private final AppPreferences prefs; + private final Context context; + + public PersonalPairingHelper(Context context) { + this.context = context; + this.prefs = new AppPreferences(context); + this.personalPairingStateRelay = BehaviorRelay.createDefault(loadInitialState()); + } + + // Load initial state from multi-process shared preferences + private PersonalPairingState loadInitialState() { + boolean enabled = prefs.getBoolean(context.getString(R.string.personalPairingEnabledPreference), false); + String compartmentId = prefs.getString( + context.getString(R.string.personalPairingCompartmentIdPreference), ""); + String alias = prefs.getString( + context.getString(R.string.personalPairingAliasPreference), ""); + + PersonalPairingData data = null; + if (compartmentId != null && !compartmentId.isEmpty()) { + data = new PersonalPairingData(compartmentId, alias != null ? alias : ""); + } + + return new PersonalPairingState(enabled, data); + } + + // Observe personal pairing state changes + public Flowable observePersonalPairingState() { + return personalPairingStateRelay.hide() + .toFlowable(BackpressureStrategy.LATEST); + } + + // Update personal pairing state enabled flag + public void setPersonalPairingEnabled(boolean enabled) { + PersonalPairingState currentState = personalPairingStateRelay.getValue(); + if (currentState != null && currentState.enabled != enabled) { + prefs.put(context.getString(R.string.personalPairingEnabledPreference), enabled); + personalPairingStateRelay.accept(currentState.withEnabled(enabled)); + } + } + + // Update personal pairing state data, i.e. compartment ID and alias values and enabled flag + public void setPersonalPairingState(boolean enabled, PersonalPairingData data) { + if (data == null) { + return; + } + PersonalPairingState currentState = personalPairingStateRelay.getValue(); + if (currentState != null && (currentState.enabled != enabled || + !Objects.equals(currentState.data, data))) { + prefs.put(context.getString(R.string.personalPairingEnabledPreference), enabled); + prefs.put(context.getString(R.string.personalPairingCompartmentIdPreference), data.compartmentId); + prefs.put(context.getString(R.string.personalPairingAliasPreference), data.alias); + personalPairingStateRelay.accept(PersonalPairingState.create(enabled, data)); + } + } + + // Container class for import result and data + public static class ImportResult { + public enum Action { + // Data imported successfully + SHOW_SUCCESS, + // Data already exists (same compartment ID) + SHOW_ALREADY_EXISTS, + // Data import failed + SHOW_ERROR, + // Prompt user to enable the feature + PROMPT_ENABLE, + // Prompt user to update existing data + PROMPT_UPDATE + } + + public final Action action; + public final PersonalPairingData data; + public final String existingCompartmentId; + public final Boolean existingEnabled; + public final ImportValidationError validationError; + + private ImportResult(Action action, + PersonalPairingData data, + String existingCompartmentId, + Boolean existingEnabled, + ImportValidationError validationError) { + this.action = action; + this.data = data; + this.existingCompartmentId = existingCompartmentId; + this.existingEnabled = existingEnabled; + this.validationError = validationError; + } + + public static ImportResult success(PersonalPairingData data) { + return new ImportResult(Action.SHOW_SUCCESS, data, null, null, null); + } + + public static ImportResult alreadyExists(PersonalPairingData data) { + return new ImportResult(Action.SHOW_ALREADY_EXISTS, data, null, null, null); + } + + public static ImportResult error(ImportValidationError validationError) { + return new ImportResult(Action.SHOW_ERROR, null, null, null, validationError); + } + + public static ImportResult promptEnable(PersonalPairingData data) { + return new ImportResult(Action.PROMPT_ENABLE, data, null, null, null); + } + + public static ImportResult needsUpdate(PersonalPairingData data, String existingId, Boolean existingEnabled) { + return new ImportResult(Action.PROMPT_UPDATE, data, existingId, existingEnabled, null); + } + } + + public static ImportValidationError validationErrorFromException(Throwable throwable) { + if (throwable instanceof PersonalPairingImportException) { + return ((PersonalPairingImportException) throwable).validationError; + } + return ImportValidationError.MALFORMED_TOKEN; + } + + private static PersonalPairingImportException invalidInputFormat() { + return new PersonalPairingImportException(ImportValidationError.INVALID_INPUT_FORMAT); + } + + private static PersonalPairingImportException malformedToken() { + return new PersonalPairingImportException(ImportValidationError.MALFORMED_TOKEN); + } + + private static PersonalPairingImportException malformedToken(Throwable cause) { + return new PersonalPairingImportException(ImportValidationError.MALFORMED_TOKEN, cause); + } + + private static PersonalPairingImportException unsupportedVersion() { + return new PersonalPairingImportException(ImportValidationError.UNSUPPORTED_VERSION); + } + + private static String normalizeTokenInput(String input) { + if (input == null) { + throw invalidInputFormat(); + } + + String trimmedInput = input.trim(); + if (trimmedInput.isEmpty()) { + throw invalidInputFormat(); + } + + if (!trimmedInput.contains("://")) { + return trimmedInput; + } + + URI uri; + try { + uri = new URI(trimmedInput); + } catch (URISyntaxException e) { + throw invalidInputFormat(); + } + + String scheme = uri.getScheme(); + if (scheme == null || scheme.isEmpty()) { + throw invalidInputFormat(); + } + + String[] segments = getRawPathSegments(uri.getRawPath()); + + if (PSIPHON_SCHEME.equals(scheme)) { + if (!PSIPHON_PAIR_HOST.equals(uri.getHost())) { + throw invalidInputFormat(); + } + if (segments.length != 1) { + throw invalidInputFormat(); + } + String token = segments[0]; + if (token == null || token.isEmpty()) { + throw invalidInputFormat(); + } + return token; + } + + if (HTTP_SCHEME.equals(scheme) || HTTPS_SCHEME.equals(scheme)) { + return extractTokenFromPairPath(segments); + } + + throw invalidInputFormat(); + } + + private static String extractTokenFromPairPath(String[] segments) { + for (int i = segments.length - 2; i >= 0; i--) { + if (PAIR_PATH_SEGMENT.equals(segments[i])) { + if (i + 2 != segments.length) { + throw invalidInputFormat(); + } + String token = segments[i + 1]; + if (token == null || token.isEmpty()) { + throw invalidInputFormat(); + } + return token; + } + } + throw invalidInputFormat(); + } + + private static String[] getRawPathSegments(String rawPath) { + if (rawPath == null || rawPath.isEmpty() || "/".equals(rawPath)) { + return new String[0]; + } + if (!rawPath.startsWith("/")) { + throw invalidInputFormat(); + } + String[] segments = rawPath.substring(1).split("/", -1); + for (String segment : segments) { + if (segment.isEmpty()) { + throw invalidInputFormat(); + } + } + return segments; + } + + private static byte[] decodeToken(String token) { + if (token == null || token.isEmpty()) { + throw malformedToken(); + } + + if (BASE64URL_PATTERN.matcher(token).matches()) { + try { + return decodeUrlSafeBase64(token); + } catch (IllegalArgumentException e) { + throw malformedToken(e); + } + } + + if (BASE64_PATTERN.matcher(token).matches() && token.length() % 4 == 0) { + try { + return Utils.Base64.decode(token); + } catch (IllegalArgumentException e) { + throw malformedToken(e); + } + } + + throw malformedToken(); + } + + private static String requireNonEmptyString(JsonParser parser) throws IOException { + if (parser.getCurrentToken() != JsonToken.VALUE_STRING) { + throw malformedToken(); + } + String stringValue = parser.getValueAsString(); + if (stringValue.isEmpty()) { + throw malformedToken(); + } + return stringValue; + } + + private static PersonalPairingData parsePayload(byte[] decodedToken) { + try (JsonParser parser = JSON_FACTORY.createParser(decodedToken)) { + if (parser.nextToken() != JsonToken.START_OBJECT) { + throw malformedToken(); + } + + String version = null; + String compartmentId = null; + String alias = null; + int topLevelFieldCount = 0; + + while (parser.nextToken() != JsonToken.END_OBJECT) { + if (parser.getCurrentToken() != JsonToken.FIELD_NAME) { + throw malformedToken(); + } + + String fieldName = parser.getCurrentName(); + topLevelFieldCount++; + parser.nextToken(); + + if (VERSION_KEY.equals(fieldName)) { + version = requireNonEmptyString(parser); + } else if (DATA_KEY.equals(fieldName)) { + if (parser.getCurrentToken() != JsonToken.START_OBJECT) { + throw malformedToken(); + } + + int dataFieldCount = 0; + while (parser.nextToken() != JsonToken.END_OBJECT) { + if (parser.getCurrentToken() != JsonToken.FIELD_NAME) { + throw malformedToken(); + } + + String dataFieldName = parser.getCurrentName(); + dataFieldCount++; + parser.nextToken(); + + if (ID_KEY.equals(dataFieldName)) { + compartmentId = requireNonEmptyString(parser); + } else if (NAME_KEY.equals(dataFieldName)) { + alias = requireNonEmptyString(parser); + } else { + throw malformedToken(); + } + } + + if (dataFieldCount != 2 || compartmentId == null || alias == null) { + throw malformedToken(); + } + } else { + throw malformedToken(); + } + } + + if (topLevelFieldCount != 2 || version == null) { + throw malformedToken(); + } + + if (!SUPPORTED_VERSION.equals(version)) { + throw unsupportedVersion(); + } + + validateCompartmentId(compartmentId); + return new PersonalPairingData(compartmentId, alias); + } catch (PersonalPairingImportException e) { + throw e; + } catch (IOException | RuntimeException e) { + throw malformedToken(e); + } + } + + private static void validateCompartmentId(String compartmentId) { + if (!COMPARTMENT_ID_PATTERN.matcher(compartmentId).matches()) { + throw malformedToken(); + } + + try { + byte[] decoded = decodeUrlSafeBase64(compartmentId); + if (decoded.length != 32) { + throw malformedToken(); + } + } catch (IllegalArgumentException e) { + throw malformedToken(e); + } + } + + private static byte[] decodeUrlSafeBase64(String token) { + int padLength = (4 - (token.length() % 4)) % 4; + String paddedToken = token + "====".substring(0, padLength); + String normalized = paddedToken + .replace('-', '+') + .replace('_', '/'); + return Utils.Base64.decode(normalized); + } + + // Extract personal pairing data from a token string, deep link, or wrapper URL + public static PersonalPairingData extractPersonalPairingData(String input) throws IllegalArgumentException { + String token = normalizeTokenInput(input); + try { + byte[] decodedToken = decodeToken(token); + return parsePayload(decodedToken); + } catch (PersonalPairingImportException e) { + throw e; + } catch (Exception e) { + throw malformedToken(e); + } + } + + // Validate personal pairing data and determine the appropriate action + private ImportResult validatePersonalPairingData(String input) { + try { + PersonalPairingData personalPairingData = extractPersonalPairingData(input); + String storedCompartmentId = prefs.getString(context.getString(R.string.personalPairingCompartmentIdPreference), ""); + Boolean storedEnabled = prefs.getBoolean(context.getString(R.string.personalPairingEnabledPreference), false); + if (storedCompartmentId == null || storedCompartmentId.isEmpty()) { + return ImportResult.promptEnable(personalPairingData); + } else if (storedCompartmentId.equals(personalPairingData.compartmentId)) { + return ImportResult.alreadyExists(personalPairingData); + } else { + return ImportResult.needsUpdate(personalPairingData, storedCompartmentId, storedEnabled); + } + } catch (IllegalArgumentException e) { + ImportValidationError validationError = validationErrorFromException(e); + MyLog.e("PersonalPairingHelper::validatePersonalPairingData error: " + validationError.name()); + return ImportResult.error(validationError); + } + } + + // Handle the import of personal pairing data import and determine the appropriate action + public Single handleImport(@NonNull String input, Flowable tunnelState) { + return Single.fromCallable(() -> validatePersonalPairingData(input)) + .flatMap(result -> { + if (result.action == ImportResult.Action.PROMPT_ENABLE) { + // If importing a new pairing while the tunnel is running, prompt the user to enable + // the feature because enabling the feature will restart the tunnel + // Otherwise, enable the feature automatically without prompting + return tunnelState + .firstOrError() + .map(state -> { + if (state.isRunning()) { + // Pass through the PROMPT_ENABLE result to trigger the prompt UI + return result; + } else { + // Enable the feature automatically, pass SHOW_SUCCESS result to trigger import success UI + setPersonalPairingState(true, result.data); + return ImportResult.success(result.data); + } + }); + } + return Single.just(result); + }); + } + + // Save the personal pairing data after user confirmation and sets the feature enabled flag + public void confirmImport(PersonalPairingData data, boolean enableSetting) { + setPersonalPairingState(enableSetting, data); + } + + // Reset all personal pairing preferences + public static void resetPersonalPairingPreferences(Context context) { + AppPreferences prefs = new AppPreferences(context); + prefs.remove(context.getString(R.string.personalPairingEnabledPreference)); + prefs.remove(context.getString(R.string.personalPairingCompartmentIdPreference)); + prefs.remove(context.getString(R.string.personalPairingAliasPreference)); + } +} diff --git a/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingPreferenceActivity.java b/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingPreferenceActivity.java new file mode 100644 index 000000000..2836edb9d --- /dev/null +++ b/app/src/main/java/com/psiphon3/psiphonlibrary/PersonalPairingPreferenceActivity.java @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2020, Psiphon Inc. + * All rights reserved. + * + * 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 . + * + */ + +package com.psiphon3.psiphonlibrary; + +import android.app.AlertDialog; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.text.InputFilter; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.lifecycle.ViewModelProvider; +import androidx.preference.CheckBoxPreference; +import androidx.preference.EditTextPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.psiphon3.MainActivityViewModel; +import com.psiphon3.R; + +public class PersonalPairingPreferenceActivity extends LocalizedActivities.AppCompatActivity { + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .add(android.R.id.content, new PersonalPairingPreferenceFragment()) + .commit(); + } + + MainActivityViewModel viewModel = new ViewModelProvider(this, + new ViewModelProvider.AndroidViewModelFactory(getApplication())) + .get(MainActivityViewModel.class); + getLifecycle().addObserver(viewModel); + } + + public static class PersonalPairingPreferenceFragment extends PsiphonPreferenceFragmentCompat + implements SharedPreferences.OnSharedPreferenceChangeListener { + + private CheckBoxPreference enabledPref; + private Preference importPref; + private EditTextPreference compartmentIdPref; + private EditTextPreference aliasPref; + private Preference resetPref; + private Toast currentToast; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + super.onCreatePreferences(savedInstanceState, rootKey); + addPreferencesFromResource(R.xml.personal_pairing_preferences); + final PreferenceScreen preferences = getPreferenceScreen(); + + // Initialize preferences + enabledPref = preferences.findPreference(getString(R.string.personalPairingEnabledPreference)); + importPref = preferences.findPreference(getString(R.string.personalPairingImportPreference)); + compartmentIdPref = preferences.findPreference(getString(R.string.personalPairingCompartmentIdPreference)); + aliasPref = preferences.findPreference(getString(R.string.personalPairingAliasPreference)); + resetPref = preferences.findPreference(getString(R.string.personalPairingResetPreference)); + + // Set initial values from current preferences + final PreferenceGetter preferenceGetter = getPreferenceGetter(); + enabledPref.setChecked(preferenceGetter.getBoolean(getString(R.string.personalPairingEnabledPreference), false)); + compartmentIdPref.setText(preferenceGetter.getString(getString(R.string.personalPairingCompartmentIdPreference), "")); + aliasPref.setText(preferenceGetter.getString(getString(R.string.personalPairingAliasPreference), "")); + + // Set up import button click listener + importPref.setOnPreferenceClickListener(preference -> { + showImportDialog(); + return true; + }); + + // Set up name preference change listener + aliasPref.setOnPreferenceChangeListener((preference, newValue) -> { + if (TextUtils.isEmpty(compartmentIdPref.getText())) { + showToast(R.string.personal_pairing_need_compartment_id, Toast.LENGTH_SHORT); + return false; + } + return true; + }); + + // Set up enabled preference change listener + enabledPref.setOnPreferenceChangeListener((preference, newValue) -> { + boolean newEnabled = (Boolean) newValue; + if (newEnabled && TextUtils.isEmpty(compartmentIdPref.getText())) { + showToast(R.string.personal_pairing_need_compartment_id, Toast.LENGTH_SHORT); + return false; + } + return true; + }); + + // Set up reset click listener + resetPref.setOnPreferenceClickListener(preference -> { + showResetDialog(); + return true; + }); + + updatePersonalPairingPreferencesUI(); + } + + private void showImportDialog() { + View dialogView = LayoutInflater.from(getContext()) + .inflate(R.layout.dialog_import_pairing, null); + EditText urlInput = dialogView.findViewById(R.id.url_input); + + new AlertDialog.Builder(requireContext()) + .setTitle(R.string.personal_pairing_import_dialog_title) + .setView(dialogView) + .setPositiveButton(R.string.import_button, (dialog, which) -> { + String url = urlInput.getText().toString(); + try { + PersonalPairingHelper.PersonalPairingData data = PersonalPairingHelper.extractPersonalPairingData(url); + updatePairingData(data); + // Also enable the feature automatically + enabledPref.setChecked(true); + } catch (IllegalArgumentException e) { + showToast(getPairingImportErrorString( + PersonalPairingHelper.validationErrorFromException(e)), Toast.LENGTH_LONG); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + + private void showResetDialog() { + String compartmentId = compartmentIdPref.getText(); + + // Guard against empty ID + if (compartmentId == null || compartmentId.isEmpty()) { + showToast(R.string.personal_pairing_reset_error, Toast.LENGTH_SHORT); + return; + } + + // Determine how many characters to request + int charsToRequest = Math.min(compartmentId.length(), 4); + String lastChars = compartmentId.substring(compartmentId.length() - charsToRequest); + + View dialogView = LayoutInflater.from(getContext()) + .inflate(R.layout.dialog_reset_pairing, null); + + TextView messageText = dialogView.findViewById(R.id.delete_message); + TextView symbolsText = dialogView.findViewById(R.id.delete_symbols); + + messageText.setText(getString(R.string.personal_pairing_delete_message, charsToRequest)); + symbolsText.setText(lastChars); + + EditText deleteInput = dialogView.findViewById(R.id.delete_input); + deleteInput.setFilters(new InputFilter[] { new InputFilter.LengthFilter(charsToRequest) }); + + AlertDialog dialog = new AlertDialog.Builder(requireContext()) + .setTitle(R.string.personal_pairing_reset_dialog_title) + .setView(dialogView) + .setPositiveButton(R.string.reset_button, null) // Set listener later to prevent auto-dismiss + .setNegativeButton(android.R.string.cancel, null) + .create(); + + // Allow pressing enter to submit + deleteInput.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_DONE) { + Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + if (positiveButton != null) { + positiveButton.performClick(); + } + return true; + } + return false; + }); + + dialog.setOnShowListener(dialogInterface -> { + Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + button.setOnClickListener(view -> { + String input = deleteInput.getText().toString(); + if (lastChars.equals(input)) { + resetPairingPreferences(); + showToast(R.string.personal_pairing_reset_success, Toast.LENGTH_SHORT); + dialog.dismiss(); + } else { + showToast(R.string.personal_pairing_reset_invalid, Toast.LENGTH_SHORT); + } + }); + }); + + dialog.show(); + } + + private void resetPairingPreferences() { + compartmentIdPref.setText(""); + compartmentIdPref.setSummary(R.string.personal_pairing_compartment_id_summary); + aliasPref.setText(""); + aliasPref.setSummary(R.string.personal_pairing_alias_summary); + enabledPref.setChecked(false); + PersonalPairingHelper.resetPersonalPairingPreferences(getContext()); + } + + private void updatePairingData(PersonalPairingHelper.PersonalPairingData data) { + compartmentIdPref.setText(data.compartmentId); + aliasPref.setText(data.alias); + updatePersonalPairingPreferencesUI(); + } + + private void updatePersonalPairingPreferencesUI() { + boolean hasCompartmentId = !TextUtils.isEmpty(compartmentIdPref.getText()); + boolean isEnabled = enabledPref.isChecked(); + + // Update preference states + aliasPref.setEnabled(hasCompartmentId); // Keep editable if compartment ID is set even if the feature is disabled + resetPref.setEnabled(hasCompartmentId); + + compartmentIdPref.setEnabled(isEnabled && hasCompartmentId); + + // If no compartment ID, ensure feature is disabled + if (!hasCompartmentId && isEnabled) { + enabledPref.setChecked(false); + } + + // Update compartment ID and alias summaries if the compartment ID is set, otherwise show the default summary + if (hasCompartmentId) { + String compartmentId = compartmentIdPref.getText(); + compartmentIdPref.setSummary(!TextUtils.isEmpty(compartmentId) ? compartmentId : null); + + String name = aliasPref.getText(); + aliasPref.setSummary(!TextUtils.isEmpty(name) ? name.replace("\n", " ") : null); + } + } + + private void showToast(@StringRes int messageId, int toastLength) { + if (currentToast != null) { + currentToast.cancel(); + } + currentToast = Toast.makeText(getContext(), messageId, toastLength); + currentToast.show(); + } + + @StringRes + private int getPairingImportErrorString(PersonalPairingHelper.ImportValidationError validationError) { + if (validationError == PersonalPairingHelper.ImportValidationError.UNSUPPORTED_VERSION) { + return R.string.personal_pairing_unsupported_version; + } + if (validationError == PersonalPairingHelper.ImportValidationError.INVALID_INPUT_FORMAT) { + return R.string.personal_pairing_invalid_url; + } + return R.string.personal_pairing_invalid_data; + } + + @Override + public void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences() + .registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onPause() { + super.onPause(); + getPreferenceScreen().getSharedPreferences() + .unregisterOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + updatePersonalPairingPreferencesUI(); + } + } +} diff --git a/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelManager.java b/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelManager.java index 36037956f..267f01c91 100644 --- a/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelManager.java +++ b/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelManager.java @@ -130,8 +130,9 @@ enum ServiceToClientMessage { static final String DATA_TUNNEL_STATE_CLIENT_REGION = "clientRegion"; static final String DATA_TUNNEL_STATE_SPONSOR_ID = "sponsorId"; public static final String DATA_TUNNEL_STATE_HOME_PAGES = "homePages"; - public static final String DATA_TUNNEL_STATE_VPN_MODE = "vpnMode"; - public static final String DATA_TUNNEL_STATE_VPN_APPS = "vpnApps"; + public static final String DATA_TUNNEL_STATE_VPN_MODE = "vpnMode"; + public static final String DATA_TUNNEL_STATE_VPN_APPS = "vpnApps"; + public static final String DATA_TUNNEL_STATE_IS_PERSONAL_PAIRING_MODE = "isPersonalPairingMode"; static final String DATA_TRANSFER_STATS_CONNECTED_TIME = "dataTransferStatsConnectedTime"; static final String DATA_TRANSFER_STATS_TOTAL_BYTES_SENT = "dataTransferStatsTotalBytesSent"; static final String DATA_TRANSFER_STATS_TOTAL_BYTES_RECEIVED = "dataTransferStatsTotalBytesReceived"; @@ -153,6 +154,7 @@ static class Config { boolean disableTimeouts = false; String sponsorId = EmbeddedValues.SPONSOR_ID; String deviceLocation = ""; + String personalPairingCompartmentId = ""; } private Config m_tunnelConfig; @@ -172,8 +174,9 @@ public static class State { String clientRegion = ""; String sponsorId = ""; ArrayList homePages = new ArrayList<>(); - VpnAppsUtils.VpnAppsExclusionSetting vpnMode = VpnAppsUtils.VpnAppsExclusionSetting.ALL_APPS; - ArrayList vpnApps = new ArrayList<>(); + VpnAppsUtils.VpnAppsExclusionSetting vpnMode = VpnAppsUtils.VpnAppsExclusionSetting.ALL_APPS; + ArrayList vpnApps = new ArrayList<>(); + public boolean isPersonalPairingMode; boolean isConnected() { return networkConnectionState == TunnelState.ConnectionData.NetworkConnectionState.CONNECTED; @@ -345,7 +348,6 @@ private Disposable connectionStatusUpdaterDisposable() { } return Observable.just(networkConnectionState); }) - .distinctUntilChanged() .doOnNext(networkConnectionState -> { m_tunnelState.networkConnectionState = networkConnectionState; sendClientMessage(ServiceToClientMessage.TUNNEL_CONNECTION_STATE.ordinal(), getTunnelStateBundle()); @@ -536,6 +538,18 @@ private Single getTunnelConfigSingle() { tunnelConfig.disableTimeouts = multiProcessPreferences .getBoolean(getContext().getString(R.string.disableTimeoutsPreference), false); + boolean personalPairingModePreference = multiProcessPreferences.getBoolean( + getContext().getString(R.string.personalPairingEnabledPreference), false); + + // If personal pairing is enabled, get the compartment ID from the preferences + String compartmentId = ""; + if (personalPairingModePreference) { + compartmentId = multiProcessPreferences.getString(getContext().getString(R.string.personalPairingCompartmentIdPreference), ""); + if (TextUtils.isEmpty(compartmentId)) { + MyLog.w("TunnelManager::getTunnelConfigSingle: personal pairing is enabled but the compartment ID is empty."); + } + } + tunnelConfig.personalPairingCompartmentId = compartmentId; return tunnelConfig; }); @@ -565,7 +579,7 @@ private Notification createNotification( int defaults = 0; if (networkConnectionState == TunnelState.ConnectionData.NetworkConnectionState.CONNECTED) { - iconID = R.drawable.notification_icon_connected; + iconID = isPersonalPairingMode() ? R.drawable.notification_icon_connected_pp : R.drawable.notification_icon_connected; switch (vpnAppsExclusionSetting) { case INCLUDE_APPS: contentText = getContext().getResources() @@ -587,7 +601,7 @@ private Notification createNotification( contentText = getContext().getString(R.string.waiting_for_network_connectivity); ticker = getContext().getText(R.string.waiting_for_network_connectivity); } else { - iconID = R.drawable.notification_icon_connecting_animation; + iconID = isPersonalPairingMode() ? R.drawable.notification_icon_connecting_animation_pp : R.drawable.notification_icon_connecting_animation;; contentText = getContext().getString(R.string.psiphon_service_notification_message_connecting); ticker = getContext().getText(R.string.psiphon_service_notification_message_connecting); } @@ -636,6 +650,10 @@ private Notification createNotification( .build(); } + private boolean isPersonalPairingMode() { + return m_tunnelConfig != null && !TextUtils.isEmpty(m_tunnelConfig.personalPairingCompartmentId); + } + /** * Update the context used to get resources with the passed context * @@ -831,8 +849,6 @@ private static void setLocale(TunnelManager manager) { manager.m_context = localeManager.setNewLocale(manager.m_parentService, languageCode); } manager.updateNotifications(); - // Also update upgrade notifications - UpgradeManager.UpgradeInstaller.updateNotification(manager.getContext()); } private Message composeClientMessage(int what, Bundle data) { @@ -893,10 +909,11 @@ private Bundle getTunnelStateBundle() { data.putString(DATA_TUNNEL_STATE_CLIENT_REGION, m_tunnelState.clientRegion); data.putString(DATA_TUNNEL_STATE_SPONSOR_ID, m_tunnelState.sponsorId); data.putStringArrayList(DATA_TUNNEL_STATE_HOME_PAGES, m_tunnelState.homePages); - data.putSerializable(DATA_TUNNEL_STATE_VPN_MODE, m_tunnelState.vpnMode); - data.putStringArrayList(DATA_TUNNEL_STATE_VPN_APPS, m_tunnelState.vpnApps); - return data; - } + data.putSerializable(DATA_TUNNEL_STATE_VPN_MODE, m_tunnelState.vpnMode); + data.putStringArrayList(DATA_TUNNEL_STATE_VPN_APPS, m_tunnelState.vpnApps); + data.putBoolean(DATA_TUNNEL_STATE_IS_PERSONAL_PAIRING_MODE, isPersonalPairingMode()); + return data; + } private Bundle getDataTransferStatsBundle() { Bundle data = new Bundle(); @@ -948,9 +965,6 @@ private void runTunnel() { m_networkConnectionStatePublishRelay.accept(TunnelState.ConnectionData.NetworkConnectionState.CONNECTING); m_isRoutingThroughTunnelPublishRelay.accept(Boolean.FALSE); - // Notify if an upgrade has already been downloaded and is waiting for install - UpgradeManager.UpgradeInstaller.notifyUpgrade(getContext(), PsiphonTunnel.getDefaultUpgradeDownloadFilePath(getContext())); - MyLog.i(R.string.starting_tunnel, MyLog.Sensitivity.NOT_SENSITIVE); m_tunnelState.homePages.clear(); @@ -1253,17 +1267,7 @@ public static String buildTunnelCoreConfig( json.put("ClientVersion", EmbeddedValues.CLIENT_VERSION); - if (UpgradeChecker.upgradeCheckNeeded(context)) { - - json.put("UpgradeDownloadURLs", new JSONArray(EmbeddedValues.UPGRADE_URLS_JSON)); - - json.put("UpgradeDownloadClientVersionHeader", "x-amz-meta-psiphon-client-version"); - - json.put("EnableUpgradeDownload", true); - } - - json.put("MigrateUpgradeDownloadFilename", - new UpgradeManager.OldDownloadedUpgradeFile(context).getFullPath()); + json.put("EnableUpgradeDownload", false); json.put("PropagationChannelId", EmbeddedValues.PROPAGATION_CHANNEL_ID); @@ -1369,6 +1373,11 @@ public static String buildTunnelCoreConfig( json.put("EmitBytesTransferred", true); + // Set the personal pairing config if config has a non-empty personal pairing compartment ID + if (!TextUtils.isEmpty(tunnelConfig.personalPairingCompartmentId)) { + json.put("InproxyClientPersonalCompartmentID", tunnelConfig.personalPairingCompartmentId); + } + return json.toString(); } catch (JSONException e) { return null; @@ -1384,8 +1393,7 @@ private Observable>) Pair::new)) .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .distinctUntilChanged(); + .observeOn(AndroidSchedulers.mainThread()); } /** @@ -1669,16 +1677,6 @@ public void run() { }); } - @Override - public void onClientUpgradeDownloaded(String filename) { - m_Handler.post(new Runnable() { - @Override - public void run() { - UpgradeManager.UpgradeInstaller.notifyUpgrade(getContext(), filename); - } - }); - } - @Override public void onUntunneledAddress(final String address) { m_Handler.post(new Runnable() { diff --git a/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelServiceInteractor.java b/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelServiceInteractor.java index 4053f936e..2249a3c6d 100644 --- a/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelServiceInteractor.java +++ b/app/src/main/java/com/psiphon3/psiphonlibrary/TunnelServiceInteractor.java @@ -298,6 +298,7 @@ private static TunnelManager.State getTunnelStateFromBundle(Bundle data) { if (vpnApps != null) { tunnelState.vpnApps = vpnApps; } + tunnelState.isPersonalPairingMode = data.getBoolean(TunnelManager.DATA_TUNNEL_STATE_IS_PERSONAL_PAIRING_MODE); return tunnelState; } @@ -352,6 +353,9 @@ public void handleMessage(Message msg) { .setHomePages(state.homePages) .setVpnMode(state.vpnMode) .setVpnApps(state.vpnApps) + .setVpnMode(state.vpnMode) + .setVpnApps(state.vpnApps) + .setPersonalPairingEnabled(state.isPersonalPairingMode) .build(); tunnelState = TunnelState.running(connectionData); } else { diff --git a/app/src/main/res/drawable-hdpi/notification_icon_connected_pp.png b/app/src/main/res/drawable-hdpi/notification_icon_connected_pp.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9b05d486b6beb66e4109c3bc025a6d4696deaa GIT binary patch literal 788 zcmV+v1MB>WP)Qzm3cU4V8!+)v(z&84l z4%OH`I>z@`7B*<3@9=l{PIve|OTy%-^pPu)hL7|N?WSGyFnv~(p+C0G_nin6`{`Hu zt%Sd0)dZf?WpKBI-)GQU#i_V!b4tR*#T9%yTyi8==`18XBfK_;zBajoJ|{IS(n#N$ zqB2_#=?QuodaFOt9wZOyY@sQx`FLueQ~x;>lxJlNZ8UKi@CNAH)MML*_@2;K==1T^ zu*eeVTk?}`_wfj08=*5f+g(3U7!UT^SSDCxeJJ*Tj`Q&dW8*{4aHr7OyBXRG>uj4$ zNC%-`7MTQn-Gv`?fbOKtCTAi&NMF!F+F@&i92xXn ze?2uU(n^0pfBhzue}-D18?4-(lDD=hSa=QeHZAb6B*IJ_qVMT^AFmqd?dkN_%Mk{3 zh2B7!g)|e;L)(ZAvl7tVKkj?&bRo?CR~I;dODG^`rn(Pkml@E2kEe!3n&?V@eYCLc z(J&Y}KOOP$)Ue0|=>Ag)IV<^p8E-;N26G&>xLwc(vl?VU?M1ELG!|OnIuPWzx{59x zg^N&&nTfF2RvCd~pU=w;=!)y<_IbI1;(rT~z94}pX3h#RJ5&V SDO^+l0000 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_01.png b/app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_01.png new file mode 100644 index 0000000000000000000000000000000000000000..cb266a8db3f21ebe03e73c2c7c70320555350541 GIT binary patch literal 1066 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_05.png b/app/src/main/res/drawable-hdpi/notification_icon_connecting_pp_05.png new file mode 100644 index 0000000000000000000000000000000000000000..106a79226a284a1d3918273679674b3bc23131e6 GIT binary patch literal 1112 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwXFs$lTHUje4OFVsD*EamTaeV1D-;9`08P*T?XZQO|K6hl>Lc@sxYqyFB%CfL-ogG!ajZ<%lL|0R{ z(vGs{ZsC_&0|G>Lt>_98nAjC|CG_BQa9?GD;xw8N-LdMYC;QV`OQuI>oU6Q^n)>8z z;ej;A6g#UMYcyV8X7LT!5M6&qxbw`f3r8zTE_%M^JITc+tzGI@wtTuMi{|TTQ(V3L zejahMv3ua^D!Qms%{8z|`M?H7M*ClPT(jA19~CCw>sdMN&w`Gx*EU2?oGv!=Q=8<6 z+1z@S=XN~)*i$dC^WKWKa}tw^E`QYW4H2!nrCHs3MC_Qr&&}q6Ps}o($F971Nr|w#5<$#U{J49K3qZyv(dq%vT)YEZZ7pu;h_m z^VUNgTNicwNx8=)FJmH?Ej#9h2^|N;gqb4>DWpKR1UY|p#rDN9Qn1r~j%v5rSvX)l*)$jfoh^qZU%>fc)KWXRL1t2o&v;I^^X>4=wa><+A${$$D& znZm7q&*Ux0S*khx2y0r5Vb1J@Pc(0JW*lJK8?aF$;oAM)bJMK2J~XuZZ1>Evd2ZWb zsjge5%2a+M`2ReY*hRBS&%8_tS6>v}GGoOf{@1h0^8_M4>@z<5e$`x!)dA<CYsl(>yWsBxG&COVNJTA*oIIyASZwgOXwDG%jtM>M7 zI~Kp?MA73dFJG-_-|ATV@sjt+rtZSsoWaX_Za-LjuXKy2h<4Q0D`rt!;t!hs&iRu2 zH-CY0;Hf4?%{AN7THfz@zUQ^wgwNUG#~ICTy^H&P`{|nSHCz6Q{+WK@AOAnrjf<2% z%uq_Q2WBnR64!{5l*E!$tK_0oAjM#0U}U0eXryas8DeB$Wom9^XsB&qU}a#y%w3v- yq9HdwB{QuOw}zsyvp0YmG~hOrWag$8mn7yE;MSw+{DvK|k0wldT1B8K;Lb6AYF9SoB8UsT^3j@P1pisjL z28L1t28LG&3=CE?7#PG0=Ijcz0ZK3>dAqwXFs$lTHUje4OFVsD*EamTaeV4E-;9`0iDMt{&+YdyK6Auuq2a`UD^Xn?Y>tj^mtC7{cC=N*Iq=0I zj&*l;UQ88tas;xqoE#msZvEP*6%n%{Vx>oBmUfiktSdKW9Pycz@@&TpYvb~?cRb(r zcJKT?r}+Q#%K5+N6{|5Z-FdCL`0H)AV0V?SngPsnho;yl#-T%PzTYYX5kG)9f!nOT-TCB=2$=Vg{3 zc6;kpADlAzV@JK<&&{E{FAbF*w@ohf2@$V47x}yAsHTs?rVH{SJDsofuQM|!d=;;G zgHz3it7+-Km8nw;?xyXo7Bg&1ynKx1;MRW&98(WEgjdUn-j> zy@xn@7j^u}IjJchJ#FJfop!kej;yBEZ&y1fomsIw=Hu#Br~NFR@oTU9?xTAk%+m4P zmIvI~5AxdI7KEt!y^=N!)^&X;*Q?nPa#qS9fmibJrYt%0Y%{siIMrjXerWi*UY=+C ze2TuV+O94+)7*>Fb)I2f{TxmraXiNlGdpJdy1avb_u-(Fqkh?jbRSO#}!+UQfs_g7u*4VY}g}A9U)3d*qv)-&&%)noHBxm}PYsDuIN0i+1 z@)y`~`QEcip|2aV?r}b!gPB#swES3t?c1p-N4GC~xo+{> zkDX$X*>BCZui)U3>`;&O6^n8I6};`oih9{x(W710)_!B)y}ka$?PvQNLjsO%TEuhh zvhATJevv=d?6(^0?YiGw7X5-V>if(80DJU9p^HVa@DsgKl3OjoPs6hj6 gLrG?CYH>+oZUJsRs?KlNfqED`UHx3vIVCg!0QQjG>;M1& literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/status_icon_connected.png b/app/src/main/res/drawable-hdpi/status_icon_connected.png deleted file mode 100644 index 406eb6fd364f90bed5bf36bff34b793994cc418e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3971 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 diff --git a/app/src/main/res/drawable-hdpi/status_icon_connecting.png b/app/src/main/res/drawable-hdpi/status_icon_connecting.png deleted file mode 100644 index 06c3cec4ddd7348da5b13420a9a333b7570850b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5371 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 Xe&#g4KenX))TA*sgc(%nJH`GFk9j^E diff --git a/app/src/main/res/drawable-hdpi/status_icon_disconnected.png b/app/src/main/res/drawable-hdpi/status_icon_disconnected.png deleted file mode 100644 index 5bfb44ec784d137f24967fcb490e9ce75987588f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2265 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_01.png b/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_01.png new file mode 100644 index 0000000000000000000000000000000000000000..750c924e262a96bbe40a66f737a5253e753bd1c8 GIT binary patch literal 739 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_05.png b/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_05.png new file mode 100644 index 0000000000000000000000000000000000000000..d03bfca1b0f49b155221bc7608f79d1b8039cd17 GIT binary patch literal 765 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1g=CK)Uj~LMH3o);76yi2K%s^g z3=E|P3=FRl7#OT(FffQ0%-I!a1C(G&@^*J&U|7|wYy{-7mw5WRvcKRF7O~_uepb1V zfr0U%r;B5V#p$V+&w7U>im-jSFDrZHV$O_BW~@QE%g)#>Fk^G+zd5b$7G{ep~} zyZ$x*YYP-aSDYbyR~dOvElW_q@X6*b1xlK76}BmWK)Ooz2ZmM?6>2G0ixzofIg{mLy ztJM7!Ghw^PTu-S7VX3VV7gck;(x#T&d^TCtdDqwMg?=-F+`H$$t5m;{ejr!=<3UYr zO{b9XsDQHL#UFg$w4C>{GWi+!b)jJN*^1!P_fBcQC<)m-^NUw#%9EpyqU0tN2d%&H zq)K=bmznmpPm3%k&#THf_@zoXsx-qm;h4lXi}w>RPp) zPTPrFr5ta_u4|2TeCzTsVu#c=^~hJ=*G0Z1m}rJe&)Is^SNoq^Z_9*?2*1iH3m$Z( zEoNIhb*tXg>svmb-Xb^mRJLpSm)lEJRGPF5SHGCO@Ks-?(>2E5M^8P|y3ROJ)4V5S z_NA7vx2Gh^wr`4Bal<+~-%I#bu87Mq-!*|j#p=3M&0;LwtN-}%W~+#7;qt0mo^_Y+ zWs%D{s}?_Bqp&ke@4YX*(dBLgc_b1OqbZ36=<0|RF6(i9X8x%nxX sX_dG&6os9=0o0%Yx1l66H?_DVF}DD>9#!Wz>_9yXp00i_>zopr0EM+S4gdfE literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_06.png b/app/src/main/res/drawable-mdpi/notification_icon_connecting_pp_06.png new file mode 100644 index 0000000000000000000000000000000000000000..a645e642a79af0476abcf78a961748577eef6d41 GIT binary patch literal 756 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 Z{{rjRtL_=AW1Ij0002ovPDHLkV1h$UDxClT diff --git a/app/src/main/res/drawable-mdpi/status_icon_connecting.png b/app/src/main/res/drawable-mdpi/status_icon_connecting.png deleted file mode 100644 index 6c7904bf64e9f822a6d82d46a3122a610cfe6828..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2770 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 diff --git a/app/src/main/res/drawable-mdpi/status_icon_disconnected.png b/app/src/main/res/drawable-mdpi/status_icon_disconnected.png deleted file mode 100644 index 6400d79956f044402a5c94ecf72f3832a8f3443b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1391 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_06.png b/app/src/main/res/drawable-xhdpi/notification_icon_connecting_pp_06.png new file mode 100644 index 0000000000000000000000000000000000000000..dcc4a7137b975ef7011d583aa510114c59b7acbc GIT binary patch literal 1431 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 diff --git a/app/src/main/res/drawable-xhdpi/status_icon_connecting.png b/app/src/main/res/drawable-xhdpi/status_icon_connecting.png deleted file mode 100644 index d974f3582ac15625c522b13bb0284f2b1cfbc828..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7514 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 c5)KHO?&iKe*lGHa_`jvTjM00001b5ch_0Itp) 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 H;KqLdJs`x4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_02.png b/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_02.png new file mode 100644 index 0000000000000000000000000000000000000000..5e47f8a8dff79e73111dd19f7443bdb9020aff6b GIT binary patch literal 2118 zcmZ{lc{tPy7sr2O&ypBPrnA^y7uFUXEP!u&}cMfKWvMh>izQIOCsBLl|-f-0s%q zrT|cxDi7m0e!QiP8UK>7gruI3>8#}yP6Dwsy>{1U`p5Xhb6I;Z|N8CSUKes+-y@`3 zB9Ag}CR~W`7d~VRSyDyilprMOZ`Vxq_xH-}k3ddl8vq7@;eB{LT#!iaaOKH(20J4u zA#vk0IdA{_`)rnX$oS*Jf?K;=y*n(GmAF>o@=Lvly^#0JeS_8+J!VM4v4$X7NIr+T zf8I)J#39$saw+8utB)IARa*LSeouybfMw;oybX@y!}!GqJ=`aE*4HyUJ(L`OoTFhZ zd-?F$HLJZBn+byPK~$B-0r`39?KSf*9DUPm0{z+fkS9$4=-mk`rWxP;43wb#FB}tV_sDK@|M$I1_#q8)cx zw=yUCuXEjX3DXtLJy;n)25tC)|+ZL{joD9T|amq5eo8%DIH}hp&KH*25 zZJ1G7a&9I_zw!kL88GO4gf_LTn6mm~T`8F~vZ^qlsU-`oc=t-4w~An5BxE0df%3Vj z+F|M{_NhU{h*MAafWp3(C7wO@ll@e$Y4vF67o!SoA|R&qYkmbJ+ziSLHU8e!YMa^(p)-u<7IUdJRMX zZSkgMHWpsAIJ#!$Uq`SP;718xjy>0VMl5N5xJxK`8*4$BTxQT2c^Oo?(c{c^R-`ZMj!YhYcb z6*hXjrzpKd_U%{duC+3W=TAaerF_gCHH8akHBnF>>CB*vMM+BY7iNTV?bgYBO@>gh z=t(RUGsz`w*Nzc$M)|t4MUgtW;g{ZhmRllI$mxwl4NLLbS~-53i^J8PazpOlFrh(1 zvNxuDA*DVKTEW{)7HlbK-1Nweo8J(X$iL-?ILmmBzJLvehb$4H_$GVM4AJe^Sm!Ex ze82f(yT%EZjR($1&=Zkhn!U-LG<)*b(oh*j!92p+tiix`WGiqm*+u)(DeBxUZ1i{g z2(c}K6)Lx!T@!pR95ECSrC|)Z*!?U4$Hr#ICt$OC`cg^;=PCy!1dSB8Xq%9xSQv%3 zaGe?}o+n%7Al?zAcz%? zd_hCqkd~6RfTn{H;@uW;6j($JLL`QlqZn`tD^B21mD^u-MM#Z0*rr z=@o>@x0F#_;*H3b5jfAAme(_y4piqM^i}I{MBM8I*$oH^^<~9 z>C%*E@<@INEa)eUi6R2Q1tP@osMhTKQ%-A2j|_=12V^^+I$Ubw=WpoNR5b{-RaV$r zWbnEH4x@&+ldx6TM_1WUFbYs7DpFLkT!af&%>0#(%L1`O$sHbVN zgxu-BqF$`?hlYC?!S|`%+6s1Wmr>u@B9+t4PW`*hLRmP-$%_=0Vpse7Hfj&Dom>t& z7DCn!Igg1f0(ZyK`?ec9Qoqv)cc%|{s=qFYS&a#?VT>PiN4-OVg4&^?`DH?aa7=%< z|9zXZ(6O*oLwWV$wBF%1ACTWzA5vWe%&v^sh$C_577<>5T?1wFCYI#yw5{x#F=ak} zK6$yftDH}5Ea&B8UrRO@gu&_(DDcPAj&#(2DvmCs-M31Z8yR9*8JqBKV!OFZ6NQhW zB;n?Y;`8)l=jiWVvX;Dx-iwo=H>0Jz@@LJzEDRW{nJmU_HpuAEe?QO#79Z^2zSQ6K z1jVXzG|sBlSrv}qJ?r74vZ||VW?P5b2SqNo+)q=R1F8u)~&%qwe#Cd{r z?i~*(HOsjCvURqxa?sDRf!xgvAoq=ODPE4V=_8zJY87;xFbpgHRBx$g8q_}bjKr6s z=N-0F*;u= zE{h-T+2s-zv^=sZDz*X-L~2bOpV)6*NRK*ky#mHe4!&B%d87(>vwL_?H@ug=N1zu+ z02maerK$l_)zG^OgX(Kv(bs?~L!tUmXnA<#;Qs+QKTotb;okwqFZBBy;PU@2;L$j* a2Y5G}|GzVFTFg2Q16Z2bnpR(Tjr|89nCQs> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_03.png b/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_03.png new file mode 100644 index 0000000000000000000000000000000000000000..8a1287698a955f2ddbabd7cafadf38034f1da2df GIT binary patch literal 2166 zcmZ{lc{tPy7sr2NZ!9Hbuj|UZGL|t4GnQL11|cQ}V~H4B#x{fOyE3*U8f6>ZF_tmN znypCIWU?nq*^{NR6r$_>=Y5{{kNd|tpXYqf^LfsnC&}Cl%@39U0|3BpWT=lhrs02! zhvT^aUI=@0j6YlqF{S_z3ITxVcmUWxj-popAP@!st4;ubqyT`ZUv86y_VI%4)-|*~ z0Fj3t*I$d35O8fm!^mXTROAL+JlH?#H-&F4%-Al#qaFF za>-@Tf$H<5q4`}r$fK0{blUAOFvdMdu3>wRDHAuU(IL?i@!qY%^pfpO^4QPfw_c}f zK+`LdNH~wLJ)1MXaxL+xHl5uu+t2+3>Lx{LS-fD5Jw;(j+h#JdxwfO#-Q7I>ocXQqg@tzr`NwB? ziEr*#6f`zD(uW{la_}%TcCR%5v4X7c#OHf4UW+vJ{-L4u;#PZcC|`uPy626O;p&%M z4Pmoi9O1$=A5>NMSxM7T%@p3imF~7-tMkgXI4O8>tp$`?zcTl6Rzq41wt)PMfPAT#VZ@5 z`W!WWmIY=Xv=MjF7&l2c&Y66}Xs7N_&JHK!FtMx}mG+5)CR*IG=&vR0un4+VPO>-A z-w1xfK4P0c4^Eq$YZZs7VfKTD)Q%GEri}WOrA3B=gb(JYKuSYaUcsHbM^+#i{?GBE z;ff=^uW4a|_IL}<4l073{1Kk~I&O|)UGvfM;d-FqyGu-C52p&6$h(bjBHvDS>>R36 zqEs5fMyY*uo@uJj6!9tXsPia7Ty~J77X%d^G0wc?E>0Npk|CFiPT>h5=G#9p*SvYyhJF|bGA-{x0mK5ez-+3a(gN&0Y^H|Hxb zSA&5>k?OALF*^#Sg?%|y?p!b784pqk>g&p6T*v5pGkRoh+^fCt*tk|q?0TiLgiA?( zmYi_K##e)NL^DTdD>fsF(s3nyHIN<&?T-sZuDhfPtOiZv6PYzlYg$%o`hInRxZK?< zrG6cS?!P*M=Gm&-%`WnKbXAkHo2-NLns}#f=kzFdmrxu9LON;^IoU*Wy#-iBFsA`VJ~Ww z*fGjjl3=N=>=(%VGL6-TKTLQOcU?}}KEMihIz?@6j@pr@5GnVR({YYxVdp{yeD1p2 z|K$u1tr*`#a%SY^r*27Q?J_y3f|qq7nbzlFo_7f|$p@mA<0<&(sclTV1*I2Tk!?#7 z;(F6yp4{!0b^o5qItlW}_+`F36UG{z-&{ip6s6P@YJaU0tCCR8zkFKWBy8G6fE+&d zDtjR(gUCj9N)Vvytn*t0NayjFl72_i!{uw+*p_C0(SOTBV@84^cluh%U9n1+E- zG%o7|eVDW=x^%8m0Hsbe-TNX-sOqn9`JPCD}2t**7 zWb-Au`uX{rvW?v*>n7H#iVXkuXlR%6{PY;^GbmMM|DZLI;a6_gFUP(&++j6jk3mMO z&6t#2zz(|btBy#WwO-mEwXki^_{6*T_Ki}zc`d9=F-XU!QbH{i{uc*Ax~cIYv{LaZFJ&g zbcm+}*q6O~-{@(`?ExZXL9X$-B-i>Qb>%(C_(GbuLE`-AyI;n-mpPNm``BEP z_>Q84&BGvqnULRh(P!{dMx4bG{~e9wXx}6@^qY zrVk;028imRGK#9UtsmZT5nJM24KY`#Fzb^k6FhTw9p=$t(VU{?Ntc-ym~@y|xj=Nf z2igXkSW|o$OW=Tpr&!GmO|s*5{aN&ULiZXRnkpEhTwYNrq8_U6#Eal)%dvp literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_04.png b/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_04.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6f9bcee45b461862d99392ed653c9509c01086 GIT binary patch literal 2204 zcmZ{lc{tPy7sr1Q!f;a~OCgDC8^#zjQkF25n{_NNV;kGp4KkJ?5$0ws*Dhp_42c=C zm)9Y?BQ24#^VTdH;Ez=l$dUanAQS-|zD|=g*U7V`VBNASnO+W0x$$*-|Ao!DqkFCn5`5oiy>0jpo9*2b zA%Zt5@004}xe5x=VLV=75XRU5C34pC=PM5j_EoYXi0H?|bimpw*HX4;U!0_Q6o zDyURSZFg!PtDuh+7tK6)`NoR5(5V^c_o!Zf&th%0JZ|e|AM>!3d4+k+Z%-!oViWWZ zDq(Re#@4qswjjkSW^xM-SUN;fx;#8A7aQD0RD1iphq0?!EdqFti2gNF2^kU_6mJwK zpSGSDxWMgUhi*jtXilqlwud1_wJGlTB84zC_T9}bwNmtyd;n+E%U=( zcEF61`P(| z5g~N#Q1lb>1g1`vS$gFD-P)UN2yr~ z{by~NjQ28d-uhnn(CUS!BQKnxZRnqbfwtppm-praY9YSwqU^s7?Q>&lsu^4LVn>Z2 z!!wiN>IcU4G`8T6OV0+XU@1o1yxeW@;qT9Ak8Zp+e` zvIC_vdvO$E(JAcfD7$BfbDag5Ypipu;dl2R#Jl?3?2PQSBg-G(N=f)8P zTNxuMHT5e0s6Ua7v{}@|hE_%oUh?o-^HA9VSyAXqam_vY)p{2~fjB0_VI*3ak+!J3 z0hieId>S@c;deBEILpP8EQJS8kiAzS;Sa|p31ZJ^=$x`_G@_UFBafMR>g4#9x8fBj z-+t~}($fV#4Keg3S&xa8`u>sh`@RO~dN^(N*H0jla3`=d=`rK<{GSWOK!- zrcv&#LQP!8(W>$t!?J*R3h|B4DNT~v+m!45PpLYkf)&tZA#29( z5xu4a-{Kriu5@fC;w2)^4(wt2$VhqNnB^_5i=%ZlWXphITk_&o4s?7GG0-b5m-qX2yE!f z?2?-!Q)l+#|9T?we&f%QovRns&x~v!i)10L4hlV*zp0A(6v~c%_%e+iG1#SqrNRsH zgctKVyaL(z+fHsEEna@6RFS2KY}jjm4AlZeXQ%6|P;y$~!$TvwL1iFk?BkaE{)yEM zUbw`Gu!C`=N(IgXf%6Lwy?5p-o3`?u<@d;iP&~%YilsTpfvC>DWiFX^t#13#Y`dlO zTKQiB7K|184haS*Zw{a9f<#sKg-eSf^^8kK+N>y;IRxAL zWoyvXU~Ex*fIorBi?}RW)ThXt-sXx7crB3tH$7&(+!zh1ZIwn23C!=g+~ zJO}lP*Su$&7{jj9qF3cqhJEJ3{q6nN|CrHUF%pSzbP2T9h@Dx|X~k#J#pax)XS2zusNVzC!9L>}i}A zd09l66^01c;**ADHARUX z-p2kaRAu8gqLSOWPL0UZ~(Y{2>{|A005H}#jOB96bJy;JOKbk008muqV{Y0tb)zk+T0WX zYSQJwtc@FM2{+?j5fBm8<%cZAl(G^hOH(69G-Gpi8}Ejc6dorSc%l^zlkGk)aGYwZu{Z$IXC7a5nnE>6zlz>>8UmjlCZN;@m<{~(xK3tuhs z>sY76Vvyyw3h*ht5zma;1Ch=s3J&T`T2P6ytR=WP-^M+U!2X=5^vv(z7=#1C%Glvszy?{GsH-;%|}+?PCPLD-@+ zvn`w}`^5EvFA)sNWUnqL5^;?CkbRu7K5yKoE{z^kIt-@QcJ}d}d5z zgo#2oi7l6yg%>Cwd6L8hl;YD=ky4`OojF`pH5iJKSw2Fl*<4I3@cGFBXqAolNNiuV&JGG{)_pA19dO!=nfT%Qk6jwVMENic;B)~wQF~M>4 z!S2lW0;Czl_K`{*hjx2;jr@IlQAYQe+xbCPx8I3ckKH6=l17;Rm{oBJ4LTn&x>L(d zYYTX!?EQ2uq*+HhhI^Qh+?_S+D~w$uV|>*^Y!IezQJF@NENn|k#^pK4mA zpC~8vPTg^lJ6Gp5qp#ACne7XALto4e4ibyuOjJ`syF2b-Y0H%3pH+!Zd7Nft!~VLn z*mv1ne|0&UAgUy}fg;5%ohP9S^rE2E)HhF=W*$*FHLHH3<;7rSA)WPG!Et$xzkb6+ zmtBM1I z_e!X!&YIx8-D_oxHj&eXXHaYAThrN&qB%Xsj6Z@Xq6Lu>!tOGS9biwxy+-%bLoZ{8 zeD`M2O)U{}dIreBNXI#<%maU5pIKm-+0!f@f@_%QCbs%p=20h|qtZG);ZFMn*B59^ zs3rB>9GSVscew9lB7AtJW*) zzkOt*dht-IS2|WUET279F0;%%!`Fg;I@dBx9iYX`hRpCm+e#7O90N5s`8tJ4cAeFI zLZSDj{*1+7ZRlY{>#9|hI1XCCmO6tyew#*6UfGPLC z(9+%DB|~=})yB~stl3479hK0?E=_EY!$F=0Mr?F!0`lsD9ZWu1aIu2h>7Jcrpn#$Z z5u}hWr4teyB-5_&mP^UGNnU>Me*f-1CFZU6%K@BkB-q78+8xEJ0s`UJJ>~LxPw;F( zb_(9~y?gwlSvm60dxki5DIP+^G>74DJ8EYBVwoiT`s*dduRd5UHurL60Tm5KsM=j#=Ku; z@5b8qe#c}%R>b!Oiv8?=uhEbwA}!FAS8?Um*q41#Y$UfTJ3MJEtfmRnY#Ly-Y6IrJ zQPpo0<0B!bsJyVa-VN$jCBX+T42qt`&j!v^{EALF-%6A8VYE`k5+#gFdN8@Gm%w$h zX~nyF9^2=7a}+lwmh72llLaDuOo=q9byW&u#|r$nF8;E=&N5krA9wVo+TdVC)3YZx zbh3V>8r{WkTgmM?;XD?6uyHkZQ`^Cc^>h`mW+<$$7uFBv6XC})01N_as%e1LG;|%o zAea^urlFw%0>MBacK#^e{{uq8d;|Ss{vC*LdN;!Yl>T=C8yMmjiS-Hz|93{gWP_W< O0G4L9ruD|2@&5piwE95+ literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_06.png b/app/src/main/res/drawable-xxhdpi/notification_icon_connecting_pp_06.png new file mode 100644 index 0000000000000000000000000000000000000000..71e0f2805d8833871f2b82a4a5b32b2ef2bebe3c GIT binary patch literal 2117 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 diff --git a/app/src/main/res/drawable-xxhdpi/status_icon_connecting.png b/app/src/main/res/drawable-xxhdpi/status_icon_connecting.png deleted file mode 100644 index 007edb0de50d6e75c01a88fdc3337db1b396a663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16838 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¥qZB6OOr0o+>1! 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 diff --git a/app/src/main/res/drawable-xxhdpi/status_icon_disconnected.png b/app/src/main/res/drawable-xxhdpi/status_icon_disconnected.png deleted file mode 100644 index 501f38daec79dbb3a185530498374da974c2f68f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5416 zcmYjVXEa<}8`h!|NhEp~hEb!pXc1jTH+sTolMn`p5Tb{OtIQBH2#Hamj}jw@62UNP zw5S)Ox2Vy-bN_v7owL?Cd+q(a&wk7E?zIyjX8KI@ob+U5WK4zz4=l*Y$c_GcX{msb zA^zE9GBVa3!w1?{FMn_4gdnX)Q9nzIpZt8n^0|+SF`7{Pb}0GN4OJ;Ue-J89R{re* z&h%a3x9ElUT7R}@k6Xlf7a-=kpS^0ipWA8QiZ)=?hG?@=B?(3+e!6#uLT_~A+Ry{r zsa}L{^G?V>=-gMfovYtxT^vUKlMK0JjD^0Wpx$Oucnk&raXE##A#Po8LW zh4fcuthMjnoa}Q|tFamDDNP7hVTS4XIdwqP;z++scmmjas?x70IyU(~?5E=sVb8Oh zevqkoE2wt)WxeBi0e)=+=Ww;HMydr!!PgYh9NaadHx4EPK8*{1O(Uh(q9cQ*?~nI> zNeqbX(P_4LAyceUW$&9it7I#s98J=ombbmHVRO(&E}YI2m^CJwjel~v|5$X~wr6>- zjHPGV=(_12PJEM*;%LAu9^uPyCCI+G8>=tnNpv^+ojkulq0}oMCAB9&`QdZ@y&VoP2@XA4oPH;XPfyr`iebQtL-zdZe`3|a!7>L;SE;gEE5{9F% zT23#5M{Jodl)H2gl znZ!`)y+!6lyjFxHI2j;FV;4Npe(Q8sz zigW!I$o^PP!&!b<+(rua_-uCJqrq>+yYW4U2Op9B}d!Y5VI*JN#k1waEv-aM(h(+{?wL_~}Z|N+v1AIj2>(g1|0cTH$&Y(nrk^(@68dtdTroryDtEo- zftQS;m-l&Tc@X=lZmE@R;9dAKIi7|+@!91yscDtwCx@+d$6Oy+a4ME9R5AA|baO6u z!ewusR~^1{ri02^4RXKgi)cgXPr?L)vB)!My$3Ul?ShIuDc*R-fW6}zGHh;5^g&Hi z$VcIBT-{)*qhy1z;rbG1_<(Hu-jmg$`aj7p^RfN$xuD~<6L;ddL{RhQHD7yA{J*h# z!Sh`=>S;Vv6!v2vZ^64LRolknH2q#R2uL#}(w(TTsYG*3vJHM&&V5oj$@gl;xcB#- zZvhd4BD(X+u&ZEVGd3eCT)4r{wzYMwG3MQcdq9!V= z$DOucI?Q}u3e1pc)Qhm|jP=>RHE)%Kzy4Gwr1Cayg8E*`$hJF?+sHj~$Hhr(3>_?A zZ>(S6xo%iA!M7WEt>x86aHoBM)L-sLS2l;l2EJEW%aY$M#gJ>cP6MEN(=+e zTRQ1w8SS2JnN-_^C{5DG2E^Bj!k5RhU8?O$^Z406spUf|zIf>Yj0vpo>geg)%_ndQ zC%0;lijd1JV%^_m`)0LCWEqF}sNEQa?w>raPJ3s{E3>DF@@dD(lv)lSAGOJLd!x!! zb!y4o@_qf9jN!2T?aHZ0Jic^hH)_t}V|+z==*^BE^hr6QVVfdu(M12~9rK)M|0CIrwK)=akeQN}&Nfj6SBxSsPZHVYFyuvCTpuxw!6spdRtZ(Nut!VP{N zA8Lz+kHk(a+n1yx41vHtnWt?XAj#`jsFW|g1|iR|qEI%4E2oM%!Gjfrb3CA;3^Uq~_jKd1MJIK*6XG0oxJ-EtxFuN=(-i=d+bw9_uqM2jb z5fjjP>(842DGa=3&@nXH)?|#aF3-+}BHDa8j?LmdiEdRDDkKCo_Ac{|-w<(MpU#RI zqyQnmwMX0qv?H`fQE^;kh*-x*6WxPWLFz`9q;T3g>!jpP;E|_NmMe;M`9rN%-ThgT z+>rtN!BW@?2|xX@zWi(|lh`ukY7_3_Rk#?`eny+R~(-ihy4^aO+_tUAu9~qY({Z0df@=;r}oX7xv*b%cS zG?)nw(ug;jD!bvi_>hbs0c>G#zim8w#Q<%p{F5@;zZ3}LYD`KWzqcYpe0y8c4RGIU zmM|hdv0yT0QNWJBCFMrH{CG>$vx*=R{#S!m!bVVVA%09(X?)u>@UHhAIF*z@0p{k# z^lsDv)loB_xC16w87enc+Yu>5Hcq7(xP(SfH{g%-lIOlcg{Ud!VqT(%buPYh*BkD= zkm7~^z_z-ctBg+E0BOu~>BOT~lrx7#xRnIPX@IO?syURK{f`lnP59uC z5$5C=xT&>$Oy9uC=b7Dhp7J1pg9mui57=5eA)^$Yur?0gmu)+s-h42L=3Yt}N9iZ9 z@82A5SHzZWrCY;7!prIAN7t5Df>q@v)~PlfjY4ut5T!9JRkeqbo=q}T*(~TCBXSq@ z?OCOTS2@x8PJeV3?rrwg?a?sT-?M3i6j8>{&8#Q#E!}x8Ns`BT z+6GAm8lPv$a;uU9ykjvZ^5(ST24NciQtN~gN@2ndL>SCf-C>ahw3qo8C~FzeTrgIr z+b>~bS>63x$Z*9|4NRV$(Xhpf5dkuSpq_F%#1pZUpk0z`p zs7UU`&aEnh7|dG_jPsDVdN7l`fe6Ni4)D>N(GmfP^mxxsUiLM7BCB`yHlRHh8iqA= zU3Gw$_Z&Pg;h!*YKN0VrMr?^*OcDZtsdA8hYF(8yAZ=<5JU+L$8#v)Ug2P)q#1ytZ znvC_O|1>@Pr@@|3!UJUdxR#Pu{`5|w=tAm8I9R%^zD&ufgoS=8%BAAs2UrBY{I6Dc z&&x3seY?A6Cv&}hdz+0SMDV-2vZXdC^G&5njRBeo*+u!?eR|2LUHJoJu0WuWVGUHs zY~*#G7I#Vn0viS4rG61s^OWd=<)$;H#&M~PInSVz76-N9q_XnNZ(Ms5O?bW#GsL8{W1eh$*0jL=pT(iAUoT2U9d$GFSs&)+{HR`*?kd|+E+HQGrvsbDf2)YYcD zmw%~TIF8{XIJ^{AkOXwq5N+z32Bjq+NL_I`7Ce?biw9hcna6)3&ICd;OZFRtV_L%h zg?`w<|x zIB<@W0-C$F*L;0`?c1`fh-2UPTp31ZT}CG+fZz}n>Y`g7dd)-n0jYek!?&guL;b96 z6hJqgbkP)$_geh>8XPOSxNI@pGTl_#`z=+T;Tqd2`4h_eLzsSwJZ9@m6CirIjsm{l znWYW3ZfRF?7}iAYnd?w$T8cD1{IBLnG1O1%+7ztMbKNSgb+%Ku)NYM1oM?0{qY+3M zftcB*7sCJ9r^|1Pq4vdekOSs}?k5hmKFbLf^;QIv+;u4DT3kHWr?*X@dS3HK>P6+y zZt$2bEmPwS9nlnd2CR|0Ty>=2iTQJ$v*xV|6^$64IRjy(jgV|Z?@%JgC$$7-8E3^GK{QY*UY1g@lGK#TPf&TzRNc)1Y#1*KA_ zE}wCfJl659+%*y_1uCJbzy~MhO<+YL-dZ(3D>8AX^ApK;d{Dd|n!#96y0rO@G2Hzr zKi6C9=9KAMNeMesO=jYgag{5-dhZXpRJ~CefgIhKZQd}aVRig*qQzmW9Ob1~FS%zq zhNKj}(rXaRy*tMckF&o?Ns?H&-7_X^M#3oPeN%E7NU%ZQ;qLG;{H0J-(v%s??>o-a zs6Cr`j99dFW~QmKzgf7JLy`*~5*D{PQGEp!B??#e(^KSa~|v2iGjy)qZWlQa)4~gIBh0N+9Uu5+rMvA-`I{e*= z>MnI2VN9MU8Q2>L!c5bW+u`gdZlSZvc|j4g)I#OrhZW2b>vh-slJ5V?^E5LtjRk$} zth+&MGLE;f4E6NOqqbR&P@kVA3&f4dyd{Lq!m(*ge{Iq*&N>oHW?L2@pON-^PeQE z+IRhob~;|AxjI)C<~D?)$6!*S@b@sw)I3M>=slj38yChJJy}zN{hCe)<6kY18i!b@ z_3a)mEl}48Kt1i*k`OmCVSn{8!5-Gtz0xX2GCYuhMI7^fQH%WQcYpoCB$!<&)D=qb zDeNx+(d8Q!i{>zAxSgvx2!P!9du;oibjm#fd8sG93Ztl#!hA}V_?2lF;=6ULR!5w*J6{~=6$I@=J ze%UWC5&Dl(+i2^z{Uo}b-k_K;xj%r${w@h;h~EML&gM;<2NG)XG3)ZCOrVz;`mnlzFAh2JwP%(ctNJV{L@bfZc@<_Eb$u*K^p#>Q1H3V~4Fu&2*QZ zi_;9N2sPyG<~6bPP&=h&kK5(vv-gZVR&jpJtVqg{e+uG@cR~(L>glM@+~fh)xUylC wNsgs#JHmtEJ7NM%q;UDaOGZ#)V$mg=9)@~Cl}$ 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_01.png b/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_01.png new file mode 100644 index 0000000000000000000000000000000000000000..eccad30f9bbaeb9d0ed27481f4fa648a1bf4a764 GIT binary patch literal 2029 zcmZ{ldpr~R8^^yJHZ}~gM%i4VDY7X!sE3@D5LyTTfD*;U z(Mzg~e?neXnq4kGu9u2Vu#1-m0A~#W;P3!gm$o?503;9qm}LN9l?TAqI6(`|S~`Fp zcXM_G;C8mYnY4nlC>~DmX~iw-mI%j>6bk@g0~AMldgAbcUqsYaC-u!oUMjl%cD)7- z{a(ZhMt{1ln)^d&9>#;DY)86IcBiMO4a&nZ1GTywl~pPBGHG2hOpqN8-Q|F1OcMOP z-Lk0m+wQ5OTvMkm#x%8V78br68Y;&nZdM#v%o$o88OpbaJ%Jpp2+4TpooM|lv$g_R zI9tjzuC^%vKkWZPPWi}H9G$jM0)mU5GFnjJ@J!&DpbLW=Snc){2G$K*FAKs-_CBmk%GW}Z%nrf>)W778B7k0Zo`ph*L~-o$eC5S z!CH=E5SMq?h5xxYIKBm(`BO5D%U_)PW*MOIz6oR*oIXGyRHk>g*Q>S!x?exO3bD$` z5Pe~;<)s^ecDcOm`I5agWWy@-wV+m4ZW$KesZ?3aE;u;#h@MW%vD)-lKZfkdSgaeY zo`um%i$s2xV>_)%>pd-#H2W*t+RUqiG#bDEvLY~>(cAwcnvQEP%v?7O-fK5jv+SJ= zzFV7XeGSwKgKUit%U1|^dXnALHwYVR91SO1=8QpwTY%wGJJr2I<>0!!c>Dp&>6Q2l zJ{8nQq#XG4GQD!|kf}cgs;p+3pTfjVxQD=OvL9K30OQUrMzg%08MFYs!G=WL)uc!+1S{NK=a-T~t`DVd+U`FDa1 z$A$Ql;hRR-fU`D?V*8gyzJX@KgW6X#p$k{X$xA>~-Et@MZ8YtdQ1*RmaOf* z69cct0$1jQgQ9gtzQce|T^bggQ-8)A))7y}*`*C(X3934)xjUp4MpM9Kg3M`NIw~f zXXlQL)8%=0Enugj8#<&r^Sg8>T4W*(Ql{1PmVqcfwOZpYZod%jXUfWH41#8!q~Cg{ z7vm@cs!exXh&Pp+6JsLP*%4D}hm~G9E4*6dX*Ior7h>at`bdr6N8Yb~F|zq6>m7`+ zt*<+OI+6_M#CJ&WsMWAuF0liDe#e!=$h)0t$nrf1U<9ea%8p04cmt^ZB~k-bW^_wvizPEZHo6*_`ZM83qUWSm691)Lao8G1P2Y%ARa0;U=O; zk`^O6;QAZHG7OOG7Z<-OqkS=tMCT$GBj=%G1)*~QGrnsmZFx`MeEQw}IJbvYze10E zEI3!Cnizj0H5z(a+qV5A^Rg&Z2lqOzHm%{3GJM$qP70$})iJ;BDf}K$$USOe(_GNT z$B{gv?h||Oc~%l(gvHl|1-Ug%WebPtF_L)$vgsf9L%CJ;H0n zT0CS)g0fH9lr5lUec~2TZoh><2$xU{wE3LWAy_>;!u5^f2Qz?V$Z@sOz90dl?t7hh z+pQ>$A0!I#JOvO?N4n#18ucZuYCfW|GdqWIv@L9Y4dCo-M)S8ZCce1 zPTw<@n1(1Vp`t^feGWmbC~CRp;QWpknoE5dofReyLRMcxFhpg6RGhn-&<)kG;@0He zWZ{8qe8AwLhEq35An!+RI-z2_;OqnYdsqzLX}kT0lkCX@c{@Mt?|}LQDt02?^LLY* zgZ6&?vC%>6b!;;@7+J121J_N3gvemhEp@F~ngN}P%q1_xie4gHzryndZF=E66%4Si zBx6ncL+vslfY8wm6QaF?b3arbzeFq%tQftDF}|KGuL0$VAyGeHlcT&Shq=Hd>6zP$ z9@WMgvyIwY%4>E4o(!p|q0QxX@%C`qB_F(>-Uzx@(g7x2Lzd5Pqo}p3WVkQcPh4deB+)TdG;z<06XP|LmV?r9+oi-3X_`R4^Ki(sGH~(R^8H;kpS$8OWz+I>{I4Fl$ey3{NEP>x&s9bl>R#dmeVm-NDwR3D)>~W zRDc=5Y@Z3y%!Fu3HzQb?TUZeZy9op<0--YbeE|2cTL?t5;+0x=S&p*F&et$fF-1|QFeb4LM`_Dc1<{5hnA-FUg03c*#Y39UL zuYW>-kDDzS&uY1%K(utS10d=s08k_o9~%oZ z03N0&X>lulij^Ine*qze)Q6kRTAkoJB35Rn2odZrxnvp=kL-@4+lYoqh>M6`@$Qmj zMR+IiiB%~aH5cmfMpT%xSgMCRBKU?`0Z6g^4)Oj-+A&d_QqDW-0a2R5b?0k%9yD)A z1SDu|GGs8V?e6||yc;2ZHN)1mwPgMmvw3m+(IR#CL5=dT3N~rlO{J`}FzTMPGs(&t zMD5@53#~dZBD+R}19rj#@i2L>#Gm3C0i>|qNu~CfMo;ypQ@prynh!?WV8Ozt5Ab-M z^dqpt>E;}L@8Y3>;cpSj;oTFpnXo*ZCmX+*%8(TX>t-GU;~P?Hr1FT-GSldR;(WK{ zE|1H%?`45HU39SZ<$-4}nQQdb@aS(@UCTwmK=5+fH>=G^X6+56&t1{iSb0P^sP+B@f9lqz$&2 ziQ10cWDr%l?2)0Ywr$c&rH`Q078ct0Nwrgv2I`f>FC3tQKT70XY(Zz_7qmS~{ z#c9(kDMn`u6MioFw{|o0rP646{y~@%>B6{G!WO+GEEHL((N-UIBmu$B?N2E^XHAe8 zKkt+)>eQH1Z9c45i^qa4$3mgY35{Xxzb-Bp2PJJ*MS=x4fpU=7qkBc?bqd*4{X zfm?IhLdjj33InYn)!5ga;+b}9Kn&F{rg!a&aVdxT4qG$R(fmDf*VbCh-dE{)_Bqy$ zUPZPJh!>oBRp(&n{H52cYWupChTR%GBZj6P3GVBCm0thgfBNy<@v80W0Flx3BerUU z*q1PzpVAgSWzuzAEQV=}X6ul2MWVZg_F;t}4aJ`vHd^hGV_j9y``GxOuaL1Z)vt#9 z&$UxnxlFhqVoAM)g(cTa))%KT@;(!dls%7a92SBa`i^@C&Ph$lj5Z$%{}C0O)8ZKm zx>w!ymr&8?rJWZBW3DaQX5a0je;^jVbe*wnJ=r7@uSP;dw=SYu+ui`T3)yr@^s{4R z(<_+kL2ywG4Ky@QiB)tkST^5Ql<_*?8JW3{-I@o4EvV@1gP~{*M5m%OoHJLu>6{S2 zBa?snXnCkSF6SzG9T8SlFrFxuR*)tm?=;JcHp?%gx1H8hED?X!c!VqwO_cs9u5li2T^P--j}F z7wu8h{ipbBR_&RI<%A^-zIvaUc?4(hW^HMtd1ct(Mh~wSoBF$B=C#E^Fe=q&&g|X4 z2ZyRicDp}(IYR)tC6_67eG&LE-zuCHS^wbOU$nB0T;%N&x{~WlT~Z#HBj4?hMZfV^ z{L17kub)w=tdc1$R<1qcnjCN{@~y+(!imGva!(o7ybB~o)7^1b zUWhGU zLiK3~>|F<>5~ZCccx!T{cYO_JS=Xfc8NXJscY&Jv@lrR6Ie}*Dh7kaV9Kt>4*eex801U7 r5c%)GnBt27E`a*q1PVEj6iV?94E}c}LFdyy-yc}v?aeApz2g51@DiwO literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_03.png b/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_03.png new file mode 100644 index 0000000000000000000000000000000000000000..292fc34e8daf41f2f1e1086fff9121f8648fbe00 GIT binary patch literal 2144 zcmZ{lc{mh$7sr2NkC9^ROpFGXig77h8v7u!j4auiv3DnCY=x06YnHNPn=m&u*;U3w z+|&gVJb^L(E3=gF|QvlJGT5d;7TTVc!`59ssX z65u)LnEYq02T<_GINAabrwjl&1%Tayh`a;NcMlRXD>Gwk%;cxC;B1&V>}BFj)1#xFFni;1&x=sw zoN6hA!-Dwei#iA_yT>`>PK^0+shbLab7ZA9yYz5M#%?F23PX;dv0-mGJ}DJS$TBBxvnC)v7i`VPFCnY$Z}av97S-K7vg2tp_7 zOEe_#dM+#XwAjSU-I!zV6?Mo>i@gwhQ(A?bC_2@DX%Mp;JDjCw{*sws!>H1v@Bpky zZ@1aSAL%sJt8Pr|PyO6j$WYl!Qn?&7yyLfS)Tsv}T_%4@&iOYKH}IP`_ zH~vty4f~p@!b6Qqxf{6uii>M=M?BHN@veBMjz}rvCrkct9NME`bA^Cq5nl;2VFkS zcC6NFzE+dLc<=ePUEp zfT%s@))rkhvD}L$dDS=8kXG&H)z|4I#V6vWL=hv9SMP;97J}mQw>?-JdEqU2zS+2X z2gbxSMi98S=jnPf^j)KU>s>6L2r=_=X6&>WX-sP4gbSbgE%8+Fp$CubL*?Zj(;SF-8duJF?YAYS zJe+r6x0!w}tn@cWPf+n{;>+G_cVOzs<7h#BfuTHU(YFV%%l?-M2YL-XdKJ z>&5Wy=02wXXzMf;m8xi1LK`TcGxsn?d}`MgEmmGI}?vO&D1Jc3sb_2-2T$t zIcp`>l8m}mkxVcShO}M&D2ZaDWarWe}&b^^kj$A<*T;5+y`aC?OQcOobKF%5( zzaX3`M8O>{Ef|Og!CRh7^Z}N>B1ma!;6n3oF$$eHlcqiL@}AdRiyCh`qefFFvELp*|T_!zb==y%B@B@K}i z>#4H+yp`>VJl67c-#-nx2WNjb!T5nrveC46iU!+)pY9xG`5W@;(du;p>b>|;b4C>m zz2#EyB(iKRtEL2y1yQ2y_k)zSUwEo1OLGrQ8CkmbIu&Kvn}Z=_lI^uS&!aC3=H@;^lEGP%3ELOV@88s%!MkGI-uWQF+#voG*bCJ|FIPx2$UmICwX z6|7=z@}&1&&t_RQN%9TVBkFNQlH{|3FdbHbFxi?m`hD0*8jNq^n~T9B_s|Gps>;Zv z;w(8NtM7`mJsdn%wcpU>K+!!>P}q(vb-r-bZvf7VSZIRx6Zl%L@6=l=O_usX@p_x# zdQ0<=rLfzdvkA|H8X-f)q2Dd^1ST`ifI7e0+&rGbrd6rBChMBRm(n@bmRC*#$=zC0 z47vfVIVglE&Rw|lC>xoWP}2beaqd(Hp$zA)h&LL3dn#P-Z*ie-JIj#pJ1F(eVMH*U zG1IMeb2DGDSvFZt#GQBtd7tVb#ws@vch=5aS8m(7n`SX#f{5T9s`P^5ORm^<7{f6f zGZ|~*DAm3Pq(#`lf1E9Khyxh~46ds|6k~(obVd3qq|9c0{}(o4R|MPf6KMlW(>r*v zNTRtbF~FCI)Ax_S9RO%)YH6QDX`MvrVYM{%bDLZpEI6T<%p2*$_$ pyAW})fBZmD{oe&*a5yfK=o?P>cL!;@#(&@dD|0)u1{0s_{{R>}#f1O> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_04.png b/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_04.png new file mode 100644 index 0000000000000000000000000000000000000000..c7fad88747fb12c1c45d4e11356f0e91e65fd4c2 GIT binary patch literal 2193 zcmZ{lc{mh$7sr2NXk@)I%90RM_GWA`VutKV$e!I;CbI7pqau6C(4dheF4=Blx#AA< z6p1X6ZIm^QeakXR@y`3t`#kR-_m6YF&-tG7dA@(16iW+ZUM^8C006J4iGejs-Tzyh z?5u9`xV@ewl3pg(R{@AU2LRy#06$q4VG)1`Bmm3q0H8?#oCJ% zE*h1*Q>aK8WQQY<*&}Yw2|aedbg#-yBQ+&8YBTv>N-7p)_?6uAbf&$ZO(>$Iopm*s z-vlS`#Enl)6)r6=*RC&#=H61Iao^M3MG9i3*u=OKL1v7GtzDj(RfbnPA4UHI`}y0bu8C^qc$ z)nP})rjVL&8TKNbm?Y`YutV=DqRYDh@t*r9TbZ56GEx^UN2>*+=Tk5VbL^ANHF7Ep z@)QM&mPQMVLtaY%xm-RchnbNOKJ|X$R*&o<_Vt=f_(cL^t>x)nMI9x(74mmT#iNn& z4vgWmZnWNQx;aj}D*NsoTOVNcA%kr0CDdMT421aR9o`{3vI{>9qOBqwCR{o`ssPIr zVQ61951+kN)2noEbe47{hr1;Ik^xids4be<^H;b*J(e`z06YtZ@8znclL4RXwqZXE!%8o^gN=RU3g_1SbEJgF3xTxIrVwDZb9k7 zWe5pXdfhJ~j1XtE9wwS?KXMuB_+EuZ1(yU_xF<2Ny4J*{=`*T$FIb+t-c>!Bz2lRG-6yePAQVyEol&<6=VQ z6{faR$A~am98Ih&RDy>B7&$i0dof*x?k_?^Ta12v1l=W_}GJ zck*5MQXvuj?UJ{xLrk9sP zECr>5_Rbq~mG{iWUyWGBXv*<|gW6rA5Nc>v%22O9RFU%ITLea&fKChW8ZweU?w)MO zh_rJ%4sOOLYMc+Oum+wb*pfv@N3bVrIb?H17u>A29=mc)2)GXvAY9pO_^|P50mggI z5r<$|QKicp>kYn`!k=ThCH!5n=?wQy|mI7b}-7sPQWJmUrBTZLuhh!@25Dr=Q z+O3x?*MAwBZyL;S7af>s(t3uV6^&+J`xQ@7dKHwiER1hBu7>Dto@iBYm=DoKFxqi| zsds7Q$*{F@n!iPHuG54}u%Hvn>RLenXYjIL5xGgG|25lUHxL!UJ7?EE)}C}y;3z{c zTUYqVN^3R}e&?DiU14?mW>J$t$q=WLMb4TXe1KK9fA8l;8qY0?-TRyK&V~c kI17;dUqU$kmUmdV$F1OhXAqZHVJrri8d@0C>bu|j58u+}X#fBK literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_05.png b/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_05.png new file mode 100644 index 0000000000000000000000000000000000000000..b3f5394c3af90418a2d54672e689c65244cbd376 GIT binary patch literal 2140 zcmZ{lS5y=D62|`_gc3lMVki<&5HLs!)c_KdUZrRN5rc#hx*=RC%MwJC-cdl1(3UDn z4^kJ6AP542O1(%8eMKUx0lm2|_niB%4>RBSX3lTsoOzkVE4F3=a0xg7K)}M>*nzG1 z{{{~yJDX?rG_gg-)7-%ZfJk`&DE9#P!7fo40EDRluz?2vlLr7Ir0|8kKD)tj%gW3c zfSOcUG~02LEo@A<8T`T`7x*+*BTCp6tc9_WQ~31uV`7SkiAaBp;7Ox|ozg`JM@OBa zQL4mPs&OjLSU8UN43)Rua>AI-!?|<<+Y=xn4B1^c!6|GX%OjEgN^Mgot$DvFe?T^^I!bbFK)2uTz4qp zu5_?#q2EI2SX{RT)44vn7d6&yF4|1_9L|;K2Q;v-{EkTx{BDm*SlNVzspyO_x0f|n zhOBI?p+IUd@9k{QRqg3l zzJz4o=29eGzpP0%u2ZGF!qd|~ZH@SFgD15R?WM=Js9k{UO-%c7=eha2#EHl@GVnX2 z)w&l9@hPw!57HK%8h#OOcr#N1`-$YK8tO8neT;|NcY@#Je4N2Ly|CPokX|vDF7CghIujbtNZDeh_I7*BM8-pA>*J#+hz6$zjRkkdieB`}!G1=PTrqpH-*$bWaS+xp^VvpQTN~=IVs9vbx?6xn3+iZU{4F?t`h&W&8q3R z^4Xd_Kb7l`k2}zkuBVm`dnc2@UKth^6i4&#Jwol=a!&ZR>jD^$aC%u!Z9f=v`iDlz zjDB(RADj2^u9SpMMzk2EeUQ>ioSbJyKWW?dFi)`NmWfdfX(?lx%rk4hB_E=O#OQL} zT7GT$k`@pwA3~^-7|gxt?zSTuv$dQwXxd&}EwUr5ecwxZd>V`R1+mo5TOWB-p!u5zTg+CLlGUQy#LfB_1vi>DF9w4LzguyW;h} zW&-RzDfeb080{a3ww2whiA+)5{90(^_+gKV<1eDV2Mo!+;@U8e4hfS7--QkwSAtn~ z12}ycx&Cny9FMPBhCFe){L5D$U45>f@pPEd#I9~#;bk8oB9JlUZ#fqtS9UANvSUyUFFvgd7xzpS0PqxI&`+3n3g zeO9)|p}JX*zKRLdk%`tGx(BN@U%l+nhFR&cmN(lIBX5(WIlrgyZtd0RFc=O{Mxob5 ze9~clIq%dUXZMH^joJ(_tzUQlqIqif33{k%{5@W4JqfAc97V#q7pC&sX=*&&z5{`X z;^txr5d@ZX3awGZ0^_SuC2Ov@&3iz^FE+7J=P3&`YH)iLzBUZCf>Pl4h5*!k7TA;8 zjiO6hK^H<6n77&mGxVGdZn9{3XNN7F8fAjyF~~P6HwJV;{e*W;T-Cu*V92}GCaWKD z1wT_dpVLvRk}zhgVs`jRR4YqHk7T4=To-kJf9(~$TqniNe}p;8fgi*MHy$ucV7+9n zrayy7=8)s0%~D&x))_etYU!Lt-xbk?fCfpq%~&J-D)Idyq+KATeLg7re1_CewSIl_ zr=@twVb~LzG)D#8FIunpSOGrzw46HS_g)~6`25F=uc6LRnqmb(@Y25CrFEhXb8JTe zmT{!?rssC@R$5sepup9IXw|+@;UyK(>=ejaV6m*S&%+gysxyF*+be&u>+Pn>%!C}M zIkT)m%9f3A^!nUZopvOsK!@P}-7+s<|LjzGsa(?)!{h)L;+!29b^6SVP+KO6Lo6V( zy=d|glrk+{vfUtwLQoPEk1It!L{JRiB3hGK0u)s31hb+N4W6$J-%^DPa#Np~v?@f` zW1_(1$^0cWRUZV{QT($OjSWUTp2e(c8w%75DYastp|l z=>{W+x`d$KFI1B?=PcL3NsEy{GSJers7-gYQ6AQ$6Ng2yxF7cYic1CLuG#F~UpYC9 zDyx#L61S15h^;n4&^koUatFRuo@u)M8r)xV7xX>X#roy=ecceHbflI9=M-bV*Ry03 zXEMQq?1k|pd9ekc)zF&C>S$&43r=V?jFt{YU0q2{4Wp(8T>o4K&{s(_e$FBeY literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_06.png b/app/src/main/res/drawable-xxxhdpi/notification_icon_connecting_pp_06.png new file mode 100644 index 0000000000000000000000000000000000000000..39f78133c3d286d11c4861feb0fc53f5bc6110cd GIT binary patch literal 2090 zcmZ{lS5y=D5{Lf@C3JBqY7`WNP!#FXB~0RjjXLS0y*z)B#L&{1SVFRn-z z=?A6vqEbW=LI?yw7csQx&3(D&+=qRb`JMUZd}khqU}tlkp9jtZ0N^(_Gj?Dl`oG1+ z&gy2Q?nYKz@G*0+1|S*%06qbLLl(l*00>h8U=t01c0K^7?iRM$>#`P5Z_De(0Mw*j zRAEgpoVm3LjK(Jwn`*q0V(h3gLs;V$W59d-80W5)Ki>t^0sn`OU4iw!4=nJVnDpzG+Q&v%1-3 zYdt(5nH%Z8E9p<69-r+{e3aU~m?tONF72J~FzT~RJ-2jTW_N5m{_l0uF0ST|={IU% zvWqx4#;k9cN8}>lE|h6e#r+0?)%5U<=k|8IiagI%@7W)K@5I@;K7Hvz zg0{`#oD~JoSD7(Rfxv4d)o2u>(5@wq=aC7$a&cqT{L!TQz=(lmyXA&ECyfH})((v!PYfiNdeCz0#1LYGy%yRQmfr#GB$a{#M8IvS4ZmBuzQFlEdyCN5xzNN}nJqUV2Z0dzB3QZN))gO5m+G8rh~T zQGMeE)kSDpf&MO7PKVwZv6oqV*+DlH~D zG~pzsY<09o5RQxll?-k;e+7R7pPq~E(A@}zLO^#3f={DBr`AukEyh3`Uz@_T= zF$`~Gx;+A~e^FC;5FYE<5-{v0&PXm6!oh)u;l64Z+Qqq)20ryO*$+m33jM=B!KOg3 zu!4N&%F*rTQ~#d+gA#x^I4!0g9klC{3n_LDhl5x{>5<5bl%nSfHG0FdRn@3vj~g>?qwI@{p39F?Y=|1@gnmaSe>UZyY^1&c>mT`!^wi zJoFOLz@|khD7i$2nox}BnGex0d&kxpc{7xzqZi)>LQ9trt`~Hk?&jC-YSI$VDzF!| zo`;spZ^oQ)Q%$Y!63je}M3Hq)_}!fe#wF-r?qoYOz$6aEiofIVhge1ybnsUW<>?1G z*orIykPV6a9~_$qM=MuEvWSrNrU}xu^)n+Wc4q+guO7s;vCm?8YUJre^06&k+WJ6kPA2RMlH}+={LN;Hb-WOB%TbaP@-%6`!7spGQ77p| z@d0;X+22oxa+1+HoXN-O4nHVu`Hj~fSgq6*4es6SeSevlHQNfs`sZwq_b}zD4jhHA z6|^M-ZF^(+9No(a0`8Vr@=k>S!8w8hoep)qEOo3S-q{G7?2{k!mZ%>`d1mS1#hn90 z{d1qWZsv4(M>Vz4FSM9I##X)rJgD6B*u-Ki3vXN)$dU}UMscc)wj!2fPn5$lK%I`9 z<4oSOS5-;O2cwtu@y1Wup+_!57QsdloFbkl=G^{Z{Hh$Di6hXrh{w}hDXeEHjWcn< zVZ3m@+CKMvSpig(RMZrdRTPx9995LG)it!0l`knNX)7tQ@rGgkPYAw)3Gj>hcj3PC l*c?lc{oe&#K(KEp&MWxtzdO=KTQHUb%uQ^JYYov4{{wHkyYB!1 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/status_icon_connected.png b/app/src/main/res/drawable-xxxhdpi/status_icon_connected.png deleted file mode 100644 index 47e928102f3156628c6aae666cfb13ea89cbff55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14913 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 ABLDyZ diff --git a/app/src/main/res/drawable-xxxhdpi/status_icon_disconnected.png b/app/src/main/res/drawable-xxxhdpi/status_icon_disconnected.png deleted file mode 100644 index d2df3daeba1a4008fcb400998495f6dae276484a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5922 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 B4sZYf diff --git a/app/src/main/res/drawable/notification_icon_connecting_animation_pp.xml b/app/src/main/res/drawable/notification_icon_connecting_animation_pp.xml new file mode 100644 index 000000000..1350c56eb --- /dev/null +++ b/app/src/main/res/drawable/notification_icon_connecting_animation_pp.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/p2p_24px.xml b/app/src/main/res/drawable/p2p_24px.xml new file mode 100644 index 000000000..47fa2da86 --- /dev/null +++ b/app/src/main/res/drawable/p2p_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/status_icon_connected.xml b/app/src/main/res/drawable/status_icon_connected.xml new file mode 100644 index 000000000..2b68223a3 --- /dev/null +++ b/app/src/main/res/drawable/status_icon_connected.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/status_icon_connected_pp.xml b/app/src/main/res/drawable/status_icon_connected_pp.xml new file mode 100644 index 000000000..c8c995709 --- /dev/null +++ b/app/src/main/res/drawable/status_icon_connected_pp.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/status_icon_connecting.xml b/app/src/main/res/drawable/status_icon_connecting.xml new file mode 100644 index 000000000..788f53f44 --- /dev/null +++ b/app/src/main/res/drawable/status_icon_connecting.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/status_icon_connecting_pp.xml b/app/src/main/res/drawable/status_icon_connecting_pp.xml new file mode 100644 index 000000000..9f9c21d71 --- /dev/null +++ b/app/src/main/res/drawable/status_icon_connecting_pp.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/status_icon_disconnected.xml b/app/src/main/res/drawable/status_icon_disconnected.xml new file mode 100644 index 000000000..49f05c6a8 --- /dev/null +++ b/app/src/main/res/drawable/status_icon_disconnected.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/dialog_import_pairing.xml b/app/src/main/res/layout/dialog_import_pairing.xml new file mode 100644 index 000000000..d8aa1f850 --- /dev/null +++ b/app/src/main/res/layout/dialog_import_pairing.xml @@ -0,0 +1,21 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_pairing_enable.xml b/app/src/main/res/layout/dialog_pairing_enable.xml new file mode 100644 index 000000000..1a6760173 --- /dev/null +++ b/app/src/main/res/layout/dialog_pairing_enable.xml @@ -0,0 +1,24 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_pairing_update.xml b/app/src/main/res/layout/dialog_pairing_update.xml new file mode 100644 index 000000000..80b21fe93 --- /dev/null +++ b/app/src/main/res/layout/dialog_pairing_update.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_reset_pairing.xml b/app/src/main/res/layout/dialog_reset_pairing.xml new file mode 100644 index 000000000..44ee06912 --- /dev/null +++ b/app/src/main/res/layout/dialog_reset_pairing.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/main_activity.xml b/app/src/main/res/layout/main_activity.xml index 62f9701b0..e7552d774 100644 --- a/app/src/main/res/layout/main_activity.xml +++ b/app/src/main/res/layout/main_activity.xml @@ -84,25 +84,65 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + + + + + +