mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Pebble: Fix pebble time 2 and core 2 duo not immediately showing up in device list
This commit is contained in:
+15
@@ -29,6 +29,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
|
||||
|
||||
/**
|
||||
* Unified source of truth for Pebble hardware definitions.
|
||||
@@ -469,6 +470,20 @@ public class PebbleHardware {
|
||||
return name != null && (name.startsWith("Pebble-LE ") || name.startsWith("Pebble Time LE "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a device candidate needs connect-first pairing (GATT connection before createBond).
|
||||
* Uses manufacturer data for reliable identification, falling back to name-based detection.
|
||||
*/
|
||||
public static boolean needsConnectFirstPairing(GBDeviceCandidate candidate) {
|
||||
if (candidate == null) {
|
||||
return false;
|
||||
}
|
||||
if (isBleOnly(candidate.getManufacturerSpecificData())) {
|
||||
return true;
|
||||
}
|
||||
return isBleOnly(candidate.getDevice());
|
||||
}
|
||||
|
||||
// ======================= Platform Utilities =======================
|
||||
|
||||
/**
|
||||
|
||||
+14
-7
@@ -130,8 +130,8 @@ public class PebblePairingActivity extends AbstractGBActivity implements Bonding
|
||||
// Note: These devices are BLE-only, so we don't need the "pebble_force_le" setting -
|
||||
// PebbleIoThread automatically uses BLE based on isPebble2() detection.
|
||||
// Use deviceCandidate to leverage manufacturer data for reliable device identification.
|
||||
if (BondingUtil.needsConnectFirstPairing(deviceCandidate)) {
|
||||
LOG.info("Pebble 2/Time 2/2 Duo detected via manufacturer data - using connect-first pairing (BLE-only device)");
|
||||
if (PebbleHardware.needsConnectFirstPairing(deviceCandidate)) {
|
||||
LOG.info("BLE-only device detected - using connect-first pairing");
|
||||
|
||||
registerBroadcastReceivers();
|
||||
|
||||
@@ -198,7 +198,8 @@ public class PebblePairingActivity extends AbstractGBActivity implements Bonding
|
||||
LOG.debug("ONBONDINGCOMPLETE");
|
||||
unregisterBroadcastReceivers();
|
||||
|
||||
// Trigger device list refresh so the new device appears immediately
|
||||
BluetoothDevice btDevice = deviceCandidate != null ? deviceCandidate.getDevice() : null;
|
||||
|
||||
if (success) {
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(
|
||||
new Intent(DeviceManager.ACTION_REFRESH_DEVICELIST));
|
||||
@@ -210,9 +211,8 @@ public class PebblePairingActivity extends AbstractGBActivity implements Bonding
|
||||
startActivity(new Intent(this, DiscoveryActivityV2.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
|
||||
}
|
||||
|
||||
// If it's not a LE Pebble, initiate a connection when bonding is complete
|
||||
if (!PebbleHardware.isLePebbleCompanion(getCurrentTarget().getDevice()) && success) {
|
||||
BondingUtil.attemptToFirstConnect(getCurrentTarget().getDevice());
|
||||
if (btDevice != null && success && getAttemptToConnect() && shouldReconnectAfterBond()) {
|
||||
BondingUtil.attemptToFirstConnect(btDevice);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
@@ -224,7 +224,14 @@ public class PebblePairingActivity extends AbstractGBActivity implements Bonding
|
||||
|
||||
@Override
|
||||
public boolean getAttemptToConnect() {
|
||||
return true;
|
||||
// LE companion manages its own connection via connectThenComplete
|
||||
return deviceCandidate == null || !PebbleHardware.isLePebbleCompanion(deviceCandidate.getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldReconnectAfterBond() {
|
||||
// Connect-first pairing: bonding occurred within the existing GATT connection
|
||||
return !PebbleHardware.needsConnectFirstPairing(deviceCandidate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -54,6 +54,15 @@ public interface BondingInterface {
|
||||
}
|
||||
|
||||
boolean getAttemptToConnect();
|
||||
|
||||
/**
|
||||
* Whether the connection should be restarted after bonding completes.
|
||||
* Return false for connect-first pairing flows where bonding occurs within an existing
|
||||
* GATT connection — the connection should not be interrupted.
|
||||
*/
|
||||
default boolean shouldReconnectAfterBond() {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* This forces bonding activities to handle the addition
|
||||
* of all broadcast receivers in the same place
|
||||
|
||||
@@ -134,14 +134,18 @@ public class BondingUtil {
|
||||
} else {
|
||||
switch (bondState) {
|
||||
case BluetoothDevice.BOND_BONDED: {
|
||||
|
||||
LOG.info("Bonded with {}", device.getAddress());
|
||||
if (PebbleHardware.isLePebbleCompanion(device) || PebbleHardware.isBleOnly(device) || !bondingInterface.getAttemptToConnect()) {
|
||||
// Do not initiate connection to LE Pebble and Pebble 2/Time 2/2 Duo
|
||||
// For Pebble 2/Time 2/2 Duo, the connection was already started before bonding
|
||||
// Just signal that bonding is complete
|
||||
LOG.info("LE/Pebble2/Pebble2Duo device bonded - signaling completion");
|
||||
if (!bondingInterface.getAttemptToConnect()) {
|
||||
LOG.info("Device bonded - notifying onBondingComplete without reconnecting.");
|
||||
bondingInterface.onBondingComplete(true);
|
||||
} else if (!bondingInterface.shouldReconnectAfterBond()) {
|
||||
// connect-first pairing, existing connection completes to INITIALIZED
|
||||
// Don't interrupt by disconnecting and reconnecting in the middle of the pairing flow.
|
||||
LOG.info("Device bonded - connect first pairing, connection already established.");
|
||||
} else {
|
||||
// Bond-then-connect flow: reconnect now that bonding is complete.
|
||||
LOG.info("Device bonded - reconnecting and waiting for initialization");
|
||||
attemptToFirstConnect(device);
|
||||
}
|
||||
return;
|
||||
@@ -334,34 +338,6 @@ public class BondingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if device needs connect-first pairing (GATT connection before createBond).
|
||||
* Pebble 2, Pebble Time 2, and Pebble 2 Duo require writing to a pairing trigger
|
||||
* characteristic before Android's createBond() will succeed.
|
||||
*
|
||||
* @param candidate Device candidate with manufacturer data from BLE scan
|
||||
* @return true if this device needs connect-first pairing
|
||||
*/
|
||||
public static boolean needsConnectFirstPairing(GBDeviceCandidate candidate) {
|
||||
if (candidate == null) {
|
||||
return false;
|
||||
}
|
||||
// First try manufacturer data - this is the most reliable method
|
||||
if (PebbleHardware.isBleOnly(candidate.getManufacturerSpecificData())) {
|
||||
return true;
|
||||
}
|
||||
// Fall back to name-based detection
|
||||
return PebbleHardware.isBleOnly(candidate.getDevice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if device needs connect-first pairing (GATT connection before createBond).
|
||||
* Uses name-based detection when GBDeviceCandidate is not available.
|
||||
*/
|
||||
public static boolean needsConnectFirstPairing(BluetoothDevice device) {
|
||||
return PebbleHardware.isBleOnly(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the CompanionDeviceManager bonding method
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user