Pebble: Fix not being able to install firmware since firmware util was comparing the wrong model string

This commit is contained in:
Benjamin Temple
2026-05-17 08:06:04 -07:00
parent 3fe42f3d8f
commit f920968deb
3 changed files with 119 additions and 3 deletions
@@ -89,7 +89,12 @@ public class PBWInstallHandler implements InstallHandler {
}
if (!mPBWReader.isValid()) {
installActivity.setInfoText("pbw/pbz is broken or incompatible with your Hardware or Firmware.");
String reason = mPBWReader.getInvalidReason();
if (reason != null) {
installActivity.setInfoText("Invalid: " + reason);
} else {
installActivity.setInfoText("pbw/pbz is broken or incompatible with your Hardware or Firmware.");
}
installActivity.setInstallEnabled(false);
return;
}
@@ -101,7 +106,10 @@ public class PBWInstallHandler implements InstallHandler {
installItem.setIcon(R.drawable.ic_firmware);
String hwRevision = mPBWReader.getHWRevision();
if (hwRevision != null && hwRevision.equals(device.getModel())) {
String deviceModel = device.getModel();
// Use platform-aware compatibility check instead of exact string match
if (PebbleHardware.isFirmwareCompatible(hwRevision, deviceModel)) {
installItem.setName(mContext.getString(R.string.pbw_installhandler_pebble_firmware, ""));
installItem.setDetails(mContext.getString(R.string.pbwinstallhandler_correct_hw_revision));
@@ -112,7 +120,13 @@ public class PBWInstallHandler implements InstallHandler {
installItem.setName(mContext.getString(R.string.pbw_installhandler_pebble_firmware, hwRevision));
installItem.setDetails(mContext.getString(R.string.pbwinstallhandler_incorrect_hw_revision));
}
installActivity.setInfoText(mContext.getString(R.string.pbw_install_handler_hw_revision_mismatch));
// Show detailed incompatibility reason
String reason = PebbleHardware.getFirmwareIncompatibilityReason(hwRevision, deviceModel);
if (reason != null) {
installActivity.setInfoText(reason);
} else {
installActivity.setInfoText(mContext.getString(R.string.pbw_install_handler_hw_revision_mismatch));
}
installActivity.setInstallEnabled(false);
}
} else {
@@ -66,6 +66,7 @@ public class PBWReader {
private boolean isFirmware = false;
private boolean isLanguage = false;
private boolean isValid = false;
private String invalidReason = null;
private String hwRevision = null;
private short mSdkVersion;
private short mAppVersion;
@@ -102,8 +103,13 @@ public class PBWReader {
platformDir = determinePlatformDir(uriHelper, platform);
if (platform.equals("chalk") && platformDir.equals("")) {
invalidReason = "No chalk/ directory found - app doesn't support Pebble Time Round";
return;
}
if (platformDir.equals("")) {
LOG.info("No platform-specific directory found for {}, will try root", platform);
}
}
LOG.info("using platformdir: '" + platformDir + "'");
@@ -160,6 +166,7 @@ public class PBWReader {
} catch (JSONException e) {
// no JSON at all that is a problem
isValid = false;
invalidReason = "Failed to parse manifest.json: " + e.getMessage();
LOG.warn("exception 1 in constructor", e);
break;
}
@@ -190,6 +197,7 @@ public class PBWReader {
}
} catch (JSONException e) {
isValid = false;
invalidReason = "Failed to parse appinfo.json: " + e.getMessage();
LOG.warn("exception 2 in constructor", e);
break;
}
@@ -227,6 +235,28 @@ public class PBWReader {
}
else if (!isFirmware) {
isValid = false;
StringBuilder missing = new StringBuilder();
if (appUUID == null) missing.append("uuid, ");
if (appName == null) missing.append("shortName, ");
if (appCreator == null) missing.append("companyName, ");
if (appVersion == null) missing.append("versionLabel, ");
if (missing.length() > 0) {
missing.setLength(missing.length() - 2); // Remove trailing ", "
invalidReason = "Missing required fields in appinfo.json: " + missing;
} else if (pebbleInstallables.isEmpty()) {
invalidReason = "No installable files found in manifest.json for platform";
} else {
invalidReason = "Unknown app parsing error";
}
}
}
// Set default invalid reason if still not valid and no specific reason
if (!isValid && invalidReason == null) {
if (pebbleInstallables == null || pebbleInstallables.isEmpty()) {
invalidReason = "No manifest.json found or no installable files for platform: " + platform;
} else {
invalidReason = "Unknown validation error";
}
}
}
@@ -281,6 +311,14 @@ public class PBWReader {
return isValid;
}
/**
* Get the reason why this pbw/pbz is invalid.
* @return Human-readable reason string, or null if valid
*/
public String getInvalidReason() {
return invalidReason;
}
public GBDeviceApp getGBDeviceApp() {
return app;
}
@@ -555,6 +555,70 @@ public class PebbleHardware {
return hw.getPlatform().hasHealth();
}
/**
* Check if a firmware's hwRevision is compatible with a device's model.
* Firmware uses platform names (emery), device uses codenames (obelix_pvt).
*
* @param firmwareHwRev The hwrev from firmware manifest (e.g., "emery")
* @param deviceModel The model from GBDevice (e.g., "obelix_pvt")
* @return true if compatible, false otherwise
*/
public static boolean isFirmwareCompatible(@Nullable String firmwareHwRev, @Nullable String deviceModel) {
if (firmwareHwRev == null || deviceModel == null) {
return false;
}
// Get platforms for both
HardwareRevision fwHw = getByModelString(firmwareHwRev);
HardwareRevision deviceHw = getByModelString(deviceModel);
if (fwHw == null || deviceHw == null) {
LOG.warn("isFirmwareCompatible: Could not resolve platform - fw={} ({}), device={} ({})",
firmwareHwRev, fwHw, deviceModel, deviceHw);
return false;
}
boolean compatible = fwHw.getPlatform() == deviceHw.getPlatform();
LOG.info("isFirmwareCompatible: fw={} ({}), device={} ({}) -> {}",
firmwareHwRev, fwHw.getPlatformName(), deviceModel, deviceHw.getPlatformName(), compatible);
return compatible;
}
/**
* Get a detailed incompatibility reason for firmware/device mismatch.
*
* @param firmwareHwRev The hwrev from firmware manifest
* @param deviceModel The model from GBDevice
* @return Human-readable reason string, or null if compatible
*/
@Nullable
public static String getFirmwareIncompatibilityReason(@Nullable String firmwareHwRev, @Nullable String deviceModel) {
if (firmwareHwRev == null) {
return "Firmware has no hardware revision specified";
}
if (deviceModel == null) {
return "Device model is unknown";
}
HardwareRevision fwHw = getByModelString(firmwareHwRev);
HardwareRevision deviceHw = getByModelString(deviceModel);
if (fwHw == null) {
return "Unknown firmware platform: " + firmwareHwRev;
}
if (deviceHw == null) {
return "Unknown device model: " + deviceModel;
}
if (fwHw.getPlatform() != deviceHw.getPlatform()) {
return String.format("Platform mismatch: firmware is for %s (%s), device is %s (%s)",
fwHw.getPlatform().getDisplayName(), firmwareHwRev,
deviceHw.getPlatform().getDisplayName(), deviceModel);
}
return null; // Compatible
}
/**
* Check if manufacturer data indicates any Pebble device.
*