mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 03:09:04 +01:00
Resolve merge conflict with 1872-key-agreement
This commit is contained in:
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -50,12 +49,6 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
private AddNearbyContactPermissionManager permissionManager;
|
||||
|
||||
private final ActivityResultLauncher<String[]> permissionLauncher =
|
||||
registerForActivityResult(new RequestMultiplePermissions(), r ->
|
||||
permissionManager.onRequestPermissionResult(r,
|
||||
viewModel::showQrCodeFragmentIfAllowed));
|
||||
private final ActivityResultLauncher<Integer> bluetoothLauncher =
|
||||
registerForActivityResult(new RequestBluetoothDiscoverable(),
|
||||
this::onBluetoothDiscoverableResult);
|
||||
@@ -65,8 +58,6 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
component.inject(this);
|
||||
viewModel = new ViewModelProvider(this, viewModelFactory)
|
||||
.get(AddNearbyContactViewModel.class);
|
||||
permissionManager = new AddNearbyContactPermissionManager(this,
|
||||
permissionLauncher::launch, viewModel.isBluetoothSupported());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +70,6 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
if (state == null) {
|
||||
showInitialFragment(AddNearbyContactIntroFragment.newInstance());
|
||||
}
|
||||
viewModel.getCheckPermissions().observeEvent(this, check ->
|
||||
permissionManager.checkPermissions());
|
||||
viewModel.getRequestBluetoothDiscoverable().observeEvent(this, r ->
|
||||
requestBluetoothDiscoverable()); // never false
|
||||
viewModel.getShowQrCodeFragment().observeEvent(this, show -> {
|
||||
@@ -92,13 +81,6 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
.observe(this, this::onAddContactStateChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// Permissions may have been granted manually while we were stopped
|
||||
permissionManager.resetPermissions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostResume() {
|
||||
super.onPostResume();
|
||||
@@ -143,17 +125,13 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
}
|
||||
|
||||
private void requestBluetoothDiscoverable() {
|
||||
if (!viewModel.isBluetoothSupported()) {
|
||||
viewModel.setBluetoothDecision(BluetoothDecision.NO_ADAPTER);
|
||||
Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE);
|
||||
if (i.resolveActivity(getPackageManager()) != null) {
|
||||
LOG.info("Asking for Bluetooth discoverability");
|
||||
viewModel.setBluetoothDecision(BluetoothDecision.WAITING);
|
||||
bluetoothLauncher.launch(120); // 2min discoverable
|
||||
} else {
|
||||
Intent i = new Intent(ACTION_REQUEST_DISCOVERABLE);
|
||||
if (i.resolveActivity(getPackageManager()) != null) {
|
||||
LOG.info("Asking for Bluetooth discoverability");
|
||||
viewModel.setBluetoothDecision(BluetoothDecision.WAITING);
|
||||
bluetoothLauncher.launch(120); // 2min discoverable
|
||||
} else {
|
||||
viewModel.setBluetoothDecision(BluetoothDecision.NO_ADAPTER);
|
||||
}
|
||||
viewModel.setBluetoothDecision(BluetoothDecision.NO_ADAPTER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +147,7 @@ public class AddNearbyContactActivity extends BriarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void onAddContactStateChanged(AddContactState state) {
|
||||
private void onAddContactStateChanged(@Nullable AddContactState state) {
|
||||
if (state instanceof ContactExchangeFinished) {
|
||||
ContactExchangeResult result =
|
||||
((ContactExchangeFinished) state).result;
|
||||
|
||||
@@ -100,7 +100,7 @@ public class AddNearbyContactFragment extends BaseFragment
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
requireActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
|
||||
cameraView.setPreviewConsumer(viewModel.qrCodeDecoder);
|
||||
cameraView.setPreviewConsumer(viewModel.getQrCodeDecoder());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,7 +153,7 @@ public class AddNearbyContactFragment extends BaseFragment
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onAddContactStateChanged(AddContactState state) {
|
||||
private void onAddContactStateChanged(@Nullable AddContactState state) {
|
||||
if (state instanceof AddContactState.KeyAgreementListening) {
|
||||
Bitmap qrCode =
|
||||
((AddContactState.KeyAgreementListening) state).qrCode;
|
||||
|
||||
@@ -15,6 +15,8 @@ import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.activity.result.ActivityResultLauncher;
|
||||
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.view.View.FOCUS_DOWN;
|
||||
@@ -23,15 +25,22 @@ import static android.view.View.FOCUS_DOWN;
|
||||
@ParametersNotNullByDefault
|
||||
public class AddNearbyContactIntroFragment extends BaseFragment {
|
||||
|
||||
public static final String TAG = AddNearbyContactIntroFragment.class.getName();
|
||||
public static final String TAG =
|
||||
AddNearbyContactIntroFragment.class.getName();
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
private AddNearbyContactPermissionManager permissionManager;
|
||||
|
||||
private ScrollView scrollView;
|
||||
|
||||
private final ActivityResultLauncher<String[]> permissionLauncher =
|
||||
registerForActivityResult(new RequestMultiplePermissions(), r ->
|
||||
permissionManager.onRequestPermissionResult(r,
|
||||
viewModel::showQrCodeFragmentIfAllowed));
|
||||
|
||||
public static AddNearbyContactIntroFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
AddNearbyContactIntroFragment
|
||||
@@ -45,6 +54,9 @@ public class AddNearbyContactIntroFragment extends BaseFragment {
|
||||
component.inject(this);
|
||||
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||
.get(AddNearbyContactViewModel.class);
|
||||
permissionManager = new AddNearbyContactPermissionManager(
|
||||
requireActivity(), permissionLauncher::launch,
|
||||
viewModel.isBluetoothSupported());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -57,13 +69,17 @@ public class AddNearbyContactIntroFragment extends BaseFragment {
|
||||
false);
|
||||
scrollView = v.findViewById(R.id.scrollView);
|
||||
View button = v.findViewById(R.id.continueButton);
|
||||
button.setOnClickListener(view -> viewModel.onContinueClicked());
|
||||
button.setOnClickListener(view -> viewModel.onContinueClicked(() ->
|
||||
permissionManager.checkPermissions()
|
||||
));
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// Permissions may have been granted manually while we were stopped
|
||||
permissionManager.resetPermissions();
|
||||
scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.LocationManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.BaseActivity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.util.Consumer;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
import static android.Manifest.permission.CAMERA;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale;
|
||||
import static androidx.core.content.ContextCompat.checkSelfPermission;
|
||||
import static org.briarproject.briar.android.util.UiUtils.getGoToSettingsListener;
|
||||
@@ -28,11 +34,11 @@ public class AddNearbyContactPermissionManager {
|
||||
private Permission cameraPermission = Permission.UNKNOWN;
|
||||
private Permission locationPermission = Permission.UNKNOWN;
|
||||
|
||||
private final BaseActivity ctx;
|
||||
private final FragmentActivity ctx;
|
||||
private final Consumer<String[]> requestPermissions;
|
||||
private final boolean isBluetoothSupported;
|
||||
|
||||
public AddNearbyContactPermissionManager(BaseActivity ctx,
|
||||
public AddNearbyContactPermissionManager(FragmentActivity ctx,
|
||||
Consumer<String[]> requestPermissions,
|
||||
boolean isBluetoothSupported) {
|
||||
this.ctx = ctx;
|
||||
@@ -45,6 +51,19 @@ public class AddNearbyContactPermissionManager {
|
||||
locationPermission = Permission.UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if location is enabled,
|
||||
* or it isn't required due to this being a SDK < 28 device.
|
||||
*/
|
||||
static boolean isLocationEnabled(Context ctx) {
|
||||
if (SDK_INT >= 28) {
|
||||
LocationManager lm = ctx.getSystemService(LocationManager.class);
|
||||
return lm.isLocationEnabled();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean areEssentialPermissionsGranted(Context ctx,
|
||||
boolean isBluetoothSupported) {
|
||||
int ok = PERMISSION_GRANTED;
|
||||
@@ -54,14 +73,15 @@ public class AddNearbyContactPermissionManager {
|
||||
!isBluetoothSupported);
|
||||
}
|
||||
|
||||
boolean areEssentialPermissionsGranted() {
|
||||
private boolean areEssentialPermissionsGranted() {
|
||||
return cameraPermission == Permission.GRANTED &&
|
||||
(SDK_INT < 23 || locationPermission == Permission.GRANTED ||
|
||||
!isBluetoothSupported);
|
||||
}
|
||||
|
||||
public boolean checkPermissions() {
|
||||
if (areEssentialPermissionsGranted()) return true;
|
||||
public boolean checkPermissions() {
|
||||
boolean locationEnabled = isLocationEnabled(ctx);
|
||||
if (locationEnabled && areEssentialPermissionsGranted()) return true;
|
||||
// If an essential permission has been permanently denied, ask the
|
||||
// user to change the setting
|
||||
if (cameraPermission == Permission.PERMANENTLY_DENIED) {
|
||||
@@ -86,8 +106,10 @@ public class AddNearbyContactPermissionManager {
|
||||
} else if (locationPermission == Permission.SHOW_RATIONALE) {
|
||||
showRationale(R.string.permission_location_title,
|
||||
R.string.permission_location_request_body);
|
||||
} else {
|
||||
} else if (isLocationEnabled(ctx)) {
|
||||
requestPermissions();
|
||||
} else {
|
||||
showLocationDialog(ctx);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -113,6 +135,25 @@ public class AddNearbyContactPermissionManager {
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static void showLocationDialog(Context ctx) {
|
||||
AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(ctx, R.style.BriarDialogTheme);
|
||||
builder.setTitle(R.string.permission_location_setting_title);
|
||||
builder.setMessage(R.string.permission_location_setting_body);
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setPositiveButton(R.string.permission_location_setting_button,
|
||||
(dialog, which) -> {
|
||||
Intent i = new Intent(ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
try {
|
||||
ctx.startActivity(i);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(ctx, R.string.error_start_activity,
|
||||
LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void requestPermissions() {
|
||||
String[] permissions;
|
||||
if (isBluetoothSupported) {
|
||||
|
||||
@@ -65,6 +65,7 @@ import javax.inject.Provider;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.core.util.Supplier;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
@@ -83,6 +84,8 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager.areEssentialPermissionsGranted;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager.isLocationEnabled;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.NO_ADAPTER;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.UNKNOWN;
|
||||
|
||||
@@ -133,8 +136,6 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
private final ContactExchangeManager contactExchangeManager;
|
||||
private final ConnectionManager connectionManager;
|
||||
|
||||
private final MutableLiveEvent<Boolean> checkPermissions =
|
||||
new MutableLiveEvent<>();
|
||||
private final MutableLiveEvent<Boolean> requestBluetoothDiscoverable =
|
||||
new MutableLiveEvent<>();
|
||||
private final MutableLiveEvent<Boolean> showQrCodeFragment =
|
||||
@@ -142,8 +143,9 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
private final MutableLiveData<AddContactState> state =
|
||||
new MutableLiveData<>();
|
||||
|
||||
final QrCodeDecoder qrCodeDecoder;
|
||||
final BroadcastReceiver bluetoothReceiver = new BluetoothStateReceiver();
|
||||
private final QrCodeDecoder qrCodeDecoder;
|
||||
private final BroadcastReceiver bluetoothReceiver =
|
||||
new BluetoothStateReceiver();
|
||||
|
||||
@Nullable
|
||||
private final BluetoothAdapter bt;
|
||||
@@ -169,7 +171,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
private boolean hasEnabledBluetooth = false;
|
||||
|
||||
@Nullable
|
||||
private KeyAgreementTask task;
|
||||
private volatile KeyAgreementTask task;
|
||||
private volatile boolean gotLocalPayload = false, gotRemotePayload = false;
|
||||
|
||||
@Inject
|
||||
@@ -211,13 +213,12 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void onContinueClicked() {
|
||||
void onContinueClicked(Supplier<Boolean> checkPermissions) {
|
||||
if (bluetoothDecision == REFUSED) {
|
||||
bluetoothDecision = UNKNOWN; // Ask again
|
||||
}
|
||||
wasContinueClicked = true;
|
||||
checkPermissions.setEvent(true);
|
||||
showQrCodeFragmentIfAllowed();
|
||||
if (checkPermissions.get()) showQrCodeFragmentIfAllowed();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -226,7 +227,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
boolean isWifiReady() {
|
||||
private boolean isWifiReady() {
|
||||
if (wifiPlugin == null) return true; // Continue without wifi
|
||||
State state = wifiPlugin.getState();
|
||||
// Wait for plugin to become enabled
|
||||
@@ -234,7 +235,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
boolean isBluetoothReady() {
|
||||
private boolean isBluetoothReady() {
|
||||
if (bt == null || bluetoothPlugin == null) {
|
||||
// Continue without Bluetooth
|
||||
return true;
|
||||
@@ -254,7 +255,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void enableWifiIfWeShould() {
|
||||
private void enableWifiIfWeShould() {
|
||||
if (hasEnabledWifi) return;
|
||||
if (wifiPlugin == null) return;
|
||||
State state = wifiPlugin.getState();
|
||||
@@ -266,7 +267,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void enableBluetoothIfWeShould() {
|
||||
private void enableBluetoothIfWeShould() {
|
||||
if (bluetoothDecision != BluetoothDecision.ACCEPTED) return;
|
||||
if (hasEnabledBluetooth) return;
|
||||
if (bluetoothPlugin == null || !isBluetoothSupported()) return;
|
||||
@@ -279,7 +280,7 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
}
|
||||
|
||||
@UiThread
|
||||
void startAddingContact() {
|
||||
private void startAddingContact() {
|
||||
// If we return to the intro fragment, the continue button needs to be
|
||||
// clicked again before showing the QR code fragment
|
||||
wasContinueClicked = false;
|
||||
@@ -290,6 +291,8 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
// Bluetooth again
|
||||
hasEnabledWifi = false;
|
||||
hasEnabledBluetooth = false;
|
||||
// reset state, so we don't show an old QR code again
|
||||
state.setValue(null);
|
||||
// start to listen with a KeyAgreementTask
|
||||
startListening();
|
||||
showQrCodeFragment.setEvent(true);
|
||||
@@ -365,14 +368,20 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
void showQrCodeFragmentIfAllowed() {
|
||||
boolean permissionsGranted = areEssentialPermissionsGranted(
|
||||
getApplication(), isBluetoothSupported());
|
||||
if (isActivityResumed && wasContinueClicked && permissionsGranted) {
|
||||
boolean locationEnabled = isLocationEnabled(getApplication());
|
||||
if (isActivityResumed && wasContinueClicked && permissionsGranted &&
|
||||
locationEnabled) {
|
||||
if (isWifiReady() && isBluetoothReady()) {
|
||||
LOG.info("Wifi and Bluetooth are ready");
|
||||
startAddingContact();
|
||||
} else {
|
||||
enableWifiIfWeShould();
|
||||
if (bluetoothDecision == UNKNOWN) {
|
||||
requestBluetoothDiscoverable.setEvent(true);
|
||||
if (isBluetoothSupported()) {
|
||||
requestBluetoothDiscoverable.setEvent(true);
|
||||
} else {
|
||||
bluetoothDecision = NO_ADAPTER;
|
||||
}
|
||||
} else if (bluetoothDecision == REFUSED) {
|
||||
// Ask again when the user clicks "continue"
|
||||
} else {
|
||||
@@ -501,8 +510,8 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
showQrCodeFragmentIfAllowed();
|
||||
}
|
||||
|
||||
LiveEvent<Boolean> getCheckPermissions() {
|
||||
return checkPermissions;
|
||||
QrCodeDecoder getQrCodeDecoder() {
|
||||
return qrCodeDecoder;
|
||||
}
|
||||
|
||||
LiveEvent<Boolean> getRequestBluetoothDiscoverable() {
|
||||
@@ -513,6 +522,9 @@ class AddNearbyContactViewModel extends AndroidViewModel
|
||||
return showQrCodeFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* This LiveData will be null initially.
|
||||
*/
|
||||
LiveData<AddContactState> getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -609,6 +609,9 @@
|
||||
<string name="permission_camera_location_request_body">To scan the QR code, Briar needs access to the camera.\n\nTo discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
||||
<string name="permission_camera_denied_body">You have denied access to the camera, but adding contacts requires using the camera.\n\nPlease consider granting access.</string>
|
||||
<string name="permission_location_denied_body">You have denied access to your location, but Briar needs this permission to discover Bluetooth devices.\n\nPlease consider granting access.</string>
|
||||
<string name="permission_location_setting_title">Location setting</string>
|
||||
<string name="permission_location_setting_body">Your device\'s location setting must be turned on to find other devices via Bluetooth. Please enable location to continue. You can disable it again afterwards.</string>
|
||||
<string name="permission_location_setting_button">Enable location</string>
|
||||
<string name="qr_code">QR code</string>
|
||||
<string name="show_qr_code_fullscreen">Show QR code fullscreen</string>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user