mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Ask before turning on Bluetooth to add a contact.
This commit is contained in:
@@ -120,6 +120,11 @@ class AndroidBluetoothPlugin extends BluetoothPlugin<BluetoothServerSocket> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void setEnabledByUs() {
|
||||
wasEnabledByUs = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
String getBluetoothAddress() {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.briarproject.bramble.api.plugin.event;
|
||||
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import jdk.nashorn.internal.ir.annotations.Immutable;
|
||||
|
||||
/**
|
||||
* An event that informs the Bluetooth plugin that we have enabled the
|
||||
* Bluetooth adapter.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
public class BluetoothEnabledEvent extends Event {
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
* An event asks the Bluetooth plugin to enable the Bluetooth adapter.
|
||||
* An event that asks the Bluetooth plugin to enable the Bluetooth adapter.
|
||||
*/
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPlugin;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexPluginCallback;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.DisableBluetoothEvent;
|
||||
import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent;
|
||||
import org.briarproject.bramble.api.properties.TransportProperties;
|
||||
@@ -51,8 +52,7 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(BluetoothPlugin.class.getName());
|
||||
|
||||
final Executor ioExecutor;
|
||||
|
||||
private final Executor ioExecutor;
|
||||
private final SecureRandom secureRandom;
|
||||
private final Backoff backoff;
|
||||
private final DuplexPluginCallback callback;
|
||||
@@ -70,6 +70,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||
|
||||
abstract void disableAdapterIfEnabledByUs();
|
||||
|
||||
abstract void setEnabledByUs();
|
||||
|
||||
@Nullable
|
||||
abstract String getBluetoothAddress();
|
||||
|
||||
@@ -358,6 +360,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
|
||||
ioExecutor.execute(this::enableAdapter);
|
||||
} else if (e instanceof DisableBluetoothEvent) {
|
||||
ioExecutor.execute(this::disableAdapterIfEnabledByUs);
|
||||
} else if (e instanceof BluetoothEnabledEvent) {
|
||||
setEnabledByUs();
|
||||
} else if (e instanceof SettingsUpdatedEvent) {
|
||||
SettingsUpdatedEvent s = (SettingsUpdatedEvent) e;
|
||||
if (s.getNamespace().equals(ID.getString()))
|
||||
|
||||
@@ -61,6 +61,11 @@ class JavaBluetoothPlugin extends BluetoothPlugin<StreamConnectionNotifier> {
|
||||
// We didn't enable it so we don't need to disable it
|
||||
}
|
||||
|
||||
@Override
|
||||
void setEnabledByUs() {
|
||||
// Irrelevant on this platform
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
String getBluetoothAddress() {
|
||||
|
||||
@@ -11,5 +11,6 @@ public interface RequestCodes {
|
||||
int REQUEST_RINGTONE = 7;
|
||||
int REQUEST_PERMISSION_CAMERA = 8;
|
||||
int REQUEST_DOZE_WHITELISTING = 9;
|
||||
int REQUEST_ENABLE_BLUETOOTH = 10;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package org.briarproject.briar.android.keyagreement;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
@@ -23,6 +28,7 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
|
||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.R.string;
|
||||
import org.briarproject.briar.R.style;
|
||||
@@ -39,9 +45,15 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.Manifest.permission.CAMERA;
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_ENABLE;
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
|
||||
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
|
||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ENABLE_BLUETOOTH;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@@ -50,6 +62,10 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
BaseFragmentListener, IntroScreenSeenListener, EventListener,
|
||||
ContactExchangeListener {
|
||||
|
||||
private enum BluetoothState {
|
||||
UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED
|
||||
}
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(KeyAgreementActivity.class.getName());
|
||||
|
||||
@@ -62,7 +78,10 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
@Inject
|
||||
volatile IdentityManager identityManager;
|
||||
|
||||
private boolean isResumed = false, enableWasRequested = false;
|
||||
private boolean continueClicked, gotCameraPermission;
|
||||
private BluetoothState bluetoothState = BluetoothState.UNKNOWN;
|
||||
private BroadcastReceiver bluetoothReceiver = null;
|
||||
|
||||
@Override
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
@@ -84,6 +103,15 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
if (state == null) {
|
||||
showInitialFragment(IntroFragment.newInstance());
|
||||
}
|
||||
IntentFilter filter = new IntentFilter(ACTION_STATE_CHANGED);
|
||||
bluetoothReceiver = new BluetoothStateReceiver();
|
||||
registerReceiver(bluetoothReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (bluetoothReceiver != null) unregisterReceiver(bluetoothReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,24 +140,72 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
@Override
|
||||
protected void onPostResume() {
|
||||
super.onPostResume();
|
||||
isResumed = true;
|
||||
// Workaround for
|
||||
// https://code.google.com/p/android/issues/detail?id=190966
|
||||
if (continueClicked && gotCameraPermission) {
|
||||
showQrCodeFragment();
|
||||
}
|
||||
if (canShowQrCodeFragment()) showQrCodeFragment();
|
||||
}
|
||||
|
||||
boolean canShowQrCodeFragment() {
|
||||
return isResumed && continueClicked
|
||||
&& (SDK_INT < 23 || gotCameraPermission)
|
||||
&& bluetoothState != BluetoothState.UNKNOWN
|
||||
&& bluetoothState != BluetoothState.WAITING;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
isResumed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showNextScreen() {
|
||||
// FIXME #824
|
||||
// showNextFragment(ShowQrCodeFragment.newInstance());
|
||||
continueClicked = true;
|
||||
if (checkPermissions()) {
|
||||
showQrCodeFragment();
|
||||
if (shouldRequestEnableBluetooth()) requestEnableBluetooth();
|
||||
else if (canShowQrCodeFragment()) showQrCodeFragment();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldRequestEnableBluetooth() {
|
||||
return bluetoothState == BluetoothState.UNKNOWN
|
||||
|| bluetoothState == BluetoothState.REFUSED;
|
||||
}
|
||||
|
||||
private void requestEnableBluetooth() {
|
||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||
if (bt == null) {
|
||||
setBluetoothState(BluetoothState.NO_ADAPTER);
|
||||
} else if (bt.isEnabled()) {
|
||||
setBluetoothState(BluetoothState.ENABLED);
|
||||
} else {
|
||||
enableWasRequested = true;
|
||||
setBluetoothState(BluetoothState.WAITING);
|
||||
Intent i = new Intent(ACTION_REQUEST_ENABLE);
|
||||
startActivityForResult(i, REQUEST_ENABLE_BLUETOOTH);
|
||||
}
|
||||
}
|
||||
|
||||
private void setBluetoothState(BluetoothState bluetoothState) {
|
||||
LOG.info("Setting Bluetooth state to " + bluetoothState);
|
||||
this.bluetoothState = bluetoothState;
|
||||
if (enableWasRequested && bluetoothState == BluetoothState.ENABLED) {
|
||||
eventBus.broadcast(new BluetoothEnabledEvent());
|
||||
enableWasRequested = false;
|
||||
}
|
||||
if (canShowQrCodeFragment()) showQrCodeFragment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int request, int result, Intent data) {
|
||||
// If the request was granted we'll catch the state change event
|
||||
if (request == REQUEST_ENABLE_BLUETOOTH && result == RESULT_CANCELED)
|
||||
setBluetoothState(BluetoothState.REFUSED);
|
||||
}
|
||||
|
||||
private void showQrCodeFragment() {
|
||||
// FIXME #824
|
||||
BaseFragment f = ShowQrCodeFragment.newInstance();
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||
@@ -154,8 +230,10 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
} else {
|
||||
requestPermission();
|
||||
}
|
||||
gotCameraPermission = false;
|
||||
return false;
|
||||
} else {
|
||||
gotCameraPermission = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -174,6 +252,7 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
if (grantResults.length > 0 &&
|
||||
grantResults[0] == PERMISSION_GRANTED) {
|
||||
gotCameraPermission = true;
|
||||
showNextScreen();
|
||||
} else {
|
||||
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||
CAMERA)) {
|
||||
@@ -258,4 +337,14 @@ public class KeyAgreementActivity extends BriarActivity implements
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
||||
if (state == STATE_ON) setBluetoothState(BluetoothState.ENABLED);
|
||||
else setBluetoothState(BluetoothState.UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package org.briarproject.briar.android.keyagreement;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Bitmap;
|
||||
import android.hardware.Camera;
|
||||
import android.os.AsyncTask;
|
||||
@@ -40,7 +36,6 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementWaitingEvent;
|
||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.bramble.api.plugin.event.EnableBluetoothEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.fragment.BaseEventFragment;
|
||||
@@ -52,9 +47,6 @@ import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
|
||||
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
|
||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
|
||||
import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
@@ -89,8 +81,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
private TextView mainProgressTitle;
|
||||
private ViewGroup mainProgressContainer;
|
||||
|
||||
private BluetoothStateReceiver receiver;
|
||||
private boolean gotRemotePayload, waitingForBluetooth;
|
||||
private boolean gotRemotePayload;
|
||||
private volatile boolean gotLocalPayload;
|
||||
private KeyAgreementTask task;
|
||||
|
||||
@@ -151,20 +142,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
} catch (CameraException e) {
|
||||
logCameraExceptionAndFinish(e);
|
||||
}
|
||||
// Listen for changes to the Bluetooth state
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_STATE_CHANGED);
|
||||
receiver = new BluetoothStateReceiver();
|
||||
getActivity().registerReceiver(receiver, filter);
|
||||
|
||||
// Enable BT adapter if it is not already on.
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (adapter != null && !adapter.isEnabled()) {
|
||||
waitingForBluetooth = true;
|
||||
eventBus.broadcast(new EnableBluetoothEvent());
|
||||
} else {
|
||||
startListening();
|
||||
}
|
||||
startListening();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +168,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
stopListening();
|
||||
if (receiver != null) getActivity().unregisterReceiver(receiver);
|
||||
try {
|
||||
cameraView.stop();
|
||||
} catch (CameraException e) {
|
||||
@@ -362,16 +339,4 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
protected void finish() {
|
||||
getActivity().getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
@UiThread
|
||||
@Override
|
||||
public void onReceive(Context ctx, Intent intent) {
|
||||
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
||||
if (state == STATE_ON && waitingForBluetooth) {
|
||||
waitingForBluetooth = false;
|
||||
startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user