Pebble: send sunrine and sunset pins to timeline when setting time in debug menu

This is just a test and it will leak your timeline data, since we never delete it.
Also this adds some rough infrastructure for calendar events.
here
Andreas Shimokawa 2016-05-16 17:30:11 +02:00
parent 8c88223f26
commit 017f650b3f
16 changed files with 167 additions and 3 deletions

View File

@ -54,6 +54,7 @@ dependencies {
compile 'com.github.PhilJay:MPAndroidChart:v2.2.4'
compile 'com.github.pfichtner:durationformatter:0.1.1'
compile 'de.cketti.library.changelog:ckchangelog:1.2.2'
compile 'net.e175.klaus:solarpositioning:0.0.9'
}
check.dependsOn 'findbugs', 'pmd', 'lint'

View File

@ -20,15 +20,20 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.e175.klaus.solarpositioning.DeltaT;
import net.e175.klaus.solarpositioning.SPA;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.GregorianCalendar;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
@ -36,6 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class DebugActivity extends GBActivity {
@ -224,6 +230,36 @@ public class DebugActivity extends GBActivity {
@Override
public void onClick(View v) {
GBApplication.deviceService().onSetTime();
//FIXME: dont do it here, make another button
Prefs prefs = GBApplication.getPrefs();
float latitude = prefs.getFloat("location_latitude", 0);
float longitude = prefs.getFloat("location_longitude", 0);
final GregorianCalendar dateTime = new GregorianCalendar();
GregorianCalendar[] sunriseTransitSet = SPA.calculateSunriseTransitSet(dateTime, latitude, longitude, DeltaT.estimate(dateTime));
if (sunriseTransitSet[0] != null) {
CalendarEventSpec calendarEventSpec = new CalendarEventSpec();
calendarEventSpec.id = -1;
calendarEventSpec.type = CalendarEventSpec.TYPE_SUNRISE;
calendarEventSpec.timestamp = (int) (sunriseTransitSet[0].getTimeInMillis() / 1000);
calendarEventSpec.durationInSeconds = 0;
calendarEventSpec.title = "Sunrise";
calendarEventSpec.description = null;
GBApplication.deviceService().onAddCalendarEvent(calendarEventSpec);
}
if (sunriseTransitSet[2] != null) {
CalendarEventSpec calendarEventSpec = new CalendarEventSpec();
calendarEventSpec.id = -1;
calendarEventSpec.type = CalendarEventSpec.TYPE_SUNSET;
calendarEventSpec.timestamp = (int) (sunriseTransitSet[2].getTimeInMillis() / 1000);
calendarEventSpec.durationInSeconds = 0;
calendarEventSpec.title = "Sunset";
calendarEventSpec.description = null;
GBApplication.deviceService().onAddCalendarEvent(calendarEventSpec);
}
}
});

View File

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -51,4 +52,6 @@ public interface EventHandler {
void onScreenshotReq();
void onEnableHeartRateSleepSupport(boolean enable);
void onAddCalendarEvent(CalendarEventSpec calendarEventSpec);
}

View File

@ -10,6 +10,7 @@ import java.util.ArrayList;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
@ -223,4 +224,16 @@ public class GBDeviceService implements DeviceService {
.putExtra(EXTRA_BOOLEAN_ENABLE, enable);
invokeService(intent);
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
Intent intent = createIntent().setAction(ACTION_ADD_CALENDAREVENT)
.putExtra(EXTRA_CALENDAREVENT_ID, calendarEventSpec.id)
.putExtra(EXTRA_CALENDAREVENT_TYPE, calendarEventSpec.type)
.putExtra(EXTRA_CALENDAREVENT_TIMESTAMP, calendarEventSpec.timestamp)
.putExtra(EXTRA_CALENDAREVENT_DURATION, calendarEventSpec.durationInSeconds)
.putExtra(EXTRA_CALENDAREVENT_TITLE, calendarEventSpec.title)
.putExtra(EXTRA_CALENDAREVENT_DESCRIPTION, calendarEventSpec.description);
invokeService(intent);
}
}

View File

