mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
add CompanionDeviceService initiated re-connection (#5023)
This commit is contained in:
committed by
José Rebelo
parent
b30ede77c7
commit
443594db8c
+33
-20
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2016-2024 Andreas Shimokawa, Daniel Dakhno, José Rebelo
|
||||
/* Copyright (C) 2016-2025 Andreas Shimokawa, Daniel Dakhno, José Rebelo, Thomas Kuehne
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.externalevents;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State.WAITING_FOR_RECONNECT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State.WAITING_FOR_SCAN;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -26,6 +29,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
@@ -33,10 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
public class BluetoothConnectReceiver extends BroadcastReceiver {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(BluetoothConnectReceiver.class);
|
||||
|
||||
final DeviceCommunicationService service;
|
||||
|
||||
public BluetoothConnectReceiver(final DeviceCommunicationService service) {
|
||||
this.service = service;
|
||||
public BluetoothConnectReceiver(final DeviceCommunicationService ignored) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,26 +57,38 @@ public class BluetoothConnectReceiver extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("connection attempt detected from {}", device.getAddress());
|
||||
final String address = device.getAddress();
|
||||
LOG.debug("observed device {} via ACL_CONNECTED", address);
|
||||
|
||||
final GBDevice gbDevice = GBApplication.app().getDeviceManager().getDeviceByAddress(device.getAddress());
|
||||
observedDevice(address);
|
||||
}
|
||||
|
||||
public static void observedDevice(String address) {
|
||||
final DeviceManager manager = GBApplication.app().getDeviceManager();
|
||||
final GBDevice gbDevice = manager.getDeviceByAddress(address);
|
||||
if (gbDevice == null) {
|
||||
LOG.info("Connected device {} unknown", device.getAddress());
|
||||
LOG.debug("observed non-GB device {}", address);
|
||||
return;
|
||||
}
|
||||
final SharedPreferences deviceSpecificPreferences = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress());
|
||||
if (deviceSpecificPreferences == null) {
|
||||
LOG.warn("no preferences found for connecting device {}", device.getAddress());
|
||||
return;
|
||||
|
||||
final GBDevice.State state = gbDevice.getState();
|
||||
if (state == WAITING_FOR_RECONNECT || state == WAITING_FOR_SCAN) {
|
||||
LOG.debug("re-connecting to observed device due to state {}", state);
|
||||
} else {
|
||||
final SharedPreferences pref = GBApplication.getDeviceSpecificSharedPrefs(address);
|
||||
if (pref == null) {
|
||||
LOG.warn("no preferences found for connecting device {}", address);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pref.getBoolean(GBPrefs.DEVICE_CONNECT_BACK, false)) {
|
||||
LOG.debug("re-connecting to observed device due DEVICE_CONNECT_BACK preference");
|
||||
} else {
|
||||
LOG.info("ignoring observed device {} {}", address, state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
boolean reactToConnection = deviceSpecificPreferences.getBoolean(GBPrefs.DEVICE_CONNECT_BACK, false);
|
||||
reactToConnection |= gbDevice.getState() == GBDevice.State.WAITING_FOR_RECONNECT;
|
||||
reactToConnection |= gbDevice.getState() == GBDevice.State.WAITING_FOR_SCAN;
|
||||
if (!reactToConnection) {
|
||||
LOG.info("Ignoring connection attempt from {}", device.getAddress());
|
||||
return;
|
||||
}
|
||||
LOG.info("Will re-connect to {} ({})", gbDevice.getAddress(), gbDevice.getName());
|
||||
|
||||
GBApplication.deviceService(gbDevice).connect();
|
||||
}
|
||||
}
|
||||
|
||||
+32
-26
@@ -18,8 +18,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service;
|
||||
|
||||
import android.companion.AssociationInfo;
|
||||
import android.companion.CompanionDeviceManager;
|
||||
import android.companion.CompanionDeviceService;
|
||||
import android.companion.DevicePresenceEvent;
|
||||
import android.net.MacAddress;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.DeprecatedSinceApi;
|
||||
@@ -30,14 +32,12 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.receivers.AutoConnectIntervalReceiver;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.BondingUtil;
|
||||
|
||||
|
||||
/**
|
||||
* For now this service only ensures that GB is less likely to get killed.
|
||||
* See {@link #maybeConnect}. Android API documentation:
|
||||
* Potentially {@link BluetoothConnectReceiver#observedDevice(String) reconnects} observed
|
||||
* companion devices. Android API documentation:
|
||||
* <blockquote>
|
||||
* The system binding CompanionDeviceService elevates the priority of the process that the service
|
||||
* is running in, and thus may prevent the Low-memory killer from killing the process at expense of
|
||||
@@ -52,8 +52,8 @@ public class GBCompanionDeviceService extends CompanionDeviceService {
|
||||
@Override
|
||||
public void onDeviceAppeared(@NonNull String address) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
LOG.debug("onDeviceAppeared address:{}", address);
|
||||
maybeConnect();
|
||||
LOG.debug("observed device {} via onDeviceAppeared(old {})", address, Build.VERSION.SDK_INT);
|
||||
BluetoothConnectReceiver.observedDevice(address);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +68,12 @@ public class GBCompanionDeviceService extends CompanionDeviceService {
|
||||
@Override
|
||||
public void onDeviceAppeared(@NonNull AssociationInfo associationInfo) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.BAKLAVA) {
|
||||
LOG.debug("onDeviceAppeared association:{}", associationInfo.getDeviceMacAddress());
|
||||
maybeConnect();
|
||||
MacAddress mac = associationInfo.getDeviceMacAddress();
|
||||
if (mac != null) {
|
||||
String address = mac.toString();
|
||||
LOG.debug("observed device {} via onDeviceAppeared(new {})", address, Build.VERSION.SDK_INT);
|
||||
BluetoothConnectReceiver.observedDevice(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,29 +99,31 @@ public class GBCompanionDeviceService extends CompanionDeviceService {
|
||||
"EVENT_SELF_MANAGED_DISAPPEARED";
|
||||
default -> Integer.toString(code);
|
||||
};
|
||||
LOG.debug("onDevicePresenceEvent {} association:{}", type, event.getAssociationId());
|
||||
|
||||
switch (code) {
|
||||
case DevicePresenceEvent.EVENT_BLE_APPEARED:
|
||||
case DevicePresenceEvent.EVENT_BT_CONNECTED:
|
||||
case DevicePresenceEvent.EVENT_SELF_MANAGED_APPEARED:
|
||||
maybeConnect();
|
||||
CompanionDeviceManager manager = BondingUtil.getCompanionDeviceManager(getBaseContext());
|
||||
if (manager == null) {
|
||||
LOG.error("CompanionDeviceManager is null");
|
||||
return;
|
||||
}
|
||||
for (final AssociationInfo info : manager.getMyAssociations()) {
|
||||
if (info.getId() == event.getAssociationId()) {
|
||||
MacAddress mac = info.getDeviceMacAddress();
|
||||
if (mac != null) {
|
||||
String address = mac.toString();
|
||||
LOG.debug("observed device {} via {}", address, type);
|
||||
BluetoothConnectReceiver.observedDevice(address);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG.warn("no matching AssociationInfo for {}", event);
|
||||
break;
|
||||
default:
|
||||
LOG.debug("onDevicePresenceEvent {} association:{}", type, event.getAssociationId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME {@link DeviceCommunicationService#connectToDevice} has to play nicer with
|
||||
* concurrent reconnect triggers before code can be added here
|
||||
* <ol>
|
||||
* <li>{@link AutoConnectIntervalReceiver}</li>
|
||||
* <li>{@link BluetoothConnectReceiver}</li>
|
||||
* <li>{@link DeviceService#ACTION_CONNECT}</li>
|
||||
* <li>device specific - e.g. {@link BtLEQueue#maybeReconnect}'s {@code mBluetoothGatt.connect}</li>
|
||||
* </ol>
|
||||
*/
|
||||
private void maybeConnect() {
|
||||
// TODO check DEVICE_CONNECT_BACK, WAITING_FOR_RECONNECT and WAITING_FOR_SCAN
|
||||
// and conditionally try to establish a connection
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user