1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-29 05:16:51 +01:00

Device Management: centralized DeviceType resolution cache

This commit is contained in:
Daniel Dakhno 2023-10-28 10:49:16 +02:00 committed by José Rebelo
parent 3d8ae8596c
commit eb0747b926
5 changed files with 34 additions and 24 deletions

View File

@ -587,7 +587,9 @@ public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterVi
return;
}
if (!deviceCandidate.getDeviceType().isSupported()) {
DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(deviceCandidate);
if (!deviceType.isSupported()) {
LOG.warn("Unsupported device candidate {}", deviceCandidate);
copyDetailsToClipboard(deviceCandidate);
return;
@ -595,7 +597,7 @@ public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterVi
stopDiscovery();
final DeviceCoordinator coordinator = DeviceHelper.getInstance().resolveCoordinator(deviceCandidate);
final DeviceCoordinator coordinator = deviceType.getDeviceCoordinator();
LOG.info("Using device candidate {} with coordinator {}", deviceCandidate, coordinator.getClass());
if (coordinator.getBondingStyle() == DeviceCoordinator.BONDING_STYLE_REQUIRE_KEY) {
@ -661,12 +663,14 @@ public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterVi
return true;
}
if (!deviceCandidate.getDeviceType().isSupported()) {
DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(deviceCandidate);
if (!deviceType.isSupported()) {
showUnsupportedDeviceDialog(deviceCandidate);
return true;
}
final DeviceCoordinator coordinator = deviceCandidate.getDeviceType().getDeviceCoordinator();
final DeviceCoordinator coordinator = deviceType.getDeviceCoordinator();
final GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
if (coordinator.getSupportedDeviceSpecificSettings(device) == null) {
return true;

View File

@ -184,10 +184,9 @@ public final class GBScanEventProcessor implements Runnable {
}
}
final DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(candidate);
final DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(candidate, false);
if (deviceType.isSupported() || discoverUnsupported) {
candidate.setDeviceType(deviceType);
synchronized (candidatesByAddress) {
candidatesByAddress.put(candidate.getMacAddress(), candidate);
}
@ -263,7 +262,7 @@ public final class GBScanEventProcessor implements Runnable {
"Device {} ({}) is supported as '{}' without scanning services",
candidate.getDevice(),
candidate.getName(),
candidate.getDeviceType()
DeviceHelper.getInstance().resolveDeviceType(candidate, false)
);
return true;
}

View File

@ -34,6 +34,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
@ -62,7 +63,9 @@ public class DeviceCandidateAdapter extends ArrayAdapter<GBDeviceCandidate> {
TextView deviceAddressLabel = view.findViewById(R.id.item_details);
TextView deviceStatus = view.findViewById(R.id.item_status);
DeviceCoordinator coordinator = device.getDeviceType().getDeviceCoordinator();
DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(device);
DeviceCoordinator coordinator = deviceType.getDeviceCoordinator();
String name = formatDeviceCandidate(device);
deviceNameLabel.setText(name);
@ -77,7 +80,7 @@ public class DeviceCandidateAdapter extends ArrayAdapter<GBDeviceCandidate> {
}
}
if (!device.getDeviceType().isSupported()) {
if (!deviceType.isSupported()) {
statusLines.add(getContext().getString(R.string.device_unsupported));
}

View File

@ -37,6 +37,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
/**
* A device candidate is a Bluetooth device that is not yet managed by
@ -49,8 +50,6 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
private BluetoothDevice device;
private short rssi;
private ParcelUuid[] serviceUuids;
private DeviceType deviceType = DeviceType.UNKNOWN;
// Cached values for device name and bond status, to avoid querying the remote bt device
private String deviceName;
private Boolean isBonded = null;
@ -67,7 +66,6 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
throw new IllegalStateException("Unable to read state from Parcel");
}
rssi = (short) in.readInt();
deviceType = DeviceType.valueOf(in.readString());
serviceUuids = AndroidUtils.toParcelUuids(in.readParcelableArray(getClass().getClassLoader()));
@ -82,7 +80,6 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(device, 0);
dest.writeInt(rssi);
dest.writeString(deviceType.name());
dest.writeParcelableArray(serviceUuids, 0);
dest.writeString(deviceName);
if (isBonded == null) {
@ -108,14 +105,6 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
return device;
}
public void setDeviceType(DeviceType type) {
deviceType = type;
}
public DeviceType getDeviceType() {
return deviceType;
}
public String getMacAddress() {
return device != null ? device.getAddress() : GBApplication.getContext().getString(R.string._unknown_);
}
@ -238,7 +227,7 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
@Override
public String toString() {
return getName() + ": " + getMacAddress() + " (" + getDeviceType() + ")";
return getName() + ": " + getMacAddress();
}
@NonNull
@ -249,7 +238,6 @@ public class GBDeviceCandidate implements Parcelable, Cloneable {
clone.device = this.device;
clone.rssi = this.rssi;
clone.serviceUuids = this.serviceUuids;
clone.deviceType = this.deviceType;
clone.deviceName = this.deviceName;
clone.isBonded = this.isBonded;
return clone;

View File

@ -34,6 +34,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@ -63,6 +64,8 @@ public class DeviceHelper {
return instance;
}
private final HashMap<String, DeviceType> deviceTypeCache = new HashMap<>();
public GBDevice findAvailableDevice(String deviceAddress, Context context) {
Set<GBDevice> availableDevices = getAvailableDevices(context);
for (GBDevice availableDevice : availableDevices) {
@ -130,14 +133,27 @@ public class DeviceHelper {
return orderedDeviceTypes;
}
public DeviceType resolveDeviceType(GBDeviceCandidate deviceCandidate) {
return resolveDeviceType(deviceCandidate, true);
}
public DeviceType resolveDeviceType(GBDeviceCandidate deviceCandidate){
public DeviceType resolveDeviceType(GBDeviceCandidate deviceCandidate, boolean useCache){
synchronized (this) {
if(useCache) {
DeviceType cachedType =
deviceTypeCache.get(deviceCandidate.getMacAddress().toLowerCase());
if (cachedType != null) {
return cachedType;
}
}
for (DeviceType type : getOrderedDeviceTypes()) {
if (type.getDeviceCoordinator().supports(deviceCandidate)) {
deviceTypeCache.put(deviceCandidate.getMacAddress().toLowerCase(), type);
return type;
}
}
deviceTypeCache.put(deviceCandidate.getMacAddress().toLowerCase(), DeviceType.UNKNOWN);
}
return DeviceType.UNKNOWN;
}