@ -0,0 +1,14 @@
package nodomain.freeyourgadget.gadgetbridge.model;
public class CalendarEventSpec {
public static final int TYPE_UNKNOWN = 0;
public static final int TYPE_SUNRISE = 1;
public static final int TYPE_SUNSET = 2;
public int type;
public long id;
public int timestamp;
public int durationInSeconds;
public String title;
public String description;
}

View File

@ -36,6 +36,7 @@ public interface DeviceService extends EventHandler {
String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement";
String ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT = PREFIX + ".action.enable_heartrate_sleep_support";
String ACTION_HEARTRATE_MEASUREMENT = PREFIX + ".action.hr_measurement";
String ACTION_ADD_CALENDAREVENT = PREFIX + ".action.add_calendarevent";
String EXTRA_DEVICE_ADDRESS = "device_address";
String EXTRA_NOTIFICATION_BODY = "notification_body";
String EXTRA_NOTIFICATION_FLAGS = "notification_flags";
@ -65,6 +66,12 @@ public interface DeviceService extends EventHandler {
String EXTRA_REALTIME_STEPS = "realtime_steps";
String EXTRA_TIMESTAMP = "timestamp";
String EXTRA_HEART_RATE_VALUE = "hr_value";
String EXTRA_CALENDAREVENT_ID = "calendarevent_id";
String EXTRA_CALENDAREVENT_TYPE = "calendarevent_type";
String EXTRA_CALENDAREVENT_TIMESTAMP = "calendarevent_timestamp";
String EXTRA_CALENDAREVENT_DURATION = "calendarevent_duration";
String EXTRA_CALENDAREVENT_TITLE = "calendarevent_title";
String EXTRA_CALENDAREVENT_DESCRIPTION = "calendarevent_description";
void start();

View File

@ -32,6 +32,7 @@ import nodomain.freeyourgadget.gadgetbridge.externalevents.SMSReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.TimeChangeReceiver;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -41,6 +42,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_ADD_CALENDAREVENT;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_APP_CONFIGURE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CALLSTATE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT;
@ -68,6 +70,12 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_START;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_APP_UUID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_BOOLEAN_ENABLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_DESCRIPTION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_DURATION;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_ID;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TIMESTAMP;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TITLE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALENDAREVENT_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_COMMAND;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_CALL_PHONENUMBER;
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.EXTRA_DEVICE_ADDRESS;
@ -265,6 +273,17 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
mDeviceSupport.onNotification(notificationSpec);
break;
}
case ACTION_ADD_CALENDAREVENT: {
CalendarEventSpec calendarEventSpec = new CalendarEventSpec();
calendarEventSpec.id = intent.getLongExtra(EXTRA_CALENDAREVENT_ID, -1);
calendarEventSpec.type = intent.getIntExtra(EXTRA_CALENDAREVENT_TYPE, -1);
calendarEventSpec.timestamp = intent.getIntExtra(EXTRA_CALENDAREVENT_TIMESTAMP, -1);
calendarEventSpec.durationInSeconds = intent.getIntExtra(EXTRA_CALENDAREVENT_DURATION, -1);
calendarEventSpec.title = intent.getStringExtra(EXTRA_CALENDAREVENT_TITLE);
calendarEventSpec.description = intent.getStringExtra(EXTRA_CALENDAREVENT_DESCRIPTION);
mDeviceSupport.onAddCalendarEvent(calendarEventSpec);
break;
}
case ACTION_REBOOT: {
mDeviceSupport.onReboot();
break;

View File

@ -13,6 +13,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -268,4 +269,12 @@ public class ServiceDeviceSupport implements DeviceSupport {
}
delegate.onEnableRealtimeHeartRateMeasurement(enable);
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
if (checkBusy("add calendar event")) {
return;
}
delegate.onAddCalendarEvent(calendarEventSpec);
}
}

View File

