mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-25 11:26:47 +01:00
Pebble: try to install app metadata on FW 3.x (untested)
This commit is contained in:
parent
2e3de0cd0f
commit
e28d6fa7cb
@ -70,7 +70,7 @@ public class PBWInstallHandler implements InstallHandler {
|
||||
}
|
||||
|
||||
GBDeviceApp app = mPBWReader.getGBDeviceApp();
|
||||
File pbwFile = new File(mPBWReader.getUri().getPath());
|
||||
File pbwFile = new File(mUri.getPath());
|
||||
try {
|
||||
File destDir = new File(FileUtils.getExternalFilesDir() + "/pbw-cache");
|
||||
destDir.mkdirs();
|
||||
|
@ -14,6 +14,8 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -50,6 +52,10 @@ public class PBWReader {
|
||||
private boolean isFirmware = false;
|
||||
private boolean isValid = false;
|
||||
private String hwRevision = null;
|
||||
private short mSdkVersion;
|
||||
private short mAppVersion;
|
||||
private int mIconId;
|
||||
private int mFlags;
|
||||
|
||||
public PBWReader(Uri uri, Context context, String platform) {
|
||||
String platformDir = "";
|
||||
@ -70,7 +76,7 @@ public class PBWReader {
|
||||
}
|
||||
ZipInputStream zis = new ZipInputStream(fin);
|
||||
ZipEntry ze;
|
||||
pebbleInstallables = new ArrayList<PebbleInstallable>();
|
||||
pebbleInstallables = new ArrayList<>();
|
||||
byte[] buffer = new byte[1024];
|
||||
int count;
|
||||
try {
|
||||
@ -149,6 +155,26 @@ public class PBWReader {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
} else if (fileName.equals(platformDir + "pebble-app.bin")) {
|
||||
zis.read(buffer, 0, 108);
|
||||
byte[] tmp_buf = new byte[32];
|
||||
ByteBuffer buf = ByteBuffer.wrap(buffer);
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buf.getLong(); // header, TODO: verifiy
|
||||
buf.getShort(); // struct version, TODO: verify
|
||||
mSdkVersion = buf.getShort();
|
||||
mAppVersion = buf.getShort();
|
||||
buf.getShort(); // size
|
||||
buf.getInt(); // offset
|
||||
buf.getInt(); // crc
|
||||
buf.get(tmp_buf, 0, 32); // app name
|
||||
buf.get(tmp_buf, 0, 32); // author
|
||||
mIconId = buf.getInt();
|
||||
LOG.info("got icon id from pebble-app.bin: " + mIconId);
|
||||
buf.getInt(); // symbol table addr
|
||||
mFlags = buf.getInt();
|
||||
LOG.info("got flags from pebble-app.bin: " + mFlags);
|
||||
// more follows but, not interesting for us
|
||||
}
|
||||
}
|
||||
zis.close();
|
||||
@ -206,7 +232,19 @@ public class PBWReader {
|
||||
return hwRevision;
|
||||
}
|
||||
|
||||
public Uri getUri() {
|
||||
return uri;
|
||||
public short getSdkVersion() {
|
||||
return mSdkVersion;
|
||||
}
|
||||
|
||||
public short getAppVersion() {
|
||||
return mAppVersion;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return mIconId;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppManagem
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PBWReader;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleInstallable;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.bt.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.bt.GBDeviceProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
@ -42,8 +43,7 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
private boolean mIsConnected = false;
|
||||
private boolean mIsInstalling = false;
|
||||
private int mConnectionAttempts = 0;
|
||||
/* app installation */
|
||||
private Uri mInstallURI = null;
|
||||
private boolean mForceUntested = false;
|
||||
private PBWReader mPBWReader = null;
|
||||
private int mAppInstallToken = -1;
|
||||
private ZipInputStream mZis = null;
|
||||
@ -84,7 +84,7 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
|
||||
mPebbleProtocol.setForceProtocol(sharedPrefs.getBoolean("pebble_force_protocol", false));
|
||||
|
||||
mForceUntested = sharedPrefs.getBoolean("pebble_force_untested", false);
|
||||
gbDevice.setState(GBDevice.State.CONNECTED);
|
||||
gbDevice.sendDeviceUpdateIntent(getContext());
|
||||
|
||||
@ -375,9 +375,8 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
return;
|
||||
}
|
||||
mIsInstalling = true;
|
||||
mInstallURI = uri;
|
||||
|
||||
mPBWReader = new PBWReader(mInstallURI, getContext(), gbDevice.getHardwareVersion().equals("dvt") ? "basalt" : "aplite");
|
||||
mPBWReader = new PBWReader(uri, getContext(), gbDevice.getHardwareVersion().equals("dvt") ? "basalt" : "aplite");
|
||||
mPebbleInstallables = mPBWReader.getPebbleInstallables();
|
||||
mCurrentInstallableIndex = 0;
|
||||
|
||||
@ -399,8 +398,12 @@ public class PebbleIoThread extends GBDeviceIoThread {
|
||||
mInstallSlot = 0;
|
||||
mInstallState = PebbleAppInstallState.START_INSTALL;
|
||||
} else {
|
||||
writeInstallApp(mPebbleProtocol.encodeAppDelete(mPBWReader.getGBDeviceApp().getUUID()));
|
||||
GBDeviceApp app = mPBWReader.getGBDeviceApp();
|
||||
writeInstallApp(mPebbleProtocol.encodeAppDelete(app.getUUID()));
|
||||
mInstallState = PebbleAppInstallState.WAIT_SLOT;
|
||||
if (mPebbleProtocol.isFw3x && mForceUntested) {
|
||||
writeInstallApp(mPebbleProtocol.encodeInstallMetadata(app.getUUID(), app.getName(), mPBWReader.getAppVersion(), mPBWReader.getSdkVersion()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,15 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
|
||||
static final byte APPRUNSTATE_START = 1;
|
||||
|
||||
static final byte BLOBDB_INSERT = 1;
|
||||
static final byte BLOBDB_DELETE = 4;
|
||||
static final byte BLOBDB_CLEAR = 5;
|
||||
|
||||
static final byte BLOBDB_PIN = 1;
|
||||
static final byte BLOBDB_APP = 2;
|
||||
static final byte BLOBDB_REMINDER = 3;
|
||||
static final byte BLOBDB_NOTIFICATION = 4;
|
||||
|
||||
static final byte NOTIFICATION_EMAIL = 0;
|
||||
static final byte NOTIFICATION_SMS = 1;
|
||||
static final byte NOTIFICATION_TWITTER = 2;
|
||||
@ -179,6 +188,8 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
static final short LENGTH_UPLOADCOMPLETE = 5;
|
||||
static final short LENGTH_UPLOADCANCEL = 5;
|
||||
|
||||
static final byte LENGTH_UUID = 16;
|
||||
|
||||
private static final String[] hwRevisions = {"unknown", "ev1", "ev2", "ev2_3", "ev2_4", "v1_5", "v2_0", "evt2", "dvt"};
|
||||
private static Random mRandom = new Random();
|
||||
|
||||
@ -406,11 +417,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
// blobdb - 23 bytes
|
||||
buf.put((byte) 0x01); // insert
|
||||
buf.put(BLOBDB_INSERT);
|
||||
buf.putShort((short) mRandom.nextInt()); // token
|
||||
buf.put((byte) 0x04); // db id (0x04 = notification)
|
||||
buf.put((byte) 16); // uuid length
|
||||
byte[] uuid_buf = new byte[16];
|
||||
buf.put(BLOBDB_NOTIFICATION);
|
||||
buf.put(LENGTH_UUID); // uuid length
|
||||
byte[] uuid_buf = new byte[LENGTH_UUID];
|
||||
mRandom.nextBytes(uuid_buf);
|
||||
buf.put(uuid_buf); // random UUID
|
||||
buf.putShort(pin_length); // length of the encapsulated data
|
||||
@ -458,6 +469,47 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
public byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion) {
|
||||
// Calculate length first
|
||||
final short BLOBDB_LENGTH = 23;
|
||||
final short METADATA_LENGTH = 126;
|
||||
|
||||
final short length = (short) (BLOBDB_LENGTH + METADATA_LENGTH);
|
||||
|
||||
byte[] name_buf = new byte[96];
|
||||
System.arraycopy(appName.getBytes(), 0, name_buf, 0, appName.length());
|
||||
ByteBuffer buf = ByteBuffer.allocate(length + LENGTH_PREFIX);
|
||||
|
||||
// Encode Prefix
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort(length);
|
||||
buf.putShort(ENDPOINT_BLOBDB);
|
||||
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
// blobdb - 23 bytes
|
||||
buf.put(BLOBDB_INSERT); // insert
|
||||
buf.putShort((short) mRandom.nextInt()); // token
|
||||
buf.put(BLOBDB_APP);
|
||||
buf.put(LENGTH_UUID);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putLong(uuid.getMostSignificantBits()); // watchapp uuid
|
||||
buf.putLong(uuid.getLeastSignificantBits());
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buf.putShort(METADATA_LENGTH); // length of the encapsulated data
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putLong(uuid.getMostSignificantBits()); // watchapp uuid
|
||||
buf.putLong(uuid.getLeastSignificantBits());
|
||||
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buf.putInt(1); // icon_id
|
||||
buf.putShort(appVersion);
|
||||
buf.putShort(sdkVersion);
|
||||
buf.put((byte) 0); // app_face_bgcolor
|
||||
buf.put((byte) 0); // app_face_template_id
|
||||
buf.put(name_buf); // 96 bytes
|
||||
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
public byte[] encodeGetTime() {
|
||||
return encodeSimpleMessage(ENDPOINT_TIME, TIME_GETTIME);
|
||||
}
|
||||
@ -762,7 +814,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
|
||||
}
|
||||
|
||||
byte[] encodeApplicationMessagePush(short endpoint, UUID uuid, ArrayList<Pair<Integer, Object>> pairs) {
|
||||
int length = 16 + 3; // UUID + (PUSH + id + length of dict)
|
||||
int length = LENGTH_UUID + 3; // UUID + (PUSH + id + length of dict)
|
||||
for (Pair<Integer, Object> pair : pairs) {
|
||||
length += 7; // key + type + length
|
||||
if (pair.second instanceof Integer) {
|
||||
|
Loading…
Reference in New Issue
Block a user