From 1c3d90f7fcea386d8ab043202e8164d7ea9567de Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 19 May 2021 09:51:18 -0300 Subject: [PATCH] Show a snackbar when a peer connected to the hotspot --- .../android/hotspot/HotspotFragment.java | 30 +++++++++++++++---- .../briar/android/hotspot/HotspotManager.java | 30 +++++++++++++++++++ .../android/hotspot/HotspotViewModel.java | 14 +++++++++ .../src/main/res/layout/fragment_error.xml | 2 +- briar-android/src/main/res/values/strings.xml | 2 ++ 5 files changed, 71 insertions(+), 7 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotFragment.java index 4c145a015..94323b0d4 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotFragment.java @@ -3,8 +3,12 @@ package org.briarproject.briar.android.hotspot; import android.os.Bundle; import android.view.View; +import com.google.android.material.snackbar.Snackbar; + import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.util.BriarSnackbarBuilder; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -20,12 +24,9 @@ public class HotspotFragment extends AbstractTabsFragment { @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - // no need to call into the ViewModel here - connectedButton.setOnClickListener(v -> { - Fragment f = new WebsiteFragment(); - String tag = WebsiteFragment.TAG; - showFragment(getParentFragmentManager(), f, tag); - }); + connectedButton.setOnClickListener(v -> showNextFragment()); + viewModel.getPeerConnectedEvent().observeEvent(getViewLifecycleOwner(), + this::onPeerConnected); } @Override @@ -38,4 +39,21 @@ public class HotspotFragment extends AbstractTabsFragment { return QrHotspotFragment.newInstance(true); } + private void onPeerConnected(boolean connected) { + if (!connected) return; + new BriarSnackbarBuilder() + .setAction(R.string.hotspot_peer_connected_action, v -> + showNextFragment()) + .make(connectedButton, R.string.hotspot_peer_connected, + Snackbar.LENGTH_LONG) + .setAnchorView(connectedButton) + .show(); + } + + private void showNextFragment() { + Fragment f = new WebsiteFragment(); + String tag = WebsiteFragment.TAG; + showFragment(getParentFragmentManager(), f, tag); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotManager.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotManager.java index fb618c1c8..6c5977280 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotManager.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotManager.java @@ -45,6 +45,9 @@ class HotspotManager implements ActionListener { @IoExecutor void onHotspotStarted(NetworkConfig networkConfig); + @UiThread + void onDeviceConnected(); + void onHotspotStopped(); void onHotspotError(String error); @@ -216,6 +219,7 @@ class HotspotManager implements ActionListener { } }; try { + if (channel == null) return; wifiP2pManager.requestGroupInfo(channel, groupListener); } catch (SecurityException e) { // this should never happen, because we request permissions before @@ -223,6 +227,7 @@ class HotspotManager implements ActionListener { } } + @UiThread private void onHotspotStarted(WifiP2pGroup group) { DisplayMetrics dm = ctx.getResources().getDisplayMetrics(); ioExecutor.execute(() -> { @@ -233,6 +238,7 @@ class HotspotManager implements ActionListener { group.getPassphrase(), qrCode); listener.onHotspotStarted(config); }); + requestGroupInfoForConnection(); } private boolean isGroupValid(@Nullable WifiP2pGroup group) { @@ -268,6 +274,30 @@ class HotspotManager implements ActionListener { } } + @UiThread + private void requestGroupInfoForConnection() { + if (LOG.isLoggable(INFO)) { + LOG.info("requestGroupInfo for connection"); + } + GroupInfoListener groupListener = group -> { + if (group == null || group.getClientList().isEmpty()) { + handler.postDelayed(this::requestGroupInfoForConnection, + RETRY_DELAY_MILLIS); + } else { + if (LOG.isLoggable(INFO)) { + LOG.info("client list " + group.getClientList()); + } + listener.onDeviceConnected(); + } + }; + try { + if (channel == null) return; + wifiP2pManager.requestGroupInfo(channel, groupListener); + } catch (SecurityException e) { + throw new AssertionError(e); + } + } + private static String createWifiLoginString(String ssid, String password) { // https://en.wikipedia.org/wiki/QR_code#WiFi_network_login // do not remove the dangling ';', it can cause problems to omit it diff --git a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotViewModel.java index f20140978..e27f73ebc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/hotspot/HotspotViewModel.java @@ -17,6 +17,8 @@ import org.briarproject.briar.android.hotspot.HotspotState.StartingHotspot; import org.briarproject.briar.android.hotspot.HotspotState.WebsiteConfig; import org.briarproject.briar.android.hotspot.WebServerManager.WebServerListener; import org.briarproject.briar.android.viewmodel.DbViewModel; +import org.briarproject.briar.android.viewmodel.LiveEvent; +import org.briarproject.briar.android.viewmodel.MutableLiveEvent; import org.briarproject.briar.api.android.AndroidNotificationManager; import java.security.SecureRandom; @@ -47,6 +49,8 @@ class HotspotViewModel extends DbViewModel private final MutableLiveData state = new MutableLiveData<>(); + private final MutableLiveEvent peerConnected = + new MutableLiveEvent<>(); @Nullable // Field to temporarily store the network config received via onHotspotStarted() @@ -109,6 +113,12 @@ class HotspotViewModel extends DbViewModel webServerManager.startWebServer(); } + @UiThread + @Override + public void onDeviceConnected() { + peerConnected.setEvent(true); + } + @Override public void onHotspotStopped() { LOG.info("stopping webserver"); @@ -141,4 +151,8 @@ class HotspotViewModel extends DbViewModel return state; } + LiveEvent getPeerConnectedEvent() { + return peerConnected; + } + } diff --git a/briar-android/src/main/res/layout/fragment_error.xml b/briar-android/src/main/res/layout/fragment_error.xml index bd663a9e3..347d24b9d 100644 --- a/briar-android/src/main/res/layout/fragment_error.xml +++ b/briar-android/src/main/res/layout/fragment_error.xml @@ -49,6 +49,6 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/errorTitle" - tools:text="@string/qr_code_unsupported" /> + tools:text="@string/startup_failed_service_error" /> diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index ea9b6517c..5acc006f6 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -720,6 +720,8 @@ To download the app on another phone, please connect to this Wi-Fi network: Network name (SSID) Instead of adding the network manually, you can also scan a QR code. + Successfully connected + Show download info After you are connected to the Wi-Fi, carefully enter this address in your browser. Address (URL) Instead of typing the address manually, you can also scan a QR code.