@ -32,6 +32,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
@ -382,6 +383,11 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
// not supported
}
/**
* Part of device initialization process. Do not call manually.
*

View File

@ -33,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
@ -464,6 +465,24 @@ public class PebbleProtocol extends GBDeviceProtocol {
}
}
@Override
public byte[] encodeAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
long id = calendarEventSpec.id != -1 ? calendarEventSpec.id : mRandom.nextLong();
int iconId;
switch (calendarEventSpec.type) {
case CalendarEventSpec.TYPE_SUNRISE:
iconId = PebbleIconID.SUNRISE;
break;
case CalendarEventSpec.TYPE_SUNSET:
iconId = PebbleIconID.SUNSET;
break;
default:
iconId = PebbleIconID.TIMELINE_CALENDAR;
}
return encodeTimelinePin(id, calendarEventSpec.timestamp, (short)calendarEventSpec.durationInSeconds, iconId, calendarEventSpec.title, calendarEventSpec.description);
}
@Override
public byte[] encodeSetTime() {
long ts = System.currentTimeMillis();
@ -742,11 +761,11 @@ public class PebbleProtocol extends GBDeviceProtocol {
return buf.array();
}
private byte[] encodeTimelinePin(int id, int timestamp, short duration, int icon_id, String title, String subtitle) {
private byte[] encodeTimelinePin(long id, int timestamp, short duration, int icon_id, String title, String subtitle) {
final short TIMELINE_PIN_LENGTH = 46;
icon_id |= 0x80000000;
UUID uuid = new UUID(mRandom.nextLong(), ((long) mRandom.nextInt() << 32) | id);
UUID uuid = new UUID(mRandom.nextLong(), id);
byte attributes_count = 2;
byte actions_count = 0;

View File

@ -12,6 +12,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -118,4 +119,11 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
//nothing to do ATM
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
if (reconnect()) {
super.onAddCalendarEvent(calendarEventSpec);
}
}
}

View File

@ -8,6 +8,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -187,4 +188,9 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
byte[] bytes = gbDeviceProtocol.encodeEnableRealtimeHeartRateMeasurement(enable);
sendToDevice(bytes);
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
byte[] bytes = gbDeviceProtocol.encodeAddCalendarEvent(calendarEventSpec);
sendToDevice(bytes);
}
}

View File

@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.serial;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
public abstract class GBDeviceProtocol {
@ -65,6 +66,10 @@ public abstract class GBDeviceProtocol {
public byte[] encodeEnableRealtimeHeartRateMeasurement(boolean enable) { return null; }
public byte[] encodeAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
return null;
}
public GBDeviceEvent[] decodeResponse(byte[] responseData) {
return null;
}

View File

@ -34,11 +34,16 @@
<string name="pref_header_general">General Settings</string>
<string name="pref_title_general_autoconnectonbluetooth">Connect to device when Bluetooth turned on</string>
<string name="pref_title_general_autocreonnect">Reconnect automatically</string>
<string name="pref_title_audo_player">Preferred Audioplayer</string>
<string name="pref_default">Default</string>
<string name="pref_header_datetime">Date and Time</string>
<string name="pref_title_datetime_syctimeonconnect">Sync time</string>
<string name="pref_summary_datetime_syctimeonconnect">Sync time to device when connecting and when time or timezone changes on Android</string>
<string name="pref_title_location_latitude">Latitude</string>
<string name="pref_title_location_longitude">Longitude</string>
<string name="pref_title_theme">Theme</string>
<string name="pref_theme_light">Light</string>
<string name="pref_theme_dark">Dark</string>
@ -248,6 +253,5 @@
<string name="updatefirmwareoperation_firmware_not_sent">Firmware not sent</string>
<string name="charts_legend_heartrate">Heart Rate</string>
<string name="live_activity_heart_rate">Heart Rate</string>
<string name="pref_title_general_autocreonnect">Reconnect automatically</string>
</resources>

View File

@ -32,6 +32,14 @@
android:key="datetime_synconconnect"
android:summary="@string/pref_summary_datetime_syctimeonconnect"
android:title="@string/pref_title_datetime_syctimeonconnect" />
<EditTextPreference
android:defaultValue="0"
android:key="location_latitude"
android:title="@string/pref_title_location_latitude" />
<EditTextPreference
android:defaultValue="0"
android:key="location_longitude"
android:title="@string/pref_title_location_longitude" />
</PreferenceCategory>
<PreferenceCategory
android:key="pref_key_notifications"

View File

@ -9,6 +9,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
@ -130,6 +131,11 @@ public class TestDeviceSupport extends AbstractDeviceSupport {
}
@Override
public void onAddCalendarEvent(CalendarEventSpec calendarEventSpec) {
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {