1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2025-02-09 16:36:48 +01:00

Oppo Headphones: Retry battery requests if unknown status

This commit is contained in:
José Rebelo 2025-02-02 16:25:41 +00:00
parent 8a747f0774
commit c08285a356
2 changed files with 49 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import static nodomain.freeyourgadget.gadgetbridge.util.GB.hexdump;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.Context; import android.content.Context;
import android.os.Handler;
import android.os.ParcelUuid; import android.os.ParcelUuid;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -33,6 +34,7 @@ import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread; import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
@ -41,6 +43,34 @@ public class OppoHeadphonesIoThread extends BtClassicIoThread {
private final OppoHeadphonesProtocol mProtocol; private final OppoHeadphonesProtocol mProtocol;
private final Handler handler = new Handler();
// Some devices will not reply to the first battery request, so we need to retry a few times
private int batteryRetries = 0;
private final Runnable batteryReqRunnable = new Runnable() {
public void run() {
final int batteryCount = getDevice().getDeviceCoordinator().getBatteryCount(getDevice());
boolean knownBattery = false;
for (int i = 0; i < batteryCount; i++) {
if (getDevice().getBatteryState(i) != BatteryState.UNKNOWN) {
knownBattery = true;
break;
}
}
if (!knownBattery) {
if (batteryRetries++ < 2) {
LOG.warn("Battery request retry {}", batteryRetries);
write(mProtocol.encodeBatteryReq());
scheduleBatteryRequestRetry();
} else {
LOG.error("Failed to get battery after {} tries", batteryRetries);
// Since this is not fatal, we stay connected
}
}
}
};
public OppoHeadphonesIoThread(final GBDevice gbDevice, public OppoHeadphonesIoThread(final GBDevice gbDevice,
final Context context, final Context context,
final OppoHeadphonesProtocol deviceProtocol, final OppoHeadphonesProtocol deviceProtocol,
@ -61,9 +91,16 @@ public class OppoHeadphonesIoThread extends BtClassicIoThread {
write(mProtocol.encodeFirmwareVersionReq()); write(mProtocol.encodeFirmwareVersionReq());
write(mProtocol.encodeConfigurationReq()); write(mProtocol.encodeConfigurationReq());
write(mProtocol.encodeBatteryReq()); write(mProtocol.encodeBatteryReq());
scheduleBatteryRequestRetry();
setUpdateState(GBDevice.State.INITIALIZED); setUpdateState(GBDevice.State.INITIALIZED);
} }
@Override
public void quit() {
handler.removeCallbacksAndMessages(null);
super.quit();
}
@Override @Override
protected byte[] parseIncoming(final InputStream inStream) throws IOException { protected byte[] parseIncoming(final InputStream inStream) throws IOException {
final byte[] buffer = new byte[1048576]; //HUGE read final byte[] buffer = new byte[1048576]; //HUGE read
@ -72,4 +109,10 @@ public class OppoHeadphonesIoThread extends BtClassicIoThread {
LOG.debug("Read {} bytes: {}", bytes, hexdump(buffer, 0, bytes)); LOG.debug("Read {} bytes: {}", bytes, hexdump(buffer, 0, bytes));
return Arrays.copyOf(buffer, bytes); return Arrays.copyOf(buffer, bytes);
} }
private void scheduleBatteryRequestRetry() {
LOG.info("Scheduling battery request retry");
handler.postDelayed(batteryReqRunnable, 2000);
}
} }

View File

@ -88,6 +88,12 @@ public class SonyHeadphonesIoThread extends BtClassicIoThread {
setUpdateState(GBDevice.State.INITIALIZING); setUpdateState(GBDevice.State.INITIALIZING);
} }
@Override
public void quit() {
handler.removeCallbacksAndMessages(null);
super.quit();
}
@Override @Override
public synchronized void write(final byte[] bytes) { public synchronized void write(final byte[] bytes) {
// Log the human-readable message, for debugging // Log the human-readable message, for debugging