mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-06-05 21:49:48 +02:00
Fossil Hybrid: added unauthenticated, limited mode
This commit is contained in:
@@ -109,7 +109,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
getDeviceInfos();
|
getDeviceInfos();
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getSupportedFileVersion(FileHandle handle){
|
public short getSupportedFileVersion(FileHandle handle) {
|
||||||
return this.supportedFileVersions.getSupportedFileVersion(handle);
|
return this.supportedFileVersions.getSupportedFileVersion(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,14 +123,14 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void getDeviceInfos(){
|
protected void getDeviceInfos() {
|
||||||
queueWrite(new GetDeviceInfoRequest(this){
|
queueWrite(new GetDeviceInfoRequest(this) {
|
||||||
@Override
|
@Override
|
||||||
public void handleDeviceInfos(DeviceInfo[] deviceInfos) {
|
public void handleDeviceInfos(DeviceInfo[] deviceInfos) {
|
||||||
for(DeviceInfo info : deviceInfos){
|
for (DeviceInfo info : deviceInfos) {
|
||||||
if(info instanceof SupportedFileVersionsInfo){
|
if (info instanceof SupportedFileVersionsInfo) {
|
||||||
FossilWatchAdapter.this.supportedFileVersions = (SupportedFileVersionsInfo) info;
|
FossilWatchAdapter.this.supportedFileVersions = (SupportedFileVersionsInfo) info;
|
||||||
}else if(info instanceof DeviceSecurityVersionInfo){
|
} else if (info instanceof DeviceSecurityVersionInfo) {
|
||||||
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem("DEVICE_SECURITY_VERSION", info.toString()));
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem("DEVICE_SECURITY_VERSION", info.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,7 +139,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncButtonSettings(){
|
private void syncButtonSettings() {
|
||||||
String buttonConfig = getDeviceSpecificPreferences().getString(CONFIG_ITEM_BUTTONS, null);
|
String buttonConfig = getDeviceSpecificPreferences().getString(CONFIG_ITEM_BUTTONS, null);
|
||||||
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, buttonConfig));
|
getDeviceSupport().getDevice().addDeviceInfo(new GenericItem(ITEM_BUTTONS, buttonConfig));
|
||||||
overwriteButtons(buttonConfig);
|
overwriteButtons(buttonConfig);
|
||||||
@@ -147,8 +147,8 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||||
if(status != BluetoothGatt.GATT_SUCCESS){
|
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||||
if(characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")){
|
if (characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")) {
|
||||||
GB.log("authentication failed", GB.ERROR, null);
|
GB.log("authentication failed", GB.ERROR, null);
|
||||||
setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED);
|
setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED);
|
||||||
requestQueue.clear();
|
requestQueue.clear();
|
||||||
@@ -163,20 +163,20 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||||
log("status " + status + " newState: " + newState);
|
log("status " + status + " newState: " + newState);
|
||||||
if(newState != BluetoothGatt.STATE_CONNECTED){
|
if (newState != BluetoothGatt.STATE_CONNECTED) {
|
||||||
log("status " + newState + " clearing queue...");
|
log("status " + newState + " clearing queue...");
|
||||||
requestQueue.clear();
|
requestQueue.clear();
|
||||||
fossilRequest = null;
|
fossilRequest = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SharedPreferences getDeviceSpecificPreferences(){
|
protected SharedPreferences getDeviceSpecificPreferences() {
|
||||||
return GBApplication.getDeviceSpecificSharedPrefs(
|
return GBApplication.getDeviceSpecificSharedPrefs(
|
||||||
getDeviceSupport().getDevice().getAddress()
|
getDeviceSupport().getDevice().getAddress()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncConfiguration(){
|
private void syncConfiguration() {
|
||||||
SharedPreferences preferences = getDeviceSpecificPreferences();
|
SharedPreferences preferences = getDeviceSpecificPreferences();
|
||||||
|
|
||||||
int stepGoal = preferences.getInt(CONFIG_ITEM_STEP_GOAL, 1000000);
|
int stepGoal = preferences.getInt(CONFIG_ITEM_STEP_GOAL, 1000000);
|
||||||
@@ -225,7 +225,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigurationPutRequest.TimeConfigItem generateTimeConfigItemNow(){
|
protected ConfigurationPutRequest.TimeConfigItem generateTimeConfigItemNow() {
|
||||||
long millis = System.currentTimeMillis();
|
long millis = System.currentTimeMillis();
|
||||||
TimeZone zone = new GregorianCalendar().getTimeZone();
|
TimeZone zone = new GregorianCalendar().getTimeZone();
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
@Override
|
@Override
|
||||||
public void overwriteButtons(String jsonConfigString) {
|
public void overwriteButtons(String jsonConfigString) {
|
||||||
try {
|
try {
|
||||||
if(jsonConfigString == null) return;
|
if (jsonConfigString == null) return;
|
||||||
getDeviceSpecificPreferences()
|
getDeviceSpecificPreferences()
|
||||||
.edit()
|
.edit()
|
||||||
.putString(CONFIG_ITEM_BUTTONS, jsonConfigString)
|
.putString(CONFIG_ITEM_BUTTONS, jsonConfigString)
|
||||||
@@ -398,12 +398,12 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
.putInt(CONFIG_ITEM_TIMEZONE_OFFSET, offset)
|
.putInt(CONFIG_ITEM_TIMEZONE_OFFSET, offset)
|
||||||
.apply();
|
.apply();
|
||||||
|
|
||||||
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.TimezoneOffsetConfigItem(offset), this){
|
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.TimezoneOffsetConfigItem(offset), this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
super.onFilePut(success);
|
super.onFilePut(success);
|
||||||
|
|
||||||
if(success) GB.toast("successfully updated timezone", Toast.LENGTH_SHORT, GB.INFO);
|
if (success) GB.toast("successfully updated timezone", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
else GB.toast("error updating timezone", Toast.LENGTH_SHORT, GB.ERROR);
|
else GB.toast("error updating timezone", Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -458,11 +458,11 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
|
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
|
||||||
// throw new RuntimeException("noope");
|
// throw new RuntimeException("noope");
|
||||||
ArrayList<nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm> activeAlarms = new ArrayList<>();
|
ArrayList<nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm> activeAlarms = new ArrayList<>();
|
||||||
for (Alarm alarm : alarms){
|
for (Alarm alarm : alarms) {
|
||||||
if(!alarm.getEnabled()) continue;
|
if (!alarm.getEnabled()) continue;
|
||||||
if(alarm.getRepetition() == 0){
|
if (alarm.getRepetition() == 0) {
|
||||||
activeAlarms.add(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm(
|
activeAlarms.add(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm(
|
||||||
(byte) alarm.getMinute(),
|
(byte) alarm.getMinute(),
|
||||||
(byte) alarm.getHour(),
|
(byte) alarm.getHour(),
|
||||||
@@ -481,12 +481,12 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
alarm.getDescription()
|
alarm.getDescription()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
queueWrite(new AlarmsSetRequest(activeAlarms.toArray(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm[0]), this){
|
queueWrite(new AlarmsSetRequest(activeAlarms.toArray(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.alarm.Alarm[0]), this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
super.onFilePut(success);
|
super.onFilePut(success);
|
||||||
if(success) GB.toast("successfully set alarms", Toast.LENGTH_SHORT, GB.INFO);
|
if (success) GB.toast("successfully set alarms", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
else GB.toast("error setting alarms", Toast.LENGTH_SHORT, GB.INFO);
|
else GB.toast("error setting alarms", Toast.LENGTH_SHORT, GB.INFO);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -525,15 +525,15 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
fossilRequest.handleResponse(characteristic);
|
fossilRequest.handleResponse(characteristic);
|
||||||
requestFinished = fossilRequest.isFinished();
|
requestFinished = fossilRequest.isFinished();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
if(characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")){
|
if (characteristic.getUuid().toString().equals("3dda0005-957f-7d4a-34a6-74696673696d")) {
|
||||||
GB.log("authentication failed", GB.ERROR, null);
|
GB.log("authentication failed", GB.ERROR, null);
|
||||||
setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED);
|
// setDeviceState(GBDevice.State.AUTHENTICATION_REQUIRED);
|
||||||
requestQueue.clear();
|
}else {
|
||||||
|
GB.log("error", GB.ERROR, e);
|
||||||
|
getDeviceSupport().notifiyException(fossilRequest.getName(), e);
|
||||||
|
GB.toast(fossilRequest.getName() + " failed", Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
GB.log("error", GB.ERROR, e);
|
|
||||||
getDeviceSupport().notifiyException(fossilRequest.getName(), e);
|
|
||||||
GB.toast(fossilRequest.getName() + " failed", Toast.LENGTH_SHORT, GB.ERROR);
|
|
||||||
requestFinished = true;
|
requestFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,8 +618,8 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
int action = value[3];
|
int action = value[3];
|
||||||
|
|
||||||
String actionString = "SINGLE";
|
String actionString = "SINGLE";
|
||||||
if(action == 3) actionString = "DOUBLE";
|
if (action == 3) actionString = "DOUBLE";
|
||||||
else if(action == 4) actionString = "LONG";
|
else if (action == 4) actionString = "LONG";
|
||||||
|
|
||||||
// lastButtonIndex = index;
|
// lastButtonIndex = index;
|
||||||
log(actionString + " button press");
|
log(actionString + " button press");
|
||||||
@@ -637,7 +637,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
|
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
|
||||||
super.onMtuChanged(gatt, mtu, status);
|
super.onMtuChanged(gatt, mtu, status);
|
||||||
|
|
||||||
if(this.MTU == mtu){
|
if (this.MTU == mtu) {
|
||||||
log("MTU changed, same value tho");
|
log("MTU changed, same value tho");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -655,7 +655,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
public void queueWrite(RequestMtuRequest request, boolean priorise) {
|
public void queueWrite(RequestMtuRequest request, boolean priorise) {
|
||||||
log("is connected: " + getDeviceSupport().isConnected());
|
log("is connected: " + getDeviceSupport().isConnected());
|
||||||
if(!getDeviceSupport().isConnected()){
|
if (!getDeviceSupport().isConnected()) {
|
||||||
log("dropping requetst " + request.getName());
|
log("dropping requetst " + request.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -687,14 +687,14 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
queueNextRequest();
|
queueNextRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDeviceState(GBDevice.State state){
|
private void setDeviceState(GBDevice.State state) {
|
||||||
getDeviceSupport().getDevice().setState(state);
|
getDeviceSupport().getDevice().setState(state);
|
||||||
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queueWrite(FossilRequest request, boolean priorise) {
|
public void queueWrite(FossilRequest request, boolean priorise) {
|
||||||
log("is connected: " + getDeviceSupport().isConnected());
|
log("is connected: " + getDeviceSupport().isConnected());
|
||||||
if(!getDeviceSupport().isConnected()){
|
if (!getDeviceSupport().isConnected()) {
|
||||||
log("dropping requetst " + request.getName());
|
log("dropping requetst " + request.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -711,7 +711,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
this.fossilRequest = request;
|
this.fossilRequest = request;
|
||||||
new TransactionBuilder(request.getClass().getSimpleName()).write(getDeviceSupport().getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getDeviceSupport().getQueue());
|
new TransactionBuilder(request.getClass().getSimpleName()).write(getDeviceSupport().getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getDeviceSupport().getQueue());
|
||||||
|
|
||||||
if(request.isFinished()){
|
if (request.isFinished()) {
|
||||||
this.fossilRequest = null;
|
this.fossilRequest = null;
|
||||||
queueNextRequest();
|
queueNextRequest();
|
||||||
}
|
}
|
||||||
@@ -719,7 +719,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
public void queueWrite(Request request, boolean priorise) {
|
public void queueWrite(Request request, boolean priorise) {
|
||||||
log("is connected: " + getDeviceSupport().isConnected());
|
log("is connected: " + getDeviceSupport().isConnected());
|
||||||
if(!getDeviceSupport().isConnected()){
|
if (!getDeviceSupport().isConnected()) {
|
||||||
log("dropping requetst " + request.getName());
|
log("dropping requetst " + request.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -730,7 +730,7 @@ public class FossilWatchAdapter extends WatchAdapter {
|
|||||||
|
|
||||||
protected void queueWrite(Request request) {
|
protected void queueWrite(Request request) {
|
||||||
log("is connected: " + getDeviceSupport().isConnected());
|
log("is connected: " + getDeviceSupport().isConnected());
|
||||||
if(!getDeviceSupport().isConnected()){
|
if (!getDeviceSupport().isConnected()) {
|
||||||
log("dropping requetst " + request.getName());
|
log("dropping requetst " + request.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -66,6 +66,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityFileParser;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityFileParser;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.RequestMtuRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.SetDeviceStateRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.button.ButtonConfigurationGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.button.ButtonConfigurationGetRequest;
|
||||||
@@ -85,6 +87,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.AssetFilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRawRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRawRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedInterface;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FirmwareFilePutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FirmwareFilePutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImage;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.image.AssetImageFactory;
|
||||||
@@ -105,6 +108,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.widget.WidgetsPutRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.FactoryResetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.FactoryResetRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetTimeRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
@@ -139,18 +143,16 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
HashMap<String, Bitmap> appIconCache = new HashMap<>();
|
HashMap<String, Bitmap> appIconCache = new HashMap<>();
|
||||||
String lastPostedApp = null;
|
String lastPostedApp = null;
|
||||||
|
|
||||||
|
enum CONNECTION_MODE {
|
||||||
|
NOT_INITIALIZED,
|
||||||
|
AUTHENTICATED,
|
||||||
|
NOT_AUTHENTICATED
|
||||||
|
}
|
||||||
|
|
||||||
|
CONNECTION_MODE connectionMode = CONNECTION_MODE.NOT_INITIALIZED;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
try {
|
|
||||||
getSecretKey();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
GB.toast("erro getting key: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
|
||||||
new TransactionBuilder("init fail")
|
|
||||||
.add(new SetDeviceStateAction(getDeviceSupport().getDevice(), GBDevice.State.AUTHENTICATION_REQUIRED, getContext()))
|
|
||||||
.queue(getDeviceSupport().getQueue());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveRawActivityFiles = getDeviceSpecificPreferences().getBoolean("save_raw_activity_files", false);
|
saveRawActivityFiles = getDeviceSpecificPreferences().getBoolean("save_raw_activity_files", false);
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
@@ -162,23 +164,33 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initializeWithSupportedFileVersions() {
|
protected void initializeWithSupportedFileVersions() {
|
||||||
|
if (getDeviceSupport().getDevice().getFirmwareVersion().contains("prod")) {
|
||||||
|
GB.toast("Dummy FW, skipping initialization", Toast.LENGTH_LONG, GB.INFO);
|
||||||
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.AUTHENTICATING));
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.AUTHENTICATING));
|
||||||
|
|
||||||
negotiateSymmetricKey();
|
negotiateSymmetricKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeAfterAuthentication(boolean authenticated){
|
||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZING));
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZING));
|
||||||
|
|
||||||
|
if(!authenticated) GB.toast("Authentication failed, limited functionality", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
|
||||||
loadNotificationConfigurations();
|
loadNotificationConfigurations();
|
||||||
queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this));
|
queueWrite(new NotificationFilterPutHRRequest(this.notificationConfigurations, this));
|
||||||
setVibrationStrength();
|
|
||||||
|
|
||||||
syncSettings();
|
if(authenticated){
|
||||||
|
setVibrationStrength();
|
||||||
setTime();
|
syncSettings();
|
||||||
|
setTime();
|
||||||
|
}
|
||||||
|
|
||||||
overwriteButtons(null);
|
overwriteButtons(null);
|
||||||
|
|
||||||
|
|
||||||
loadBackground();
|
loadBackground();
|
||||||
loadWidgets();
|
loadWidgets();
|
||||||
// renderWidgets();
|
// renderWidgets();
|
||||||
@@ -187,6 +199,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
|
queueWrite(new SetDeviceStateRequest(GBDevice.State.INITIALIZED));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleAuthenticationResult(boolean success){
|
||||||
|
if(this.connectionMode != CONNECTION_MODE.NOT_INITIALIZED) return;
|
||||||
|
this.connectionMode = success ? CONNECTION_MODE.AUTHENTICATED : CONNECTION_MODE.NOT_AUTHENTICATED;
|
||||||
|
this.initializeAfterAuthentication(success);
|
||||||
|
}
|
||||||
|
|
||||||
private void setVibrationStrength() {
|
private void setVibrationStrength() {
|
||||||
Prefs prefs = new Prefs(getDeviceSpecificPreferences());
|
Prefs prefs = new Prefs(getDeviceSpecificPreferences());
|
||||||
int vibrationStrengh = prefs.getInt(DeviceSettingsPreferenceConst.PREF_VIBRATION_STRENGH_PERCENTAGE, 2);
|
int vibrationStrengh = prefs.getInt(DeviceSettingsPreferenceConst.PREF_VIBRATION_STRENGH_PERCENTAGE, 2);
|
||||||
@@ -198,8 +216,14 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVibrationStrength(short strength) {
|
public void setVibrationStrength(short strength) {
|
||||||
negotiateSymmetricKey();
|
if(connectionMode == CONNECTION_MODE.NOT_AUTHENTICATED){
|
||||||
queueWrite(new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength), this));
|
GB.toast("not available in unauthenticated mode", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queueWrite(
|
||||||
|
(FileEncryptedInterface) new ConfigurationPutRequest(new nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest.VibrationStrengthConfigItem((byte) strength), this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadNotificationConfigurations() {
|
private void loadNotificationConfigurations() {
|
||||||
@@ -337,7 +361,6 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void uploadWidgets() {
|
private void uploadWidgets() {
|
||||||
negotiateSymmetricKey();
|
|
||||||
ArrayList<Widget> systemWidgets = new ArrayList<>(widgets.size());
|
ArrayList<Widget> systemWidgets = new ArrayList<>(widgets.size());
|
||||||
for (Widget widget : this.widgets) {
|
for (Widget widget : this.widgets) {
|
||||||
if (!(widget instanceof CustomWidget) && !widget.getWidgetType().isCustom())
|
if (!(widget instanceof CustomWidget) && !widget.getWidgetType().isCustom())
|
||||||
@@ -514,7 +537,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleFileDownload(FileHandle handle, byte[] file){
|
private void handleFileDownload(FileHandle handle, byte[] file) {
|
||||||
Intent resultIntent = new Intent(QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE);
|
Intent resultIntent = new Intent(QHybridSupport.QHYBRID_ACTION_DOWNLOADED_FILE);
|
||||||
File outputFile = new File(getContext().getExternalFilesDir("download"), handle.name() + "_" + System.currentTimeMillis() + ".bin");
|
File outputFile = new File(getContext().getExternalFilesDir("download"), handle.name() + "_" + System.currentTimeMillis() + ".bin");
|
||||||
try {
|
try {
|
||||||
@@ -547,7 +570,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
queueWrite(new FilePutRawRequest(handle, fileData, this){
|
queueWrite(new FilePutRawRequest(handle, fileData, this) {
|
||||||
@Override
|
@Override
|
||||||
public void onFilePut(boolean success) {
|
public void onFilePut(boolean success) {
|
||||||
resultIntent.putExtra("EXTRA_SUCCESS", success);
|
resultIntent.putExtra("EXTRA_SUCCESS", success);
|
||||||
@@ -558,16 +581,15 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void downloadFile(final FileHandle handle, boolean fileIsEncrypted) {
|
public void downloadFile(final FileHandle handle, boolean fileIsEncrypted) {
|
||||||
if(fileIsEncrypted){
|
if (fileIsEncrypted) {
|
||||||
negotiateSymmetricKey();
|
queueWrite((FileEncryptedInterface) new FileEncryptedGetRequest(handle, this) {
|
||||||
queueWrite(new FileEncryptedGetRequest(handle, this) {
|
|
||||||
@Override
|
@Override
|
||||||
public void handleFileData(byte[] fileData) {
|
public void handleFileData(byte[] fileData) {
|
||||||
logger.debug("downloaded encrypted file");
|
logger.debug("downloaded encrypted file");
|
||||||
handleFileDownload(handle, fileData);
|
handleFileDownload(handle, fileData);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
} else {
|
||||||
queueWrite(new FileGetRawRequest(handle, this) {
|
queueWrite(new FileGetRawRequest(handle, this) {
|
||||||
@Override
|
@Override
|
||||||
public void handleFileRawData(byte[] fileData) {
|
public void handleFileRawData(byte[] fileData) {
|
||||||
@@ -589,21 +611,43 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
if (renderOnWatch && update) renderWidgets();
|
if (renderOnWatch && update) renderWidgets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void queueWrite(final FileEncryptedInterface request){
|
||||||
|
try {
|
||||||
|
queueWrite(new VerifyPrivateKeyRequest(
|
||||||
|
this.getSecretKey(),
|
||||||
|
this
|
||||||
|
){
|
||||||
|
@Override
|
||||||
|
protected void handleAuthenticationResult(boolean success) {
|
||||||
|
if(success){
|
||||||
|
GB.log("success auth", GB.INFO, null);
|
||||||
|
queueWrite((FossilRequest) request, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
GB.toast("error getting key: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void negotiateSymmetricKey() {
|
private void negotiateSymmetricKey() {
|
||||||
try {
|
try {
|
||||||
queueWrite(new VerifyPrivateKeyRequest(
|
queueWrite(new VerifyPrivateKeyRequest(
|
||||||
this.getSecretKey(),
|
this.getSecretKey(),
|
||||||
this
|
this
|
||||||
));
|
){
|
||||||
|
@Override
|
||||||
|
protected void handleAuthenticationResult(boolean success) {
|
||||||
|
FossilHRWatchAdapter.this.handleAuthenticationResult(success);
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
GB.toast("error getting key: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
GB.toast("error getting key: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||||
getDeviceSupport().getDevice().setState(GBDevice.State.AUTHENTICATION_REQUIRED);
|
this.handleAuthenticationResult(false);
|
||||||
getDeviceSupport().getDevice().sendDeviceUpdateIntent(getContext());
|
|
||||||
getDeviceSupport().getQueue().clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toast(final String data){
|
private void toast(final String data) {
|
||||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -614,10 +658,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTime() {
|
public void setTime() {
|
||||||
negotiateSymmetricKey();
|
if(connectionMode == CONNECTION_MODE.NOT_AUTHENTICATED){
|
||||||
|
GB.toast("not available in unauthenticated mode", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
queueWrite(
|
queueWrite(
|
||||||
new ConfigurationPutRequest(this.generateTimeConfigItemNow() ,this), false
|
(FileEncryptedInterface) new ConfigurationPutRequest(this.generateTimeConfigItemNow(), this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,13 +705,17 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFetchActivityData() {
|
public void onFetchActivityData() {
|
||||||
|
if(connectionMode == CONNECTION_MODE.NOT_AUTHENTICATED){
|
||||||
|
GB.toast("not available in unauthenticated mode", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
syncSettings();
|
syncSettings();
|
||||||
|
|
||||||
negotiateSymmetricKey();
|
|
||||||
queueWrite(new FileLookupRequest(FileHandle.ACTIVITY_FILE, this) {
|
queueWrite(new FileLookupRequest(FileHandle.ACTIVITY_FILE, this) {
|
||||||
@Override
|
@Override
|
||||||
public void handleFileLookup(final short fileHandle) {
|
public void handleFileLookup(final short fileHandle) {
|
||||||
queueWrite(new FileEncryptedGetRequest(fileHandle, FossilHRWatchAdapter.this) {
|
queueWrite((FileEncryptedInterface) new FileEncryptedGetRequest(fileHandle, FossilHRWatchAdapter.this) {
|
||||||
@Override
|
@Override
|
||||||
public void handleFileData(byte[] fileData) {
|
public void handleFileData(byte[] fileData) {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
@@ -725,9 +775,12 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void syncSettings() {
|
private void syncSettings() {
|
||||||
negotiateSymmetricKey();
|
if(connectionMode == CONNECTION_MODE.NOT_AUTHENTICATED){
|
||||||
|
GB.toast("not available in unauthenticated mode", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
queueWrite(new ConfigurationGetRequest(this));
|
queueWrite((FileEncryptedInterface) new ConfigurationGetRequest(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1010,7 +1063,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
if (authKey != null && !authKey.isEmpty()) {
|
if (authKey != null && !authKey.isEmpty()) {
|
||||||
authKey = authKey.replace(" ", "");
|
authKey = authKey.replace(" ", "");
|
||||||
authKey = authKey.replace("0x", "");
|
authKey = authKey.replace("0x", "");
|
||||||
if(authKey.length() != 32){
|
if (authKey.length() != 32) {
|
||||||
throw new IllegalAccessException("Key should be 16 bytes long as hex string");
|
throw new IllegalAccessException("Key should be 16 bytes long as hex string");
|
||||||
}
|
}
|
||||||
byte[] srcBytes = GB.hexStringToByteArray(authKey);
|
byte[] srcBytes = GB.hexStringToByteArray(authKey);
|
||||||
@@ -1052,10 +1105,11 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
|
|||||||
|
|
||||||
String firmware = getDeviceSupport().getDevice().getFirmwareVersion();
|
String firmware = getDeviceSupport().getDevice().getFirmwareVersion();
|
||||||
Matcher matcher = Pattern.compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").matcher(firmware); // DN1.0.2.19r.v5
|
Matcher matcher = Pattern.compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+").matcher(firmware); // DN1.0.2.19r.v5
|
||||||
if(matcher.find()){
|
if (matcher.find()) {
|
||||||
firmware = matcher.group(0);
|
firmware = matcher.group(0);
|
||||||
Version version = new Version(firmware);
|
Version version = new Version(firmware);
|
||||||
if(version.compareTo(new Version("1.0.2.19")) == -1) singlePressEvent = "single_click";
|
if (version.compareTo(new Version("1.0.2.19")) == -1)
|
||||||
|
singlePressEvent = "single_click";
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonConfiguration[] buttonConfigurations = new ButtonConfiguration[]{
|
ButtonConfiguration[] buttonConfigurations = new ButtonConfiguration[]{
|
||||||
|
@@ -84,6 +84,8 @@ public class VerifyPrivateKeyRequest extends FossilRequest {
|
|||||||
} else if (value[1] == 2) {
|
} else if (value[1] == 2) {
|
||||||
ResultCode code = ResultCode.fromCode(value[2]);
|
ResultCode code = ResultCode.fromCode(value[2]);
|
||||||
|
|
||||||
|
handleAuthenticationResult(code.inidicatesSuccess());
|
||||||
|
|
||||||
if (!code.inidicatesSuccess()) throw new RuntimeException("Authentication error: " + code + " (" + value[2] + ")");
|
if (!code.inidicatesSuccess()) throw new RuntimeException("Authentication error: " + code + " (" + value[2] + ")");
|
||||||
|
|
||||||
|
|
||||||
@@ -91,6 +93,8 @@ public class VerifyPrivateKeyRequest extends FossilRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void handleAuthenticationResult(boolean success){}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isFinished() {
|
public boolean isFinished() {
|
||||||
return isFinished;
|
return isFinished;
|
||||||
|
@@ -10,10 +10,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil_hr.FossilHRWatchAdapter;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.configuration.ConfigurationPutRequest;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedInterface;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedLookupAndGetRequest;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file.FileEncryptedLookupAndGetRequest;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest {
|
public class ConfigurationGetRequest extends FileEncryptedLookupAndGetRequest implements FileEncryptedInterface {
|
||||||
public ConfigurationGetRequest(FossilHRWatchAdapter adapter) {
|
public ConfigurationGetRequest(FossilHRWatchAdapter adapter) {
|
||||||
super(FileHandle.CONFIGURATION, adapter);
|
super(FileHandle.CONFIGURATION, adapter);
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
public abstract class FileEncryptedGetRequest extends FossilRequest {
|
public abstract class FileEncryptedGetRequest extends FossilRequest implements FileEncryptedInterface{
|
||||||
private short handle;
|
private short handle;
|
||||||
private FossilHRWatchAdapter adapter;
|
private FossilHRWatchAdapter adapter;
|
||||||
|
|
||||||
|
@@ -0,0 +1,4 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file;
|
||||||
|
|
||||||
|
public interface FileEncryptedInterface {
|
||||||
|
}
|
@@ -36,7 +36,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;
|
import nodomain.freeyourgadget.gadgetbridge.util.CRC32C;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
|
|
||||||
public class FileEncryptedPutRequest extends FossilRequest {
|
public class FileEncryptedPutRequest extends FossilRequest implements FileEncryptedInterface {
|
||||||
public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED}
|
public enum UploadState {INITIALIZED, UPLOADING, CLOSING, UPLOADED}
|
||||||
|
|
||||||
public UploadState state;
|
public UploadState state;
|
||||||
|
Reference in New Issue
Block a user