mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Enable BT plugin before showing QR code.
This commit is contained in:
@@ -8,10 +8,20 @@ import android.content.IntentFilter;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
|
import org.briarproject.bramble.api.event.EventListener;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||||
|
import org.briarproject.bramble.api.plugin.Plugin;
|
||||||
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
import org.briarproject.bramble.api.plugin.event.BluetoothEnabledEvent;
|
||||||
|
import org.briarproject.bramble.api.plugin.event.TransportActiveEvent;
|
||||||
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
|
import org.briarproject.bramble.api.settings.SettingsManager;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
@@ -21,6 +31,7 @@ import org.briarproject.briar.android.keyagreement.IntroFragment.IntroScreenSeen
|
|||||||
import org.briarproject.briar.android.keyagreement.KeyAgreementFragment.KeyAgreementEventListener;
|
import org.briarproject.briar.android.keyagreement.KeyAgreementFragment.KeyAgreementEventListener;
|
||||||
import org.briarproject.briar.android.util.UiUtils;
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -37,15 +48,15 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
|||||||
import static android.Manifest.permission.CAMERA;
|
import static android.Manifest.permission.CAMERA;
|
||||||
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
||||||
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
||||||
import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
|
|
||||||
import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE;
|
import static android.bluetooth.BluetoothAdapter.EXTRA_SCAN_MODE;
|
||||||
import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
|
|
||||||
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE;
|
|
||||||
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
import static android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||||
import static android.bluetooth.BluetoothAdapter.STATE_ON;
|
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
|
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENABLE;
|
||||||
|
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
|
||||||
|
|
||||||
@@ -53,10 +64,41 @@ import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMI
|
|||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public abstract class KeyAgreementActivity extends BriarActivity implements
|
public abstract class KeyAgreementActivity extends BriarActivity implements
|
||||||
BaseFragmentListener, IntroScreenSeenListener,
|
BaseFragmentListener, IntroScreenSeenListener,
|
||||||
KeyAgreementEventListener {
|
KeyAgreementEventListener, EventListener {
|
||||||
|
|
||||||
private enum BluetoothState {
|
private enum BluetoothState {
|
||||||
UNKNOWN, NO_ADAPTER, WAITING, REFUSED, ENABLED, DISCOVERABLE
|
/**
|
||||||
|
* We don't yet know the state of the Bluetooth adapter or plugin.
|
||||||
|
*/
|
||||||
|
UNKNOWN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The device doesn't have a Bluetooth adapter.
|
||||||
|
*/
|
||||||
|
NO_ADAPTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We're waiting for the user to decide whether to allow
|
||||||
|
* discoverability, or the user has allowed discoverability and we're
|
||||||
|
* waiting for the adapter to become discoverable.
|
||||||
|
*/
|
||||||
|
WAITING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user has refused discoverability.
|
||||||
|
*/
|
||||||
|
REFUSED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Bluetooth adapter is discoverable.
|
||||||
|
*/
|
||||||
|
DISCOVERABLE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Bluetooth adapter is discoverable and we're waiting for the
|
||||||
|
* Bluetooth plugin to become active.
|
||||||
|
*/
|
||||||
|
ACTIVATING_PLUGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Permission {
|
private enum Permission {
|
||||||
@@ -69,6 +111,16 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
@Inject
|
@Inject
|
||||||
EventBus eventBus;
|
EventBus eventBus;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PluginManager pluginManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@IoExecutor
|
||||||
|
Executor ioExecutor;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SettingsManager settingsManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set to true in onPostResume() and false in onPause(). This prevents the
|
* Set to true in onPostResume() and false in onPause(). This prevents the
|
||||||
* QR code fragment from being shown if onRequestPermissionsResult() is
|
* QR code fragment from being shown if onRequestPermissionsResult() is
|
||||||
@@ -91,6 +143,13 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
*/
|
*/
|
||||||
private boolean wasAdapterEnabled = false;
|
private boolean wasAdapterEnabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records whether the user accepted the most recent request (if any) to
|
||||||
|
* make the Bluetooth adapter discoverable, so we know whether to broadcast
|
||||||
|
* a {@link BluetoothEnabledEvent}.
|
||||||
|
*/
|
||||||
|
private boolean wasRequestAccepted = false;
|
||||||
|
|
||||||
private Permission cameraPermission = Permission.UNKNOWN;
|
private Permission cameraPermission = Permission.UNKNOWN;
|
||||||
private Permission locationPermission = Permission.UNKNOWN;
|
private Permission locationPermission = Permission.UNKNOWN;
|
||||||
private BluetoothState bluetoothState = BluetoothState.UNKNOWN;
|
private BluetoothState bluetoothState = BluetoothState.UNKNOWN;
|
||||||
@@ -111,9 +170,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
if (state == null) {
|
if (state == null) {
|
||||||
showInitialFragment(IntroFragment.newInstance());
|
showInitialFragment(IntroFragment.newInstance());
|
||||||
}
|
}
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
|
||||||
filter.addAction(ACTION_STATE_CHANGED);
|
|
||||||
filter.addAction(ACTION_SCAN_MODE_CHANGED);
|
|
||||||
bluetoothReceiver = new BluetoothStateReceiver();
|
bluetoothReceiver = new BluetoothStateReceiver();
|
||||||
registerReceiver(bluetoothReceiver, filter);
|
registerReceiver(bluetoothReceiver, filter);
|
||||||
}
|
}
|
||||||
@@ -136,6 +193,7 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
eventBus.addListener(this);
|
||||||
// Permissions may have been granted manually while we were stopped
|
// Permissions may have been granted manually while we were stopped
|
||||||
cameraPermission = Permission.UNKNOWN;
|
cameraPermission = Permission.UNKNOWN;
|
||||||
locationPermission = Permission.UNKNOWN;
|
locationPermission = Permission.UNKNOWN;
|
||||||
@@ -152,11 +210,22 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
|
|
||||||
private void showQrCodeFragmentIfAllowed() {
|
private void showQrCodeFragmentIfAllowed() {
|
||||||
if (isResumed && continueClicked && areEssentialPermissionsGranted()) {
|
if (isResumed && continueClicked && areEssentialPermissionsGranted()) {
|
||||||
if (bluetoothState == BluetoothState.UNKNOWN ||
|
if (bluetoothState == BluetoothState.UNKNOWN) {
|
||||||
bluetoothState == BluetoothState.ENABLED) {
|
|
||||||
requestBluetoothDiscoverable();
|
requestBluetoothDiscoverable();
|
||||||
} else if (bluetoothState != BluetoothState.WAITING) {
|
} else if (bluetoothState == BluetoothState.NO_ADAPTER ||
|
||||||
|
bluetoothState == BluetoothState.REFUSED) {
|
||||||
|
LOG.info("Continuing without Bluetooth");
|
||||||
showQrCodeFragment();
|
showQrCodeFragment();
|
||||||
|
} else if (bluetoothState == BluetoothState.DISCOVERABLE ||
|
||||||
|
bluetoothState == BluetoothState.ACTIVATING_PLUGIN) {
|
||||||
|
if (isBluetoothPluginActive()) {
|
||||||
|
LOG.info("Bluetooth plugin is active");
|
||||||
|
showQrCodeFragment();
|
||||||
|
} else {
|
||||||
|
LOG.info("Enabling Bluetooth plugin");
|
||||||
|
bluetoothState = BluetoothState.ACTIVATING_PLUGIN;
|
||||||
|
enableBluetoothPlugin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,12 +238,36 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
locationPermission == Permission.PERMANENTLY_DENIED);
|
locationPermission == Permission.PERMANENTLY_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isBluetoothPluginActive() {
|
||||||
|
Plugin p = pluginManager.getPlugin(BluetoothConstants.ID);
|
||||||
|
return p != null && p.getState() == ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableBluetoothPlugin() {
|
||||||
|
ioExecutor.execute(() -> {
|
||||||
|
try {
|
||||||
|
Settings s = new Settings();
|
||||||
|
s.putBoolean(PREF_BT_ENABLE, true);
|
||||||
|
String namespace = BluetoothConstants.ID.getString();
|
||||||
|
settingsManager.mergeSettings(s, namespace);
|
||||||
|
} catch (DbException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
isResumed = false;
|
isResumed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
eventBus.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showNextScreen() {
|
public void showNextScreen() {
|
||||||
continueClicked = true;
|
continueClicked = true;
|
||||||
@@ -200,8 +293,11 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
private void setBluetoothState(BluetoothState bluetoothState) {
|
private void setBluetoothState(BluetoothState bluetoothState) {
|
||||||
LOG.info("Setting Bluetooth state to " + bluetoothState);
|
LOG.info("Setting Bluetooth state to " + bluetoothState);
|
||||||
this.bluetoothState = bluetoothState;
|
this.bluetoothState = bluetoothState;
|
||||||
if (!wasAdapterEnabled && bluetoothState == BluetoothState.ENABLED) {
|
if (!wasAdapterEnabled && wasRequestAccepted &&
|
||||||
|
bluetoothState == BluetoothState.DISCOVERABLE) {
|
||||||
|
LOG.info("Bluetooth adapter was enabled by us");
|
||||||
eventBus.broadcast(new BluetoothEnabledEvent());
|
eventBus.broadcast(new BluetoothEnabledEvent());
|
||||||
|
wasRequestAccepted = false;
|
||||||
wasAdapterEnabled = true;
|
wasAdapterEnabled = true;
|
||||||
}
|
}
|
||||||
showQrCodeFragmentIfAllowed();
|
showQrCodeFragmentIfAllowed();
|
||||||
@@ -214,12 +310,14 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
if (result == RESULT_CANCELED) {
|
if (result == RESULT_CANCELED) {
|
||||||
setBluetoothState(BluetoothState.REFUSED);
|
setBluetoothState(BluetoothState.REFUSED);
|
||||||
} else {
|
} else {
|
||||||
|
wasRequestAccepted = true;
|
||||||
// If Bluetooth is already discoverable, show the QR code -
|
// If Bluetooth is already discoverable, show the QR code -
|
||||||
// otherwise wait for the state or scan mode to change
|
// otherwise wait for the state or scan mode to change
|
||||||
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (bt == null) throw new AssertionError();
|
if (bt == null) throw new AssertionError();
|
||||||
if (bt.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE)
|
if (bt.getScanMode() == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||||
setBluetoothState(BluetoothState.DISCOVERABLE);
|
setBluetoothState(BluetoothState.DISCOVERABLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else super.onActivityResult(request, result, data);
|
} else super.onActivityResult(request, result, data);
|
||||||
}
|
}
|
||||||
@@ -332,23 +430,30 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
|
|||||||
permission);
|
permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventOccurred(Event e) {
|
||||||
|
if (e instanceof TransportActiveEvent) {
|
||||||
|
TransportActiveEvent t = (TransportActiveEvent) e;
|
||||||
|
if (t.getTransportId().equals(BluetoothConstants.ID)) {
|
||||||
|
showQrCodeFragmentIfAllowed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (ACTION_STATE_CHANGED.equals(action)) {
|
if (ACTION_SCAN_MODE_CHANGED.equals(action)) {
|
||||||
int state = intent.getIntExtra(EXTRA_STATE, 0);
|
|
||||||
if (state == STATE_ON)
|
|
||||||
setBluetoothState(BluetoothState.ENABLED);
|
|
||||||
else setBluetoothState(BluetoothState.UNKNOWN);
|
|
||||||
} else if (ACTION_SCAN_MODE_CHANGED.equals(action)) {
|
|
||||||
int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, 0);
|
int scanMode = intent.getIntExtra(EXTRA_SCAN_MODE, 0);
|
||||||
if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE)
|
if (scanMode == SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
|
||||||
|
LOG.info("Bluetooth adapter is discoverable");
|
||||||
setBluetoothState(BluetoothState.DISCOVERABLE);
|
setBluetoothState(BluetoothState.DISCOVERABLE);
|
||||||
else if (scanMode == SCAN_MODE_CONNECTABLE)
|
} else if (bluetoothState == BluetoothState.DISCOVERABLE) {
|
||||||
setBluetoothState(BluetoothState.ENABLED);
|
LOG.info("Bluetooth adapter is not discoverable");
|
||||||
else setBluetoothState(BluetoothState.UNKNOWN);
|
setBluetoothState(BluetoothState.UNKNOWN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user