mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Address review feedback for feature branch
This commit is contained in:
@@ -92,9 +92,9 @@
|
||||
<li id="troubleshooting_1">If you can't download the app, try it with a different web
|
||||
browser app.
|
||||
</li>
|
||||
<li id="troubleshooting_2">Ensure that your browser is allowed to download apps directly by
|
||||
giving it the permission or enabling the installation of apps from "Unknown Sources" in
|
||||
system settings.
|
||||
<li id="troubleshooting_2">To install the downloaded app,
|
||||
you might need to allow your browser to install unknown apps.
|
||||
We recommend to undo that after successful installation.
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
@@ -61,15 +61,14 @@ class ConditionManager29 extends AbstractConditionManager {
|
||||
}
|
||||
|
||||
private boolean areEssentialPermissionsGranted() {
|
||||
boolean isWifiEnabled = wifiManager.isWifiEnabled();
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info(String.format("areEssentialPermissionsGranted(): " +
|
||||
"locationPermission? %s, " +
|
||||
"wifiManager.isWifiEnabled()? %b",
|
||||
locationPermission,
|
||||
wifiManager.isWifiEnabled()));
|
||||
locationPermission, isWifiEnabled));
|
||||
}
|
||||
return locationPermission == Permission.GRANTED &&
|
||||
wifiManager.isWifiEnabled();
|
||||
return locationPermission == Permission.GRANTED && isWifiEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.util.ActivityLaunchers.CreateDocumentAdvanced;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -22,7 +23,6 @@ import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
@@ -33,12 +33,10 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static androidx.activity.result.contract.ActivityResultContracts.CreateDocument;
|
||||
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
||||
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class FallbackFragment extends BaseFragment {
|
||||
@@ -50,7 +48,7 @@ public class FallbackFragment extends BaseFragment {
|
||||
|
||||
private HotspotViewModel viewModel;
|
||||
private final ActivityResultLauncher<String> launcher =
|
||||
registerForActivityResult(new CreateDocument(),
|
||||
registerForActivityResult(new CreateDocumentAdvanced(),
|
||||
this::onDocumentCreated);
|
||||
private Button fallbackButton;
|
||||
private ProgressBar progressBar;
|
||||
@@ -75,7 +73,7 @@ public class FallbackFragment extends BaseFragment {
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return inflater
|
||||
.inflate(R.layout.fragment_hotspot_save_apk, container, false);
|
||||
.inflate(R.layout.fragment_hotspot_fallback, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,8 +90,7 @@ public class FallbackFragment extends BaseFragment {
|
||||
if (SDK_INT >= 19) launcher.launch(getApkFileName());
|
||||
else viewModel.exportApk();
|
||||
});
|
||||
viewModel.getSavedApkToUri()
|
||||
.observeEvent(this, uri -> shareUri(this, uri));
|
||||
viewModel.getSavedApkToUri().observeEvent(this, this::shareUri);
|
||||
}
|
||||
|
||||
private void onDocumentCreated(@Nullable Uri uri) {
|
||||
@@ -107,12 +104,12 @@ public class FallbackFragment extends BaseFragment {
|
||||
progressBar.setVisibility(INVISIBLE);
|
||||
}
|
||||
|
||||
static void shareUri(Fragment fragment, Uri uri) {
|
||||
void shareUri(Uri uri) {
|
||||
Intent i = new Intent(ACTION_SEND);
|
||||
i.putExtra(EXTRA_STREAM, uri);
|
||||
i.setType("*/*"); // gives us all sharing options
|
||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||
Context ctx = fragment.requireContext();
|
||||
Context ctx = requireContext();
|
||||
if (SDK_INT <= 19) {
|
||||
// Workaround for Android bug:
|
||||
// ctx.grantUriPermission also needed for Android 4
|
||||
@@ -124,7 +121,7 @@ public class FallbackFragment extends BaseFragment {
|
||||
FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
}
|
||||
fragment.startActivity(Intent.createChooser(i, null));
|
||||
startActivity(Intent.createChooser(i, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ public class HotspotActivity extends BriarActivity
|
||||
// check if fragment is already added
|
||||
// to not lose state on configuration changes
|
||||
if (fm.findFragmentByTag(tag) == null) {
|
||||
if (!started.consume()) {
|
||||
if (started.wasNotYetConsumed()) {
|
||||
showFragment(fm, new HotspotFragment(), tag);
|
||||
}
|
||||
}
|
||||
} else if (hotspotState instanceof HotspotError) {
|
||||
HotspotError error = ((HotspotError) hotspotState);
|
||||
HotspotError error = (HotspotError) hotspotState;
|
||||
showErrorFragment(error.getError());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -2,13 +2,11 @@ package org.briarproject.briar.android.hotspot;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import android.widget.Toast;
|
||||
|
||||
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;
|
||||
@@ -41,13 +39,8 @@ public class HotspotFragment extends AbstractTabsFragment {
|
||||
|
||||
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();
|
||||
Toast.makeText(requireContext(), R.string.hotspot_peer_connected,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void showNextFragment() {
|
||||
|
||||
@@ -48,7 +48,9 @@ import static android.net.wifi.p2p.WifiP2pManager.NO_SERVICE_REQUESTS;
|
||||
import static android.net.wifi.p2p.WifiP2pManager.P2P_UNSUPPORTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.os.PowerManager.FULL_WAKE_LOCK;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.briar.android.util.UiUtils.handleException;
|
||||
|
||||
@@ -57,6 +59,7 @@ import static org.briarproject.briar.android.util.UiUtils.handleException;
|
||||
class HotspotManager {
|
||||
|
||||
interface HotspotListener {
|
||||
@UiThread
|
||||
void onStartingHotspot();
|
||||
|
||||
@IoExecutor
|
||||
@@ -65,8 +68,7 @@ class HotspotManager {
|
||||
@UiThread
|
||||
void onDeviceConnected();
|
||||
|
||||
void onHotspotStopped();
|
||||
|
||||
@UiThread
|
||||
void onHotspotError(String error);
|
||||
}
|
||||
|
||||
@@ -97,8 +99,9 @@ class HotspotManager {
|
||||
private WifiManager.WifiLock wifiLock;
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
private WifiP2pManager.Channel channel;
|
||||
@Nullable
|
||||
@RequiresApi(29)
|
||||
private volatile NetworkConfig savedNetworkConfig;
|
||||
private volatile NetworkConfig savedNetworkConfig = null;
|
||||
|
||||
@Inject
|
||||
HotspotManager(Application ctx,
|
||||
@@ -157,9 +160,11 @@ class HotspotManager {
|
||||
* We'll realize that the framework is busy when the ActionListener passed
|
||||
* to {@link WifiP2pManager#createGroup} is called with onFailure(BUSY)
|
||||
*/
|
||||
@UiThread
|
||||
private void startWifiP2pFramework(int attempt) {
|
||||
if (LOG.isLoggable(INFO))
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("startWifiP2pFramework attempt: " + attempt);
|
||||
}
|
||||
/*
|
||||
* It is important that we call WifiP2pManager#initialize again
|
||||
* for every attempt to starting the framework because otherwise,
|
||||
@@ -167,13 +172,12 @@ class HotspotManager {
|
||||
*/
|
||||
channel = wifiP2pManager.initialize(ctx, ctx.getMainLooper(), null);
|
||||
if (channel == null) {
|
||||
listener.onHotspotError(
|
||||
releaseHotspotWithError(
|
||||
ctx.getString(R.string.hotspot_error_no_wifi_direct));
|
||||
return;
|
||||
}
|
||||
|
||||
ActionListener listener = new ActionListener() {
|
||||
|
||||
@Override
|
||||
// Callback for wifiP2pManager#createGroup() during startWifiP2pHotspot()
|
||||
public void onSuccess() {
|
||||
@@ -183,7 +187,9 @@ class HotspotManager {
|
||||
@Override
|
||||
// Callback for wifiP2pManager#createGroup() during startWifiP2pHotspot()
|
||||
public void onFailure(int reason) {
|
||||
LOG.info("onFailure: " + reason);
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("onFailure: " + reason);
|
||||
}
|
||||
if (reason == BUSY) {
|
||||
// WifiP2p not ready yet or hotspot already running
|
||||
restartWifiP2pFramework(attempt);
|
||||
@@ -210,21 +216,26 @@ class HotspotManager {
|
||||
|
||||
try {
|
||||
if (SDK_INT >= 29) {
|
||||
dbExecutor.execute(() -> {
|
||||
Runnable createGroup = () -> {
|
||||
NetworkConfig c = requireNonNull(savedNetworkConfig);
|
||||
WifiP2pConfig config = new WifiP2pConfig.Builder()
|
||||
.setGroupOperatingBand(GROUP_OWNER_BAND_2GHZ)
|
||||
.setNetworkName(c.ssid)
|
||||
.setPassphrase(c.password)
|
||||
.build();
|
||||
wifiP2pManager.createGroup(channel, config, listener);
|
||||
};
|
||||
if (savedNetworkConfig == null) {
|
||||
// load savedNetworkConfig before starting hotspot
|
||||
loadSavedNetworkConfig();
|
||||
androidExecutor.runOnUiThread(() -> {
|
||||
WifiP2pConfig config = new WifiP2pConfig.Builder()
|
||||
.setGroupOperatingBand(GROUP_OWNER_BAND_2GHZ)
|
||||
.setNetworkName(savedNetworkConfig.ssid)
|
||||
.setPassphrase(savedNetworkConfig.password)
|
||||
.build();
|
||||
acquireLocks();
|
||||
wifiP2pManager.createGroup(channel, config, listener);
|
||||
dbExecutor.execute(() -> {
|
||||
loadSavedNetworkConfig();
|
||||
androidExecutor.runOnUiThread(createGroup);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// savedNetworkConfig was already loaded, create group now
|
||||
createGroup.run();
|
||||
}
|
||||
} else {
|
||||
acquireLocks();
|
||||
wifiP2pManager.createGroup(channel, listener);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
@@ -233,9 +244,11 @@ class HotspotManager {
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void restartWifiP2pFramework(int attempt) {
|
||||
LOG.info("retrying to start WifiP2p framework");
|
||||
if (attempt < MAX_FRAMEWORK_ATTEMPTS) {
|
||||
if (SDK_INT >= 27 && channel != null) channel.close();
|
||||
handler.postDelayed(() -> startWifiP2pFramework(attempt + 1),
|
||||
RETRY_DELAY_MILLIS);
|
||||
} else {
|
||||
@@ -250,19 +263,23 @@ class HotspotManager {
|
||||
wifiP2pManager.removeGroup(channel, new ActionListener() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
releaseHotspot();
|
||||
closeChannelAndReleaseLocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int reason) {
|
||||
// not propagating back error
|
||||
releaseHotspot();
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
LOG.warning("Error removing Wifi P2P group: " + reason);
|
||||
}
|
||||
closeChannelAndReleaseLocks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("WakelockTimeout")
|
||||
private void acquireLocks() {
|
||||
// FLAG_KEEP_SCREEN_ON is not respected on some Huawei devices.
|
||||
wakeLock = powerManager.newWakeLock(FULL_WAKE_LOCK, lockTag);
|
||||
wakeLock.acquire();
|
||||
// WIFI_MODE_FULL has no effect on API >= 29
|
||||
@@ -272,23 +289,21 @@ class HotspotManager {
|
||||
wifiLock.acquire();
|
||||
}
|
||||
|
||||
private void releaseHotspot() {
|
||||
listener.onHotspotStopped();
|
||||
closeChannelAndReleaseLocks();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void releaseHotspotWithError(String error) {
|
||||
listener.onHotspotError(error);
|
||||
closeChannelAndReleaseLocks();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void closeChannelAndReleaseLocks() {
|
||||
if (SDK_INT >= 27) channel.close();
|
||||
if (SDK_INT >= 27 && channel != null) channel.close();
|
||||
channel = null;
|
||||
wakeLock.release();
|
||||
wifiLock.release();
|
||||
if (wakeLock.isHeld()) wakeLock.release();
|
||||
if (wifiLock.isHeld()) wifiLock.release();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void requestGroupInfo(int attempt) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("requestGroupInfo attempt: " + attempt);
|
||||
@@ -331,25 +346,20 @@ class HotspotManager {
|
||||
LOG.info("group is null");
|
||||
return false;
|
||||
} else if (!group.getNetworkName().startsWith("DIRECT-")) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("received networkName without prefix 'DIRECT-': " +
|
||||
group.getNetworkName());
|
||||
}
|
||||
LOG.info("received networkName without prefix 'DIRECT-'");
|
||||
return false;
|
||||
} else if (SDK_INT >= 29) {
|
||||
// if we get here, the savedNetworkConfig must have a value
|
||||
String networkName = savedNetworkConfig.ssid;
|
||||
String networkName = requireNonNull(savedNetworkConfig).ssid;
|
||||
if (!networkName.equals(group.getNetworkName())) {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("expected networkName: " + networkName);
|
||||
LOG.info("received networkName: " + group.getNetworkName());
|
||||
}
|
||||
LOG.info("expected networkName does not match received one");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void retryRequestingGroupInfo(int attempt) {
|
||||
LOG.info("retrying to request group info");
|
||||
// On some devices we need to wait for the group info to become available
|
||||
@@ -364,17 +374,12 @@ class HotspotManager {
|
||||
|
||||
@UiThread
|
||||
private void requestGroupInfoForConnection() {
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
LOG.info("requestGroupInfo for connection");
|
||||
}
|
||||
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();
|
||||
}
|
||||
};
|
||||
@@ -433,26 +438,15 @@ class HotspotManager {
|
||||
}
|
||||
|
||||
// exclude chars that are easy to confuse: 0 O, 5 S, 1 l I
|
||||
private static final String digits = "2346789";
|
||||
private static final String letters = "abcdefghijkmnopqrstuvwxyz";
|
||||
private static final String LETTERS = "ABCDEFGHJKLMNPQRTUVWXYZ";
|
||||
private static final String chars =
|
||||
"2346789ABCDEFGHJKLMNPQRTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
private String getRandomString(int length) {
|
||||
char[] c = new char[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (random.nextBoolean()) {
|
||||
c[i] = random(digits);
|
||||
} else if (random.nextBoolean()) {
|
||||
c[i] = random(letters);
|
||||
} else {
|
||||
c[i] = random(LETTERS);
|
||||
}
|
||||
c[i] = chars.charAt(random.nextInt(chars.length()));
|
||||
}
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
private char random(String universe) {
|
||||
return universe.charAt(random.nextInt(universe.length()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,10 +63,10 @@ abstract class HotspotState {
|
||||
* to not repeat actions such as showing fragments on rotation changes.
|
||||
*/
|
||||
@UiThread
|
||||
boolean consume() {
|
||||
boolean wasNotYetConsumed() {
|
||||
boolean old = consumed;
|
||||
consumed = true;
|
||||
return old;
|
||||
return !old;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,12 +141,6 @@ class HotspotViewModel extends DbViewModel
|
||||
peerConnected.setEvent(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotspotStopped() {
|
||||
LOG.info("stopping webserver");
|
||||
ioExecutor.execute(webServerManager::stopWebServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHotspotError(String error) {
|
||||
if (LOG.isLoggable(WARNING)) {
|
||||
@@ -170,7 +164,7 @@ class HotspotViewModel extends DbViewModel
|
||||
public void onWebServerError() {
|
||||
state.postValue(new HotspotError(getApplication()
|
||||
.getString(R.string.hotspot_error_web_server_start)));
|
||||
hotspotManager.stopWifiP2pHotspot();
|
||||
stopHotspot();
|
||||
}
|
||||
|
||||
void exportApk(Uri uri) {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package org.briarproject.briar.android.hotspot;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
@@ -16,7 +18,6 @@ import org.briarproject.briar.android.hotspot.HotspotState.HotspotStarted;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
@@ -60,19 +61,23 @@ public class QrHotspotFragment extends Fragment {
|
||||
TextView qrIntroView = v.findViewById(R.id.qrIntroView);
|
||||
ImageView qrCodeView = v.findViewById(R.id.qrCodeView);
|
||||
|
||||
Consumer<HotspotStarted> consumer;
|
||||
if (requireArguments().getBoolean(ARG_FOR_WIFI_CONNECT)) {
|
||||
qrIntroView.setText(R.string.hotspot_qr_wifi);
|
||||
consumer = state ->
|
||||
qrCodeView.setImageBitmap(state.getNetworkConfig().qrCode);
|
||||
} else {
|
||||
qrIntroView.setText(R.string.hotspot_qr_site);
|
||||
consumer = state ->
|
||||
qrCodeView.setImageBitmap(state.getWebsiteConfig().qrCode);
|
||||
}
|
||||
boolean forWifi = requireArguments().getBoolean(ARG_FOR_WIFI_CONNECT);
|
||||
|
||||
qrIntroView.setText(forWifi ? R.string.hotspot_qr_wifi :
|
||||
R.string.hotspot_qr_site);
|
||||
|
||||
viewModel.getState().observe(getViewLifecycleOwner(), state -> {
|
||||
if (state instanceof HotspotStarted) {
|
||||
consumer.accept((HotspotStarted) state);
|
||||
HotspotStarted s = (HotspotStarted) state;
|
||||
Bitmap qrCode = forWifi ? s.getNetworkConfig().qrCode :
|
||||
s.getWebsiteConfig().qrCode;
|
||||
if (qrCode == null) {
|
||||
Toast.makeText(requireContext(), R.string.error,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
qrCodeView.setImageResource(R.drawable.ic_image_broken);
|
||||
} else {
|
||||
qrCodeView.setImageBitmap(qrCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
return v;
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.logging.Logger;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.list;
|
||||
@@ -49,7 +50,7 @@ class WebServerManager {
|
||||
private final WebServer webServer;
|
||||
private final DisplayMetrics dm;
|
||||
|
||||
private WebServerListener listener;
|
||||
private volatile WebServerListener listener;
|
||||
|
||||
@Inject
|
||||
WebServerManager(Application ctx) {
|
||||
@@ -57,6 +58,7 @@ class WebServerManager {
|
||||
dm = ctx.getResources().getDisplayMetrics();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void setListener(WebServerListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/feedbackButton"
|
||||
tools:layout="@layout/fragment_hotspot_save_apk" />
|
||||
tools:layout="@layout/fragment_hotspot_fallback" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
android:id="@id/fallbackTitleView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/hotspot_help_fallback_title"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
@@ -119,7 +119,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/site4View"
|
||||
tools:layout="@layout/fragment_hotspot_save_apk" />
|
||||
tools:layout="@layout/fragment_hotspot_fallback" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="spread_inside"
|
||||
app:srcCompat="@drawable/ic_nickname"
|
||||
app:srcCompat="@drawable/ic_wifi_tethering"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
|
||||
<!-- Share app offline -->
|
||||
<string name="hotspot_title">Share Briar offline</string>
|
||||
<string name="hotspot_intro">Share this app with someone nearby without internet connection by using your phone\'s Wi-Fi.
|
||||
<string name="hotspot_intro">Share this app with someone nearby without Internet connection by using your phone\'s Wi-Fi.
|
||||
\n\nYour phone will start a Wi-Fi hotspot. People nearby can connect to the hotspot and download the Briar app from your phone.</string>
|
||||
<string name="hotspot_button_start_sharing">Start hotspot</string>
|
||||
<string name="hotspot_button_stop_sharing">Stop hotspot</string>
|
||||
@@ -707,9 +707,10 @@
|
||||
<string name="permission_hotspot_location_denied_body">You have denied access to your location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
||||
<string name="wifi_settings_title">Wi-Fi setting</string>
|
||||
<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
|
||||
<string name="wifi_settings_request_denied_body">You have denied to enable Wi-Fi, but Briar needs to use Wi-Fi.\n\nPlease consider enabling it.</string>
|
||||
<string name="wifi_settings_request_denied_body">You have denied permission to enable Wi-Fi, but Briar needs to use Wi-Fi.\n\nPlease consider enabling it.</string>
|
||||
|
||||
<string name="hotspot_tab_manual">Manual</string>
|
||||
<!-- The placeholder to be inserted into the string 'hotspot_manual_wifi': People can connect by %s -->
|
||||
<string name="hotspot_scanning_a_qr_code">scanning a QR code</string>
|
||||
|
||||
<!-- Wi-Fi setup -->
|
||||
@@ -718,7 +719,6 @@
|
||||
<string name="hotspot_manual_wifi_ssid">Network name (SSID)</string>
|
||||
<string name="hotspot_qr_wifi">Your phone is providing a Wi-Fi hotspot. People who want to download Briar can connect to the hotspot by scanning this QR code. When they have connected to the hotspot, press \'Next\'.</string>
|
||||
<string name="hotspot_peer_connected">Successfully connected</string>
|
||||
<string name="hotspot_peer_connected_action">Show download info</string>
|
||||
|
||||
<!-- Download link -->
|
||||
<!-- The %s placeholder will be replaced with the translation of 'hotspot_scanning_a_qr_code' -->
|
||||
@@ -732,21 +732,21 @@
|
||||
<string name="website_download_outro">After the download is complete, open the downloaded file and install it.</string>
|
||||
<string name="website_troubleshooting_title">Troubleshooting</string>
|
||||
<string name="website_troubleshooting_1">If you cannot download the app, try it with a different web browser app.</string>
|
||||
<string name="website_troubleshooting_2_old">To install the downloaded app, you might need to allow installation of apps from \"Unknown sources\" in system settings. Afterwards, you may need to download the app again. We recommend to undo that after successful installation.</string>
|
||||
<string name="website_troubleshooting_2_new">To install the downloaded app, you might need to allow your browser to install unknown apps. We recommend to undo that after successful installation.</string>
|
||||
<string name="website_troubleshooting_2_old">To install the downloaded app, you might need to allow installation of apps from \"Unknown sources\" in system settings. Afterwards, you may need to download the app again. We recommend disabling the \"Unknown sources\" setting after installing the app.</string>
|
||||
<string name="website_troubleshooting_2_new">To install the downloaded app, you might need to allow your browser to install unknown apps. After installing the app, we recommend removing the browser\'s permission to install unknown apps.</string>
|
||||
|
||||
<string name="hotspot_help_wifi_title">Problems with connecting to Wi-Fi:</string>
|
||||
<string name="hotspot_help_wifi_1">Try disabling and re-enabling Wi-Fi on both phones and try again.</string>
|
||||
<string name="hotspot_help_wifi_2">If your phone complains that the Wi-Fi has no internet, tell it that you want to stay connected anyway.</string>
|
||||
<string name="hotspot_help_wifi_2">If your phone complains that the Wi-Fi has no Internet, tell it that you want to stay connected anyway.</string>
|
||||
<string name="hotspot_help_site_title">Problems visiting the local website:</string>
|
||||
<string name="hotspot_help_site_1">Double check that you entered the address exactly as shown. A small error can make it fail.</string>
|
||||
<string name="hotspot_help_site_2">Ensure that your phone is still connected to the correct Wi-Fi (see above) when you try to access the site.</string>
|
||||
<string name="hotspot_help_site_3">Check that you don\'t have any active firewall apps that may block the access.</string>
|
||||
<string name="hotspot_help_site_3">If you have a firewall app, check that it isn\'t blocking access.</string>
|
||||
<string name="hotspot_help_site_4">If you can visit the site, but not download the Briar app, try it with a different web browser app.</string>
|
||||
<string name="hotspot_help_fallback_title">Nothing works?</string>
|
||||
<string name="hotspot_help_fallback_intro">You can try to save the app as an .apk file to share in some other way. Once on the other device, it can be used to install Briar.
|
||||
<string name="hotspot_help_fallback_intro">You can try to save the app as an .apk file to share in some other way. Once the file has been transferred to the other device, it can be used to install Briar.
|
||||
\n\nTip: For sharing via Bluetooth, you might need to rename the file to end with .zip first.</string>
|
||||
<string name="hotspot_help_fallback_button">Save app install file</string>
|
||||
<string name="hotspot_help_fallback_button">Save app</string>
|
||||
|
||||
<!-- error handling -->
|
||||
<string name="hotspot_error_intro">Something went wrong while trying to share the app via Wi-Fi:</string>
|
||||
@@ -754,10 +754,10 @@
|
||||
<string name="hotspot_error_start_callback_failed">Hotspot failed to start: error %s</string>
|
||||
<string name="hotspot_error_start_callback_failed_unknown">Hotspot failed to start with an unknown error, reason %d</string>
|
||||
<string name="hotspot_error_start_callback_no_group_info">Hotspot failed to start: no group info</string>
|
||||
<string name="hotspot_error_web_server_start">Error starting web server!</string>
|
||||
<string name="hotspot_error_web_server_start">Error starting web server</string>
|
||||
<string name="hotspot_error_web_server_serve">Error presenting website.\n\nPlease send feedback (with anonymous data) via the Briar app if the issue persists.</string>
|
||||
<string name="hotspot_flag_test">Warning: This app was installed with Android Studio and can NOT be installed on another device.</string>
|
||||
<string name="hotspot_error_framework_busy">Unable to start the hotspot.\n\nIf you have another hotspot running or are sharing your internet connection via Wi-Fi, try stopping that and try again afterwards.</string>
|
||||
<string name="hotspot_error_framework_busy">Unable to start the hotspot.\n\nIf you have another hotspot running or are sharing your Internet connection via Wi-Fi, try stopping that and try again afterwards.</string>
|
||||
|
||||
|
||||
<!-- Transfer Data via Removable Drives -->
|
||||
|
||||
Reference in New Issue
Block a user