diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java index 0ebabb11..1abd25a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -224,6 +224,11 @@ public class FwAppInstallerActivity extends GBActivity implements InstallActivit fwAppInstallTextView.setText(text); } + @Override + public CharSequence getInfoText() { + return fwAppInstallTextView.getText(); + } + @Override public void setInstallEnabled(boolean enable) { boolean enabled = device != null && device.isConnected() && enable; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java index b00c1dfd..4af5405e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/InstallActivity.java @@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.activities; import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails; public interface InstallActivity { + CharSequence getInfoText(); + void setInfoText(String text); void setInstallEnabled(boolean enable); @@ -26,4 +28,5 @@ public interface InstallActivity { void clearInstallItems(); void setInstallItem(ItemWithDetails item); + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java index ba009e33..d52b698b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/AbstractMiBandFWInstallHandler.java @@ -48,6 +48,14 @@ public abstract class AbstractMiBandFWInstallHandler implements InstallHandler { } } + public Context getContext() { + return mContext; + } + + public AbstractMiBandFWHelper getHelper() { + return helper; + } + protected abstract AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java index af1336aa..8ea09a15 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband2/MiBand2FWInstallHandler.java @@ -24,10 +24,14 @@ import org.slf4j.LoggerFactory; import java.io.IOException; +import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWHelper; import nodomain.freeyourgadget.gadgetbridge.devices.miband.AbstractMiBandFWInstallHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.FirmwareType; +import nodomain.freeyourgadget.gadgetbridge.util.Version; public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { private static final Logger LOG = LoggerFactory.getLogger(MiBand2FWInstallHandler.class); @@ -36,6 +40,55 @@ public class MiBand2FWInstallHandler extends AbstractMiBandFWInstallHandler { super(uri, context); } + @Override + public void validateInstallation(InstallActivity installActivity, GBDevice device) { + super.validateInstallation(installActivity, device); + maybeAddFw53Hint(installActivity, device); + } + + private void maybeAddFw53Hint(InstallActivity installActivity, GBDevice device) { + FirmwareType type = getFirmwareType(); + if (type != FirmwareType.FIRMWARE) { + return; + } + + Version deviceVersion = getFirmwareVersionOf(device); + if (deviceVersion != null) { + Version v53 = new Version("1.0.0.53"); + if (deviceVersion.compareTo(v53) < 0) { + String vInstall = getHelper().format(getHelper().getFirmwareVersion()); + if (vInstall == null || new Version(vInstall).compareTo(v53) > 0) { + String newInfoText = getContext().getString(R.string.mi2_fw_installhandler_fw53_hint, v53.get()) + "\n\n" + installActivity.getInfoText(); + installActivity.setInfoText(newInfoText); + } + } + } + } + + private Version getFirmwareVersionOf(GBDevice device) { + String version = device.getFirmwareVersion(); + if (version == null || version.length() == 0) { + return null; + } + if (version.charAt(0) == 'V') { + version = version.substring(1); + } + try { + return new Version(version); + } catch (Exception ex) { + LOG.error("Unable to parse version: " + version); + return null; + } + } + + private FirmwareType getFirmwareType() { + AbstractMiBandFWHelper helper = getHelper(); + if (helper instanceof MiBand2FWHelper) { + return ((MiBand2FWHelper) helper).getFirmwareInfo().getFirmwareType(); + } + return FirmwareType.INVALID; + } + @Override protected AbstractMiBandFWHelper createHelper(Uri uri, Context context) throws IOException { return new MiBand2FWHelper(uri, context); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java index b0a8030e..e7679301 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/CheckSums.java @@ -16,6 +16,13 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.util; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + public class CheckSums { public static int getCRC8(byte[] seq) { int len = seq.length; @@ -51,4 +58,31 @@ public class CheckSums { crc &= 0xffff; return crc; } + + public static void main(String[] args) throws IOException { + if (args == null || args.length == 0) { + throw new IllegalArgumentException("Pass the files to be checksummed as arguments"); + } + for (String name : args) { + try (FileInputStream in = new FileInputStream(name)) { + byte[] bytes = readAll(in, 1000 * 1000); + System.out.println(name + " : " + getCRC16(bytes)); + } + } + } + + public static byte[] readAll(InputStream in, long maxLen) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(8192, in.available())); + byte[] buf = new byte[8192]; + int read = 0; + long totalRead = 0; + while ((read = in.read(buf)) > 0) { + out.write(buf, 0, read); + totalRead += read; + if (totalRead > maxLen) { + throw new IOException("Too much data to read into memory. Got already " + totalRead + buf); + } + } + return out.toByteArray(); + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java new file mode 100644 index 00000000..3d363745 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/Version.java @@ -0,0 +1,48 @@ +package nodomain.freeyourgadget.gadgetbridge.util; + +// http://stackoverflow.com/questions/198431/how-do-you-compare-two-version-strings-in-java +public class Version implements Comparable { + + private String version; + + public final String get() { + return this.version; + } + + public Version(String version) { + if(version == null) + throw new IllegalArgumentException("Version can not be null"); + if(!version.matches("[0-9]+(\\.[0-9]+)*")) + throw new IllegalArgumentException("Invalid version format"); + this.version = version; + } + + @Override public int compareTo(Version that) { + if(that == null) + return 1; + String[] thisParts = this.get().split("\\."); + String[] thatParts = that.get().split("\\."); + int length = Math.max(thisParts.length, thatParts.length); + for(int i = 0; i < length; i++) { + int thisPart = i < thisParts.length ? + Integer.parseInt(thisParts[i]) : 0; + int thatPart = i < thatParts.length ? + Integer.parseInt(thatParts[i]) : 0; + if(thisPart < thatPart) + return -1; + if(thisPart > thatPart) + return 1; + } + return 0; + } + + @Override public boolean equals(Object that) { + if(this == that) + return true; + if(that == null) + return false; + if(this.getClass() != that.getClass()) + return false; + return this.compareTo((Version) that) == 0; + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 61453fbe..4f6039a3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -406,4 +406,5 @@ (%1$s) You found it! Mi2: Time Format + You need to install version %1$s before installing this firmware!