Skip to content

Commit

Permalink
Device Management: centralized DeviceType resolution cache
Browse files Browse the repository at this point in the history
  • Loading branch information
dakhnod authored and José Rebelo committed Oct 29, 2023
1 parent 3d8ae85 commit eb0747b
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,17 @@ public void onItemClick(final AdapterView<?> parent, final View view, final int
return;
}

if (!deviceCandidate.getDeviceType().isSupported()) {
DeviceType deviceType = DeviceHelper.getInstance().resolveDeviceType(deviceCandidate);

if (!deviceType.isSupported()) {
LOG.warn("Unsupported device candidate {}", deviceCandidate);
copyDetailsToClipboard(deviceCandidate);
return;
}

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) {
Expand Down Expand Up @@ -661,12 +663,14 @@ public boolean onItemLongClick(final AdapterView<?> adapterView, final View view
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,9 @@ private boolean processCandidate(final GBDeviceCandidate candidate) {
}
}

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);
}
Expand Down Expand Up @@ -263,7 +262,7 @@ private boolean processAllScanEvents(final String address) {
"Device {} ({}) is supported as '{}' without scanning services",
candidate.getDevice(),
candidate.getName(),
candidate.getDeviceType()
DeviceHelper.getInstance().resolveDeviceType(candidate, false)
);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
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;

Expand Down Expand Up @@ -62,7 +63,9 @@ public View getView(int position, View view, ViewGroup parent) {
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);
Expand All @@ -77,7 +80,7 @@ public View getView(int position, View view, ViewGroup parent) {
}
}

if (!device.getDeviceType().isSupported()) {
if (!deviceType.isSupported()) {
statusLines.add(getContext().getString(R.string.device_unsupported));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
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
Expand All @@ -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;
Expand All @@ -67,7 +66,6 @@ private GBDeviceCandidate(Parcel in) {
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()));

Expand All @@ -82,7 +80,6 @@ private GBDeviceCandidate(Parcel in) {
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) {
Expand All @@ -108,14 +105,6 @@ public BluetoothDevice getDevice() {
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_);
}
Expand Down Expand Up @@ -238,7 +227,7 @@ public int hashCode() {

@Override
public String toString() {
return getName() + ": " + getMacAddress() + " (" + getDeviceType() + ")";
return getName() + ": " + getMacAddress();
}

@NonNull
Expand All @@ -249,7 +238,6 @@ public GBDeviceCandidate clone() {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
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;
Expand Down Expand Up @@ -63,6 +64,8 @@ public static DeviceHelper getInstance() {
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) {
Expand Down Expand Up @@ -130,14 +133,27 @@ private DeviceType[] getOrderedDeviceTypes(){

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;
}
Expand Down

0 comments on commit eb0747b

Please sign in to comment.