1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2025-02-18 05:17:08 +01:00

added some requests and logic

This commit is contained in:
Daniel Dakhno 2019-10-28 12:35:22 +01:00
parent 37d7df2d31
commit 06d7568249
19 changed files with 588 additions and 353 deletions

View File

@ -56,7 +56,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo
public class ConfigActivity extends AbstractGBActivity { public class ConfigActivity extends AbstractGBActivity {
PackageAdapter adapter; PackageAdapter adapter;
ArrayList<PackageConfig> list; ArrayList<NotificationConfiguration> list;
PackageConfigHelper helper; PackageConfigHelper helper;
final int REQUEST_CODE_ADD_APP = 0; final int REQUEST_CODE_ADD_APP = 0;
@ -146,10 +146,10 @@ public class ConfigActivity extends AbstractGBActivity {
public boolean onMenuItemClick(MenuItem menuItem) { public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getTitle().toString()) { switch (menuItem.getTitle().toString()) {
case "edit": { case "edit": {
TimePicker picker = new TimePicker(ConfigActivity.this, (PackageConfig) adapterView.getItemAtPosition(i)); TimePicker picker = new TimePicker(ConfigActivity.this, (NotificationConfiguration) adapterView.getItemAtPosition(i));
picker.finishListener = new TimePicker.OnFinishListener() { picker.finishListener = new TimePicker.OnFinishListener() {
@Override @Override
public void onFinish(boolean success, PackageConfig config) { public void onFinish(boolean success, NotificationConfiguration config) {
setControl(false, null); setControl(false, null);
if (success) { if (success) {
helper.saveConfig(config); helper.saveConfig(config);
@ -159,13 +159,13 @@ public class ConfigActivity extends AbstractGBActivity {
}; };
picker.handsListener = new TimePicker.OnHandsSetListener() { picker.handsListener = new TimePicker.OnHandsSetListener() {
@Override @Override
public void onHandsSet(PackageConfig config) { public void onHandsSet(NotificationConfiguration config) {
setHands(config); setHands(config);
} }
}; };
picker.vibrationListener = new TimePicker.OnVibrationSetListener() { picker.vibrationListener = new TimePicker.OnVibrationSetListener() {
@Override @Override
public void onVibrationSet(PackageConfig config) { public void onVibrationSet(NotificationConfiguration config) {
vibrate(config); vibrate(config);
} }
}; };
@ -173,7 +173,7 @@ public class ConfigActivity extends AbstractGBActivity {
break; break;
} }
case "delete": { case "delete": {
helper.deleteConfig((PackageConfig) adapterView.getItemAtPosition(i)); helper.deleteConfig((NotificationConfiguration) adapterView.getItemAtPosition(i));
refreshList(); refreshList();
break; break;
} }
@ -190,7 +190,7 @@ public class ConfigActivity extends AbstractGBActivity {
@Override @Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent notificationIntent = new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION); Intent notificationIntent = new Intent(QHybridSupport.QHYBRID_COMMAND_NOTIFICATION);
notificationIntent.putExtra("CONFIG", (PackageConfig) adapterView.getItemAtPosition(i)); notificationIntent.putExtra("CONFIG", (NotificationConfiguration) adapterView.getItemAtPosition(i));
LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(notificationIntent); LocalBroadcastManager.getInstance(ConfigActivity.this).sendBroadcast(notificationIntent);
} }
}); });
@ -307,7 +307,7 @@ public class ConfigActivity extends AbstractGBActivity {
}); });
} }
private void setControl(boolean control, PackageConfig config) { private void setControl(boolean control, NotificationConfiguration config) {
if (hasControl == control) return; if (hasControl == control) return;
Intent intent = new Intent(control ? QHybridSupport.QHYBRID_COMMAND_CONTROL : QHybridSupport.QHYBRID_COMMAND_UNCONTROL); Intent intent = new Intent(control ? QHybridSupport.QHYBRID_COMMAND_CONTROL : QHybridSupport.QHYBRID_COMMAND_UNCONTROL);
intent.putExtra("CONFIG", config); intent.putExtra("CONFIG", config);
@ -315,15 +315,15 @@ public class ConfigActivity extends AbstractGBActivity {
this.hasControl = control; this.hasControl = control;
} }
private void setHands(PackageConfig config) { private void setHands(NotificationConfiguration config) {
sendControl(config, QHybridSupport.QHYBRID_COMMAND_SET); sendControl(config, QHybridSupport.QHYBRID_COMMAND_SET);
} }
private void vibrate(PackageConfig config) { private void vibrate(NotificationConfiguration config) {
sendControl(config, QHybridSupport.QHYBRID_COMMAND_VIBRATE); sendControl(config, QHybridSupport.QHYBRID_COMMAND_VIBRATE);
} }
private void sendControl(PackageConfig config, String request) { private void sendControl(NotificationConfiguration config, String request) {
Intent intent = new Intent(request); Intent intent = new Intent(request);
intent.putExtra("CONFIG", config); intent.putExtra("CONFIG", config);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
@ -376,10 +376,10 @@ public class ConfigActivity extends AbstractGBActivity {
}); });
} }
class PackageAdapter extends ArrayAdapter<PackageConfig> { class PackageAdapter extends ArrayAdapter<NotificationConfiguration> {
PackageManager manager; PackageManager manager;
PackageAdapter(@NonNull Context context, int resource, @NonNull List<PackageConfig> objects) { PackageAdapter(@NonNull Context context, int resource, @NonNull List<NotificationConfiguration> objects) {
super(context, resource, objects); super(context, resource, objects);
manager = context.getPackageManager(); manager = context.getPackageManager();
} }
@ -389,7 +389,7 @@ public class ConfigActivity extends AbstractGBActivity {
public View getView(int position, @Nullable View view, @NonNull ViewGroup parent) { public View getView(int position, @Nullable View view, @NonNull ViewGroup parent) {
if (!(view instanceof RelativeLayout)) if (!(view instanceof RelativeLayout))
view = ((LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.qhybrid_package_settings_item, null); view = ((LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(R.layout.qhybrid_package_settings_item, null);
PackageConfig settings = getItem(position); NotificationConfiguration settings = getItem(position);
if (settings == null) { if (settings == null) {
Button addButton = new Button(ConfigActivity.this); Button addButton = new Button(ConfigActivity.this);

View File

@ -6,14 +6,14 @@ import java.io.Serializable;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
public class PackageConfig implements Serializable { public class NotificationConfiguration implements Serializable {
private short min, hour, activity = -1; private short min, hour, subEye = -1;
private String packageName, appName; private String packageName, appName;
private PlayNotificationRequest.VibrationType vibration; private PlayNotificationRequest.VibrationType vibration;
private boolean respectSilentMode; private boolean respectSilentMode;
private long id = -1; private long id = -1;
PackageConfig(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration) { NotificationConfiguration(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration) {
this.min = min; this.min = min;
this.hour = hour; this.hour = hour;
this.packageName = packageName; this.packageName = packageName;
@ -22,14 +22,14 @@ public class PackageConfig implements Serializable {
this.vibration = vibration; this.vibration = vibration;
} }
public PackageConfig(short min, short hour, short activity, PlayNotificationRequest.VibrationType vibration) { public NotificationConfiguration(short min, short hour, short subEye, PlayNotificationRequest.VibrationType vibration) {
this.min = min; this.min = min;
this.hour = hour; this.hour = hour;
this.activity = activity; this.subEye = subEye;
this.vibration = vibration; this.vibration = vibration;
} }
PackageConfig(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration, long id) { NotificationConfiguration(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration, long id) {
this.min = min; this.min = min;
this.hour = hour; this.hour = hour;
this.packageName = packageName; this.packageName = packageName;
@ -38,7 +38,7 @@ public class PackageConfig implements Serializable {
this.vibration = vibration; this.vibration = vibration;
this.id = id; this.id = id;
} }
PackageConfig(String packageName, String appName) { NotificationConfiguration(String packageName, String appName) {
this.min = -1; this.min = -1;
this.hour = -1; this.hour = -1;
this.packageName = packageName; this.packageName = packageName;
@ -97,12 +97,12 @@ public class PackageConfig implements Serializable {
return hour; return hour;
} }
public short getActivity() { public short getSubEye() {
return activity; return subEye;
} }
public void setActivity(short activity) { public void setSubEye(short subEye) {
this.activity = activity; this.subEye = subEye;
} }
public String getPackageName() { public String getPackageName() {

View File

@ -31,7 +31,7 @@ public class PackageConfigHelper extends DBOpenHelper {
initDB(); initDB();
} }
public void saveConfig(PackageConfig settings){ public void saveConfig(NotificationConfiguration settings){
ContentValues values = new ContentValues(6); ContentValues values = new ContentValues(6);
values.put(DB_PACKAGE, settings.getPackageName()); values.put(DB_PACKAGE, settings.getPackageName());
values.put(DB_APPNAME, settings.getAppName()); values.put(DB_APPNAME, settings.getAppName());
@ -48,10 +48,10 @@ public class PackageConfigHelper extends DBOpenHelper {
//LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent()); //LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent());
} }
public ArrayList<PackageConfig> getSettings(){ public ArrayList<NotificationConfiguration> getSettings(){
Cursor cursor = database.query(DB_TABLE, new String[]{"*"}, null, null, null, null, null); Cursor cursor = database.query(DB_TABLE, new String[]{"*"}, null, null, null, null, null);
int size = cursor.getCount(); int size = cursor.getCount();
ArrayList<PackageConfig> list = new ArrayList<>(size); ArrayList<NotificationConfiguration> list = new ArrayList<>(size);
if(size > 0){ if(size > 0){
int appNamePos = cursor.getColumnIndex(DB_APPNAME); int appNamePos = cursor.getColumnIndex(DB_APPNAME);
int packageNamePos = cursor.getColumnIndex(DB_PACKAGE); int packageNamePos = cursor.getColumnIndex(DB_PACKAGE);
@ -62,7 +62,7 @@ public class PackageConfigHelper extends DBOpenHelper {
int idPos = cursor.getColumnIndex(DB_ID); int idPos = cursor.getColumnIndex(DB_ID);
cursor.moveToFirst(); cursor.moveToFirst();
do { do {
list.add(new PackageConfig( list.add(new NotificationConfiguration(
(short)cursor.getInt(minPos), (short)cursor.getInt(minPos),
(short)cursor.getInt(hourPos), (short)cursor.getInt(hourPos),
cursor.getString(packageNamePos), cursor.getString(packageNamePos),
@ -78,7 +78,7 @@ public class PackageConfigHelper extends DBOpenHelper {
return list; return list;
} }
public PackageConfig getSetting(String appName){ public NotificationConfiguration getSetting(String appName){
if(appName == null) return null; if(appName == null) return null;
Cursor c = database.query(DB_TABLE, new String[]{"*"}, DB_APPNAME + "=?", new String[]{appName}, null, null, null); Cursor c = database.query(DB_TABLE, new String[]{"*"}, DB_APPNAME + "=?", new String[]{appName}, null, null, null);
if(c.getCount() == 0){ if(c.getCount() == 0){
@ -86,7 +86,7 @@ public class PackageConfigHelper extends DBOpenHelper {
return null; return null;
} }
c.moveToFirst(); c.moveToFirst();
PackageConfig settings = new PackageConfig( NotificationConfiguration settings = new NotificationConfiguration(
(short)c.getInt(c.getColumnIndex(DB_MINUTE)), (short)c.getInt(c.getColumnIndex(DB_MINUTE)),
(short)c.getInt(c.getColumnIndex(DB_HOUR)), (short)c.getInt(c.getColumnIndex(DB_HOUR)),
c.getString(c.getColumnIndex(DB_PACKAGE)), c.getString(c.getColumnIndex(DB_PACKAGE)),
@ -116,7 +116,7 @@ public class PackageConfigHelper extends DBOpenHelper {
database.close(); database.close();
} }
public void deleteConfig(PackageConfig packageSettings) { public void deleteConfig(NotificationConfiguration packageSettings) {
Log.d("DB", "deleting id " + packageSettings.getId()); Log.d("DB", "deleting id " + packageSettings.getId());
if(packageSettings.getId() == -1) return; if(packageSettings.getId() == -1) return;
this.database.delete(DB_TABLE, DB_ID + "=?", new String[]{String.valueOf(packageSettings.getId())}); this.database.delete(DB_TABLE, DB_ID + "=?", new String[]{String.valueOf(packageSettings.getId())});

View File

@ -88,15 +88,15 @@ public class QHybridAppChoserActivity extends AbstractGBActivity {
this.hasControl = control; this.hasControl = control;
} }
private void setHands(PackageConfig config){ private void setHands(NotificationConfiguration config){
sendControl(config, QHybridSupport.QHYBRID_COMMAND_SET); sendControl(config, QHybridSupport.QHYBRID_COMMAND_SET);
} }
private void vibrate(PackageConfig config){ private void vibrate(NotificationConfiguration config){
sendControl(config, QHybridSupport.QHYBRID_COMMAND_VIBRATE); sendControl(config, QHybridSupport.QHYBRID_COMMAND_VIBRATE);
} }
private void sendControl(PackageConfig config, String request){ private void sendControl(NotificationConfiguration config, String request){
Intent intent = new Intent(request); Intent intent = new Intent(request);
intent.putExtra("CONFIG", config); intent.putExtra("CONFIG", config);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
@ -108,7 +108,7 @@ public class QHybridAppChoserActivity extends AbstractGBActivity {
picker.finishListener = new TimePicker.OnFinishListener() { picker.finishListener = new TimePicker.OnFinishListener() {
@Override @Override
public void onFinish(boolean success, PackageConfig config) { public void onFinish(boolean success, NotificationConfiguration config) {
setControl(false); setControl(false);
if(success){ if(success){
helper.saveConfig(config); helper.saveConfig(config);
@ -119,14 +119,14 @@ public class QHybridAppChoserActivity extends AbstractGBActivity {
picker.handsListener = new TimePicker.OnHandsSetListener() { picker.handsListener = new TimePicker.OnHandsSetListener() {
@Override @Override
public void onHandsSet(PackageConfig config) { public void onHandsSet(NotificationConfiguration config) {
setHands(config); setHands(config);
} }
}; };
picker.vibrationListener = new TimePicker.OnVibrationSetListener() { picker.vibrationListener = new TimePicker.OnVibrationSetListener() {
@Override @Override
public void onVibrationSet(PackageConfig config) { public void onVibrationSet(NotificationConfiguration config) {
vibrate(config); vibrate(config);
} }
}; };

View File

@ -19,7 +19,7 @@ public class TaskerPluginReceiver extends BroadcastReceiver {
int minDegrees = (int)Float.parseFloat(min); int minDegrees = (int)Float.parseFloat(min);
int hourDegrees = (int)Float.parseFloat(hour); int hourDegrees = (int)Float.parseFloat(hour);
PackageConfig config = new PackageConfig( NotificationConfiguration config = new NotificationConfiguration(
(short)minDegrees, (short)minDegrees,
(short)hourDegrees, (short)hourDegrees,
null, null,

View File

@ -28,7 +28,7 @@ public class TimePicker extends AlertDialog.Builder {
Canvas pickerCanvas; Canvas pickerCanvas;
Bitmap pickerBitmap; Bitmap pickerBitmap;
PackageConfig settings; NotificationConfiguration settings;
int height, width, radius; int height, width, radius;
int radius1, radius2, radius3; int radius1, radius2, radius3;
@ -44,11 +44,11 @@ public class TimePicker extends AlertDialog.Builder {
protected TimePicker(@NonNull Context context, PackageInfo info) { protected TimePicker(@NonNull Context context, PackageInfo info) {
super(context); super(context);
settings = new PackageConfig(info.packageName, context.getApplicationContext().getPackageManager().getApplicationLabel(info.applicationInfo).toString()); settings = new NotificationConfiguration(info.packageName, context.getApplicationContext().getPackageManager().getApplicationLabel(info.applicationInfo).toString());
initGraphics(context); initGraphics(context);
} }
protected TimePicker(Context context, PackageConfig config){ protected TimePicker(Context context, NotificationConfiguration config){
super(context); super(context);
settings = config; settings = config;
@ -148,7 +148,7 @@ public class TimePicker extends AlertDialog.Builder {
}); });
} }
public PackageConfig getSettings() { public NotificationConfiguration getSettings() {
return settings; return settings;
} }
@ -265,14 +265,14 @@ public class TimePicker extends AlertDialog.Builder {
} }
interface OnFinishListener{ interface OnFinishListener{
public void onFinish(boolean success, PackageConfig config); public void onFinish(boolean success, NotificationConfiguration config);
} }
interface OnHandsSetListener{ interface OnHandsSetListener{
public void onHandsSet(PackageConfig config); public void onHandsSet(NotificationConfiguration config);
} }
interface OnVibrationSetListener{ interface OnVibrationSetListener{
public void onVibrationSet(PackageConfig config); public void onVibrationSet(NotificationConfiguration config);
} }
} }

View File

@ -24,7 +24,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfigHelper;
import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener; import nodomain.freeyourgadget.gadgetbridge.externalevents.NotificationListener;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -148,7 +148,7 @@ public class QHybridSupport extends QHybridBaseSupport {
//new Exception().printStackTrace(); //new Exception().printStackTrace();
String packageName = notificationSpec.sourceName; String packageName = notificationSpec.sourceName;
PackageConfig config = helper.getSetting(packageName); NotificationConfiguration config = helper.getSetting(packageName);
if (config == null) return; if (config == null) return;
Log.d("Service", "handling notification"); Log.d("Service", "handling notification");
@ -160,7 +160,7 @@ public class QHybridSupport extends QHybridBaseSupport {
boolean enforceActivityHandNotification = config.getHour() == -1 && config.getMin() == -1; boolean enforceActivityHandNotification = config.getHour() == -1 && config.getMin() == -1;
showNotificationsByAllActive(enforceActivityHandNotification); // showNotificationsByAllActive(enforceActivityHandNotification);
playNotification(config); playNotification(config);
} }
@ -178,7 +178,7 @@ public class QHybridSupport extends QHybridBaseSupport {
showNotificationCountOnActivityHand(progress); showNotificationCountOnActivityHand(progress);
if (enforceByNotification) { if (enforceByNotification) {
watchAdapter.playNotification(new PackageConfig( watchAdapter.playNotification(new NotificationConfiguration(
(short) -1, (short) -1,
(short) -1, (short) -1,
(short) (progress * 180), (short) (progress * 180),
@ -189,19 +189,19 @@ public class QHybridSupport extends QHybridBaseSupport {
public double calculateNotificationProgress() { public double calculateNotificationProgress() {
HashMap<PackageConfig, Boolean> configs = new HashMap<>(0); HashMap<NotificationConfiguration, Boolean> configs = new HashMap<>(0);
for (PackageConfig config : helper.getSettings()) { for (NotificationConfiguration config : helper.getSettings()) {
configs.put(config, false); configs.put(config, false);
} }
double notificationProgress = 0; double notificationProgress = 0;
for (String notificationPackage : NotificationListener.notificationStack) { for (String notificationPackage : NotificationListener.notificationStack) {
for (PackageConfig packageConfig : configs.keySet()) { for (NotificationConfiguration notificationConfiguration : configs.keySet()) {
if (configs.get(packageConfig)) continue; if (configs.get(notificationConfiguration)) continue;
if (packageConfig.getPackageName().equals(notificationPackage)) { if (notificationConfiguration.getPackageName().equals(notificationPackage)) {
notificationProgress += 0.25; notificationProgress += 0.25;
configs.put(packageConfig, true); configs.put(notificationConfiguration, true);
} }
} }
} }
@ -215,7 +215,7 @@ public class QHybridSupport extends QHybridBaseSupport {
} }
} }
private void playNotification(PackageConfig config) { private void playNotification(NotificationConfiguration config) {
if (config.getMin() == -1 && config.getHour() == -1 && config.getVibration() == PlayNotificationRequest.VibrationType.NO_VIBE) if (config.getMin() == -1 && config.getHour() == -1 && config.getVibration() == PlayNotificationRequest.VibrationType.NO_VIBE)
return; return;
watchAdapter.playNotification(config); watchAdapter.playNotification(config);
@ -357,7 +357,7 @@ public class QHybridSupport extends QHybridBaseSupport {
float progress = (float) extra; float progress = (float) extra;
watchAdapter.setActivityHand(progress); watchAdapter.setActivityHand(progress);
watchAdapter.playNotification(new PackageConfig( watchAdapter.playNotification(new NotificationConfiguration(
(short) -1, (short) -1,
(short) -1, (short) -1,
(short) (progress * 180), (short) (progress * 180),
@ -378,7 +378,7 @@ public class QHybridSupport extends QHybridBaseSupport {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
PackageConfig config = extras == null ? null : (PackageConfig) intent.getExtras().get("CONFIG"); NotificationConfiguration config = extras == null ? null : (NotificationConfiguration) intent.getExtras().get("CONFIG");
switch (intent.getAction()) { switch (intent.getAction()) {
case QHYBRID_COMMAND_CONTROL: { case QHYBRID_COMMAND_CONTROL: {
Log.d("Service", "sending control request"); Log.d("Service", "sending control request");

View File

@ -4,12 +4,8 @@ import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context; import android.content.Context;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.misfit.MisfitWatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
public abstract class WatchAdapter { public abstract class WatchAdapter {
@ -30,7 +26,7 @@ public abstract class WatchAdapter {
public abstract void initialize(); public abstract void initialize();
public abstract void playPairingAnimation(); public abstract void playPairingAnimation();
public abstract void playNotification(PackageConfig config); public abstract void playNotification(NotificationConfiguration config);
public abstract void setTime(); public abstract void setTime();
public abstract void overwriteButtons(); public abstract void overwriteButtons();
public abstract void setActivityHand(double progress); public abstract void setActivityHand(double progress);

View File

@ -11,19 +11,19 @@ import java.util.NoSuchElementException;
import java.util.Queue; import java.util.Queue;
import java.util.TimeZone; import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.ConfigurationGetRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.ConfigurationGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.ConfigurationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.ConfigurationPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FileGetRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FileGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FileLookupAndGetRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FileLookupRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FileLookupRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FilePutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.NotifcationFilterGetRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.NotificationFilterPutRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.PlayNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.PrepareFilesRequestOrWhatever;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
public class FossilWatchAdapter extends WatchAdapter { public class FossilWatchAdapter extends WatchAdapter {
@ -41,6 +41,7 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override @Override
public void initialize() { public void initialize() {
playPairingAnimation(); playPairingAnimation();
queueWrite(new PrepareFilesRequestOrWhatever());
} }
@ -50,7 +51,7 @@ public class FossilWatchAdapter extends WatchAdapter {
} }
@Override @Override
public void playNotification(PackageConfig config) { public void playNotification(NotificationConfiguration config) {
queueWrite(new PlayNotificationRequest(config.getPackageName(), this)); queueWrite(new PlayNotificationRequest(config.getPackageName(), this));
} }
@ -60,8 +61,8 @@ public class FossilWatchAdapter extends WatchAdapter {
TimeZone zone = new GregorianCalendar().getTimeZone(); TimeZone zone = new GregorianCalendar().getTimeZone();
queueWrite( queueWrite(
new ConfigurationRequest( new ConfigurationPutRequest(
new ConfigurationRequest.TimeConfigItem( new ConfigurationPutRequest.TimeConfigItem(
(int) (millis / 1000 + getDeviceSupport().getTimeOffset() * 60), (int) (millis / 1000 + getDeviceSupport().getTimeOffset() * 60),
(short) (millis % 1000), (short) (millis % 1000),
(short) ((zone.getRawOffset() + (zone.inDaylightTime(new Date()) ? 1 : 0)) / 60000) (short) ((zone.getRawOffset() + (zone.inDaylightTime(new Date()) ? 1 : 0)) / 60000)
@ -77,7 +78,10 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override @Override
public void setActivityHand(double progress) { public void setActivityHand(double progress) {
queueWrite(new ConfigurationPutRequest(
new ConfigurationPutRequest.CurrentStepCountConfigItem(Math.min(999999, (int) (1000000 * progress))),
this
));
} }
@Override @Override
@ -107,17 +111,34 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override @Override
public void setStepGoal(int stepGoal) { public void setStepGoal(int stepGoal) {
queueWrite(new ConfigurationPutRequest(new ConfigurationPutRequest.DailyStepGoalConfigItem(stepGoal), this));
} }
@Override @Override
public void setVibrationStrength(short strength) { public void setVibrationStrength(short strength) {
queueWrite(
new ConfigurationPutRequest(
new ConfigurationPutRequest.VibrationStrengthConfigItem(
(byte) strength
),
this
)
);
} }
@Override @Override
public void onTestNewFunction() { public void onTestNewFunction() {
queueWrite(new FileLookupAndGetRequest((byte)8, this)); NotificationConfiguration c = new NotificationConfiguration(
(short) 0x77,
(short) 0x77,
(short) 0xFF,
nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest.VibrationType.WHATEVER
);
c.setPackageName("com.whatsapp");
queueWrite(new NotificationFilterPutRequest(
new NotificationConfiguration[]{c, c},
this
));
} }
@Override @Override
@ -158,7 +179,7 @@ public class FossilWatchAdapter extends WatchAdapter {
@Override @Override
public void onFetchActivityData() { public void onFetchActivityData() {
queueWrite(new ConfigurationGetRequest(this));
} }
@Override @Override
@ -177,34 +198,34 @@ public class FossilWatchAdapter extends WatchAdapter {
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
} }
} }
} else if(fileGetRequest != null){ } else if (fileGetRequest != null) {
boolean requestFinished; boolean requestFinished;
try { try {
fileGetRequest.handleResponse(characteristic); fileGetRequest.handleResponse(characteristic);
requestFinished = fileGetRequest.isFinished(); requestFinished = fileGetRequest.isFinished();
}catch (RuntimeException e){ } catch (RuntimeException e) {
e.printStackTrace(); e.printStackTrace();
requestFinished = true; requestFinished = true;
} }
if(requestFinished){ if (requestFinished) {
fileGetRequest = null; fileGetRequest = null;
try { try {
queueWrite(requestQueue.remove()); queueWrite(requestQueue.remove());
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
} }
} }
} else if(fileLookupRequest != null){ } else if (fileLookupRequest != null) {
boolean requestFinished; boolean requestFinished;
try { try {
fileLookupRequest.handleResponse(characteristic); fileLookupRequest.handleResponse(characteristic);
requestFinished = fileLookupRequest.isFinished(); requestFinished = fileLookupRequest.isFinished();
}catch (RuntimeException e){ } catch (RuntimeException e) {
e.printStackTrace(); e.printStackTrace();
requestFinished = true; requestFinished = true;
} }
if(requestFinished){ if (requestFinished) {
fileLookupRequest = null; fileLookupRequest = null;
try { try {
queueWrite(requestQueue.remove()); queueWrite(requestQueue.remove());
@ -219,13 +240,15 @@ public class FossilWatchAdapter extends WatchAdapter {
public void queueWrite(Request request) { public void queueWrite(Request request) {
if (filePutRequest != null || fileGetRequest != null || fileLookupRequest != null) { if (filePutRequest != null || fileGetRequest != null || fileLookupRequest != null) {
Log.d("FossilWatchAdapter", "queing request");
requestQueue.add(request); requestQueue.add(request);
return; return;
} }
if (request instanceof FilePutRequest) filePutRequest = (FilePutRequest) request; if (request instanceof FilePutRequest) filePutRequest = (FilePutRequest) request;
else if (request instanceof FileGetRequest) fileGetRequest = (FileGetRequest) request; else if (request instanceof FileGetRequest) fileGetRequest = (FileGetRequest) request;
else if (request instanceof FileLookupRequest) fileLookupRequest = (FileLookupRequest) request; else if (request instanceof FileLookupRequest)
fileLookupRequest = (FileLookupRequest) 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());
} }

View File

@ -23,7 +23,7 @@ import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig; import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState; import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem; import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
@ -108,12 +108,12 @@ public class MisfitWatchAdapter extends WatchAdapter {
} }
@Override @Override
public void playNotification(PackageConfig config) { public void playNotification(NotificationConfiguration config) {
queueWrite(new PlayNotificationRequest( queueWrite(new PlayNotificationRequest(
config.getVibration(), config.getVibration(),
config.getHour(), config.getHour(),
config.getMin(), config.getMin(),
config.getActivity() config.getSubEye()
)); ));
} }

View File

@ -1,16 +1,34 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil; package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import android.util.Log; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class ConfigurationGetRequest extends FileGetRequest { public class ConfigurationGetRequest extends FileLookupAndGetRequest {
public ConfigurationGetRequest(short handle, FossilWatchAdapter adapter) { public ConfigurationGetRequest(FossilWatchAdapter adapter) {
super(handle, adapter); super((byte) 8, adapter);
} }
@Override @Override
void handleFileData(byte[] fileData) { void handleFileData(byte[] fileData) {
byte[] data = new byte[fileData.length - 12 - 4];
System.arraycopy(fileData, 12, data, 0, data.length);
log("config file: " + getAdapter().arrayToString(fileData)); log("config file: " + getAdapter().arrayToString(fileData));
log("config file: " + getAdapter().arrayToString(data));
GBDevice device = getAdapter().getDeviceSupport().getDevice();
ConfigurationPutRequest.ConfigItem[] items = ConfigurationPutRequest.parsePayload(data);
for(ConfigurationPutRequest.ConfigItem item : items){
if(item instanceof ConfigurationPutRequest.VibrationStrengthConfigItem){
device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_VIBRATION_STRENGTH, String.valueOf(((ConfigurationPutRequest.VibrationStrengthConfigItem) item).getValue())));
}else if(item instanceof ConfigurationPutRequest.DailyStepGoalConfigItem){
device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_STEP_GOAL, String.valueOf(((ConfigurationPutRequest.DailyStepGoalConfigItem) item).getValue())));
}else if(item instanceof ConfigurationPutRequest.CurrentStepCountConfigItem){
device.addDeviceInfo(new GenericItem(QHybridSupport.ITEM_STEP_COUNT, String.valueOf(((ConfigurationPutRequest.CurrentStepCountConfigItem) item).getValue())));
}
}
} }
} }

View File

@ -0,0 +1,234 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import android.graphics.Bitmap;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class ConfigurationPutRequest extends FilePutRequest {
private static HashMap<Short, Class<? extends ConfigItem>> itemsById = new HashMap<>();
static {
itemsById.put((short)3, DailyStepGoalConfigItem.class);
itemsById.put((short)10, VibrationStrengthConfigItem.class);
itemsById.put((short)2, CurrentStepCountConfigItem.class);
itemsById.put((short)3, DailyStepGoalConfigItem.class);
itemsById.put((short)12, TimeConfigItem.class);
}
static ConfigItem[] parsePayload(byte[] data) {
ByteBuffer buffer = ByteBuffer.wrap(data);
buffer.order(ByteOrder.LITTLE_ENDIAN);
ArrayList<ConfigItem> configItems = new ArrayList<>();
while(buffer.hasRemaining()){
short id = buffer.getShort();
byte length = buffer.get();
byte[] payload = new byte[length];
for(int i = 0; i < length; i++){
payload[i] = buffer.get();
}
Class<? extends ConfigItem> configClass = itemsById.get(id);
if(configClass == null){
continue;
}
ConfigItem item = null;
try {
item = configClass.newInstance();
} catch (IllegalAccessException | InstantiationException e) {
e.printStackTrace();
continue;
}
item.parseData(payload);
configItems.add(item);
}
return configItems.toArray(new ConfigItem[0]);
}
public ConfigurationPutRequest(ConfigItem item, FossilWatchAdapter adapter) {
super((short) 0x0800, createFileContent(item), adapter);
}
public static byte[] createFileContent(ConfigItem item) {
ByteBuffer buffer = ByteBuffer.allocate(item.getItemSize() + 3);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort(item.getId());
buffer.put((byte) item.getItemSize());
buffer.put(item.getContent());
return buffer.array();
}
public static abstract class ConfigItem {
public abstract int getItemSize();
public abstract short getId();
public abstract byte[] getContent();
public abstract void parseData(byte[] data);
}
static public class GenericConfigItem<T> extends ConfigItem {
private T value;
private short configId;
public GenericConfigItem(short configId, T value) {
this.value = value;
this.configId = configId;
}
public T getValue(){
return value;
}
@Override
public int getItemSize() {
switch (value.getClass().getName()) {
case "java.lang.Byte":
return 1;
case "java.lang.Integer":
return 4;
case "java.lang.Long":
return 8;
}
throw new UnsupportedOperationException("config type " + value.getClass().getName() + " not supported");
}
@Override
public short getId() {
return 0;
}
@Override
public byte[] getContent() {
ByteBuffer buffer = ByteBuffer.allocate(getItemSize());
buffer.order(ByteOrder.LITTLE_ENDIAN);
switch (value.getClass().getName()) {
case "java.lang.Byte": {
buffer.put((Byte) this.value);
break;
}
case "java.lang.Integer": {
buffer.putInt((Integer) this.value);
break;
}
case "java.lang.Long": {
buffer.putLong((Long) this.value);
break;
}
}
return buffer.array();
}
@Override
public void parseData(byte[] data) {
ByteBuffer buffer = ByteBuffer.wrap(data);
buffer.order(ByteOrder.LITTLE_ENDIAN);
switch (data.length){
case 1:{
this.value = (T) (Byte) buffer.get();
break;
}
case 2:{
this.value = (T) (Short) buffer.getShort();
break;
}
case 4:{
this.value = (T) (Integer) buffer.getInt();
break;
}
}
}
}
static public class DailyStepGoalConfigItem extends GenericConfigItem<Integer> {
public DailyStepGoalConfigItem(){
this(-1);
}
public DailyStepGoalConfigItem(int value) {
super((short) 3, value);
}
}
static public class VibrationStrengthConfigItem extends GenericConfigItem<Byte> {
public VibrationStrengthConfigItem(){
this((byte) -1);
}
public VibrationStrengthConfigItem(Byte value) {
super((short) 10, value);
}
}
static public class CurrentStepCountConfigItem extends GenericConfigItem<Integer> {
public CurrentStepCountConfigItem(){
this(-1);
}
public CurrentStepCountConfigItem(Integer value) {
super((short) 2, value);
}
}
static public class TimeConfigItem extends ConfigItem {
private int epochSeconds;
private short millis, offsetMinutes;
public TimeConfigItem(){
this(-1, (short) -1, (short) -1);
}
public TimeConfigItem(int epochSeconds, short millis, short offsetMinutes) {
this.epochSeconds = epochSeconds;
this.millis = millis;
this.offsetMinutes = offsetMinutes;
}
@Override
public int getItemSize() {
return 8;
}
@Override
public short getId() {
return (short) 12;
}
@Override
public byte[] getContent() {
ByteBuffer buffer = ByteBuffer.allocate(getItemSize());
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt(this.epochSeconds);
buffer.putShort(millis);
buffer.putShort(offsetMinutes);
return buffer.array();
}
@Override
public void parseData(byte[] data) {
if(data.length != 8) throw new RuntimeException("wrong data");
ByteBuffer buffer = ByteBuffer.wrap(data);
buffer.order(ByteOrder.LITTLE_ENDIAN);
this.epochSeconds = buffer.getInt();
this.millis = buffer.getShort();
this.offsetMinutes = buffer.getShort();
}
}
}

View File

@ -1,154 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import android.graphics.Bitmap;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class ConfigurationRequest extends FilePutRequest {
private static HashMap<Byte, Class<? extends ConfigItem>> itemsById;
static {
itemsById.put((byte)3, DailyStepGoalConfigItem.class);
itemsById.put((byte)10, VibrationStrengthConfigItem.class);
itemsById.put((byte)2, CurrentStepCountConfigItem.class);
itemsById.put((byte)3, DailyStepGoalConfigItem.class);
itemsById.put((byte)12, TimeConfigItem.class);
}
static ConfigItem parsePayload(byte id, byte[] data) throws InstantiationException, IllegalAccessException {
Class<? extends ConfigItem> itemClass = itemsById.get(id);
ConfigItem item = itemClass.newInstance();
item.parseData(data);
return item;
}
public ConfigurationRequest(ConfigItem item, FossilWatchAdapter adapter) {
super((short) 0x0800, createFileContent(item), adapter);
}
public static byte[] createFileContent(ConfigItem item) {
ByteBuffer buffer = ByteBuffer.allocate(item.getItemSize() + 3);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putShort(item.getId());
buffer.put((byte) item.getItemSize());
buffer.put(item.getContent());
return buffer.array();
}
public interface ConfigItem {
public int getItemSize();
public short getId();
public byte[] getContent();
public void parseData(byte[] data);
}
static public class GenericConfigItem<T> implements ConfigItem {
T value;
short configId;
public GenericConfigItem(short configId, T value) {
this.value = value;
this.configId = configId;
}
@Override
public int getItemSize() {
switch (value.getClass().getName()) {
case "Byte":
return 1;
case "Integer":
return 4;
case "Long":
return 8;
}
throw new UnsupportedOperationException("config type " + value.getClass().getName() + " not supported");
}
@Override
public short getId() {
return 0;
}
@Override
public byte[] getContent() {
ByteBuffer buffer = ByteBuffer.allocate(getItemSize());
buffer.order(ByteOrder.LITTLE_ENDIAN);
switch (value.getClass().getName()) {
case "Byte": {
buffer.put((Byte) this.value);
break;
}
case "Integer": {
buffer.putInt((Integer) this.value);
break;
}
case "Long": {
buffer.putLong((Long) this.value);
break;
}
}
return buffer.array();
}
}
static public class DailyStepGoalConfigItem extends GenericConfigItem<Integer> {
public DailyStepGoalConfigItem(int value) {
super((short) 3, value);
}
}
static public class VibrationStrengthConfigItem extends GenericConfigItem<Byte> {
public VibrationStrengthConfigItem(Byte value) {
super((short) 10, value);
}
}
static public class CurrentStepCountConfigItem extends GenericConfigItem<Integer> {
public CurrentStepCountConfigItem(Integer value) {
super((short) 2, value);
}
}
static public class TimeConfigItem implements ConfigItem {
private int epochSeconds;
private short millis, offsetMinutes;
public TimeConfigItem(int epochSeconds, short millis, short offsetMinutes) {
this.epochSeconds = epochSeconds;
this.millis = millis;
this.offsetMinutes = offsetMinutes;
}
@Override
public int getItemSize() {
return 8;
}
@Override
public short getId() {
return (short) 12;
}
@Override
public byte[] getContent() {
ByteBuffer buffer = ByteBuffer.allocate(getItemSize());
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt(this.epochSeconds);
buffer.putShort(millis);
buffer.putShort(offsetMinutes);
return buffer.array();
}
}
}

View File

@ -2,13 +2,20 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fo
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class FileLookupAndGetRequest extends FileLookupRequest { public abstract class FileLookupAndGetRequest extends FileLookupRequest {
public FileLookupAndGetRequest(byte fileType, FossilWatchAdapter adapter) { public FileLookupAndGetRequest(byte fileType, FossilWatchAdapter adapter) {
super(fileType, adapter); super(fileType, adapter);
} }
@Override @Override
public void handleFileLookup(short fileHandle) { public void handleFileLookup(short fileHandle){
this.getAdapter().queueWrite(new ConfigurationGetRequest(fileHandle, getAdapter())); getAdapter().queueWrite(new FileGetRequest(getHandle(), getAdapter()) {
@Override
void handleFileData(byte[] fileData) {
FileLookupAndGetRequest.this.handleFileData(fileData);
} }
});
}
abstract void handleFileData(byte[] fileData);
} }

View File

@ -51,11 +51,12 @@ public abstract class FilePutRequest extends Request {
@Override @Override
public void handleResponse(BluetoothGattCharacteristic characteristic) { public void handleResponse(BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue(); byte[] value = characteristic.getValue();
if(characteristic.getUuid().toString().equals("3dda0003-957f-7d4a-34a6-74696673696d")) {
int responseType = value[0] & 0x0F; int responseType = value[0] & 0x0F;
log("response: " + responseType); log("response: " + responseType);
switch (responseType){ switch (responseType) {
case 3:{ case 3: {
if(value.length != 5 || (value[0] & 0x0F) != 3){ if (value.length != 5 || (value[0] & 0x0F) != 3) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong answer header"); log("wrong answer header");
break; break;
@ -72,21 +73,21 @@ public abstract class FilePutRequest extends Request {
.queue(queue); .queue(queue);
break; break;
} }
case 8:{ case 8: {
if(value.length == 4) return; if (value.length == 4) return;
ByteBuffer buffer = ByteBuffer.wrap(value); ByteBuffer buffer = ByteBuffer.wrap(value);
buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.order(ByteOrder.LITTLE_ENDIAN);
short handle = buffer.getShort(1); short handle = buffer.getShort(1);
int crc = buffer.getInt(8); int crc = buffer.getInt(8);
byte status = value[3]; byte status = value[3];
if(status != 0){ if (status != 0) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("file error: " + status); log("file error: " + status);
break; break;
} }
if(handle != this.handle){ if (handle != this.handle) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong file handle"); log("wrong file handle");
break; break;
@ -96,7 +97,7 @@ public abstract class FilePutRequest extends Request {
byte[] data = packets.get(packetIndex); byte[] data = packets.get(packetIndex);
realCrc.update(data, 1, data.length - 1); realCrc.update(data, 1, data.length - 1);
if(crc != (int) realCrc.getValue()){ if (crc != (int) realCrc.getValue()) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong crc"); log("wrong crc");
// TODO CRC // TODO CRC
@ -105,7 +106,7 @@ public abstract class FilePutRequest extends Request {
packetIndex++; packetIndex++;
if(packetIndex < packets.size()){ if (packetIndex < packets.size()) {
byte[] initialPacket = packets.get(packetIndex); byte[] initialPacket = packets.get(packetIndex);
new TransactionBuilder("file upload") new TransactionBuilder("file upload")
@ -115,7 +116,7 @@ public abstract class FilePutRequest extends Request {
) )
.queue(adapter.getDeviceSupport().getQueue()); .queue(adapter.getDeviceSupport().getQueue());
break; break;
} else{ } else {
ByteBuffer buffer2 = ByteBuffer.allocate(3); ByteBuffer buffer2 = ByteBuffer.allocate(3);
buffer2.order(ByteOrder.LITTLE_ENDIAN); buffer2.order(ByteOrder.LITTLE_ENDIAN);
buffer2.put((byte) 4); buffer2.put((byte) 4);
@ -133,8 +134,8 @@ public abstract class FilePutRequest extends Request {
} }
} }
case 4: { case 4: {
if(value.length == 9) return; if (value.length == 9) return;
if(value.length != 4 || (value[0] & 0x0F) != 4){ if (value.length != 4 || (value[0] & 0x0F) != 4) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong closing header"); log("wrong closing header");
break; break;
@ -144,7 +145,7 @@ public abstract class FilePutRequest extends Request {
short handle = buffer.getShort(1); short handle = buffer.getShort(1);
if(handle != this.handle){ if (handle != this.handle) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong file handle"); log("wrong file handle");
break; break;
@ -152,7 +153,7 @@ public abstract class FilePutRequest extends Request {
byte status = buffer.get(3); byte status = buffer.get(3);
if(status != 0){ if (status != 0) {
this.state = UploadState.ERROR; this.state = UploadState.ERROR;
log("wrong closing handle"); log("wrong closing handle");
break; break;
@ -166,6 +167,7 @@ public abstract class FilePutRequest extends Request {
} }
} }
} }
}
public boolean isFinished(){ public boolean isFinished(){
return this.state == UploadState.UPLOADED || this.state == UploadState.ERROR; return this.state == UploadState.UPLOADED || this.state == UploadState.ERROR;

View File

@ -8,8 +8,8 @@ import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.CRC32C; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.CRC32C;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class NotifcationFilterGetRequest extends FileGetRequest { public class NotificationFilterGetRequest extends FileGetRequest {
public NotifcationFilterGetRequest(FossilWatchAdapter adapter) { public NotificationFilterGetRequest(FossilWatchAdapter adapter) {
super((short) 0x0C00, adapter); super((short) 0x0C00, adapter);
} }

View File

@ -0,0 +1,84 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.zip.CRC32;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter;
public class NotificationFilterPutRequest extends FilePutRequest {
public NotificationFilterPutRequest(NotificationConfiguration[] configs, FossilWatchAdapter adapter) {
super((short) 0x0C00, createFile(configs), adapter);
}
private static byte[] createFile(NotificationConfiguration[] configs){
ByteBuffer buffer = ByteBuffer.allocate(configs.length * 27);
buffer.order(ByteOrder.LITTLE_ENDIAN);
for(NotificationConfiguration config : configs){
buffer.putShort((short) 25); //packet length
CRC32 crc = new CRC32();
crc.update(config.getPackageName().getBytes());
buffer.put(PacketID.PACKAGE_NAME_CRC.id);
buffer.put((byte) 4);
buffer.putInt((int) crc.getValue());
buffer.put(PacketID.GROUP_ID.id);
buffer.put((byte) 1);
buffer.put((byte) 2);
buffer.put(PacketID.PRIORITY.id);
buffer.put((byte) 1);
buffer.put((byte) 0xFF);
buffer.put(PacketID.MOVEMENT.id);
buffer.put((byte) 8);
buffer.putShort(config.getHour())
.putShort(config.getMin())
.putShort(config.getSubEye())
.putShort((short) 1000);
buffer.put(PacketID.VIBRATION.id);
buffer.put((byte) 1);
buffer.put(config.getVibration().getValue());
}
// return new byte[]{(byte) 0x19, (byte) 0x00, (byte) 0x04, (byte) 0x04, (byte) 0xCC, (byte) 0x6A, (byte) 0x8C, (byte) 0x17, (byte) 0x80, (byte) 0x01, (byte) 0x02, (byte) 0xC1, (byte) 0x01, (byte) 0xFF, (byte) 0xC2, (byte) 0x08, (byte) 0x77, (byte) 0x00, (byte) 0x77, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0x10, (byte) 0x27, (byte) 0xC3, (byte) 0x01, (byte) 0x04, (byte) 0x19, (byte) 0x00, (byte) 0x04, (byte) 0x04, (byte) 0xCC, (byte) 0x6A, (byte) 0x8C, (byte) 0x17, (byte) 0x80, (byte) 0x01, (byte) 0x02, (byte) 0xC1, (byte) 0x01, (byte) 0xFF, (byte) 0xC2, (byte) 0x08, (byte) 0x77, (byte) 0x00, (byte) 0x77, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0x10, (byte) 0x27, (byte) 0xC3, (byte) 0x01, (byte) 0x04};
return buffer.array();
// return new byte[]{1};
// return new byte[]{0x19, (byte) 0x00, (byte) 0x04, (byte) 0x04, (byte) 0xCC, (byte) 0x6A, (byte) 0x8C, (byte) 0x17, (byte) 0x80, (byte) 0x01, (byte) 0x02, (byte) 0xC1, (byte) 0x01, (byte) 0xFF, (byte) 0xC2, (byte) 0x08, (byte) 0x59, (byte) 0x00, (byte) 0x59, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0x10, (byte) 0x27, (byte) 0xC3, (byte) 0x01, (byte) 0x04, (byte) 0x19, (byte) 0x00, (byte) 0x04, (byte) 0x04, (byte) 0xCC, (byte) 0x6A, (byte) 0x8C, (byte) 0x17, (byte) 0x80, (byte) 0x01, (byte) 0x02, (byte) 0xC1, (byte) 0x01, (byte) 0xFF, (byte) 0xC2, (byte) 0x08, (byte) 0x59, (byte) 0x00, (byte) 0x59, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0x10, (byte) 0x27, (byte) 0xC3, (byte) 0x01, (byte) 0x04};
}
enum PacketID{
PACKAGE_NAME((byte) 1),
SENDER_NAME((byte) 2),
PACKAGE_NAME_CRC((byte) 4),
GROUP_ID((byte) 128),
APP_DISPLAY_NAME((byte) 129),
PRIORITY((byte) 0xC1),
MOVEMENT((byte) 0xC2),
VIBRATION((byte) 0xC3);
byte id;
PacketID(byte id){
this.id = id;
}
}
enum VibrationType{
SINGLE_SHORT((byte) 5),
DOUBLE_SHORT((byte) 6),
TRIPLE_SHORT((byte) 7),
SINGLE_LONG((byte) 8),
SILENT((byte) 9);
byte id;
VibrationType(byte id){
this.id = id;
}
}
}

View File

@ -0,0 +1,24 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil;
import android.bluetooth.BluetoothGattCharacteristic;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
public class PrepareFilesRequestOrWhatever extends Request {
@Override
public byte[] getStartSequence() {
return new byte[]{(byte) 0x09, (byte) 0xFF, (byte) 0xFF};
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
super.handleResponse(characteristic);
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0003-957f-7d4a-34a6-74696673696d");
}
}

View File

@ -8,6 +8,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Req
public class PlayNotificationRequest extends Request { public class PlayNotificationRequest extends Request {
public enum VibrationType{ public enum VibrationType{
WHATEVER(4),
SINGLE_SHORT(3), SINGLE_SHORT(3),
DOUBLE_SHORT(2), DOUBLE_SHORT(2),
TRIPLE_SHORT(1), TRIPLE_SHORT(1),